1<?php
2
3namespace Guzzle\Common\Exception;
4
5/**
6 * Collection of exceptions
7 */
8class ExceptionCollection extends \Exception implements GuzzleException, \IteratorAggregate, \Countable
9{
10    /** @var array Array of Exceptions */
11    protected $exceptions = array();
12
13    /** @var string Succinct exception message not including sub-exceptions */
14    private $shortMessage;
15
16    public function __construct($message = '', $code = 0, \Exception $previous = null)
17    {
18        parent::__construct($message, $code, $previous);
19        $this->shortMessage = $message;
20    }
21
22    /**
23     * Set all of the exceptions
24     *
25     * @param array $exceptions Array of exceptions
26     *
27     * @return self
28     */
29    public function setExceptions(array $exceptions)
30    {
31        $this->exceptions = array();
32        foreach ($exceptions as $exception) {
33            $this->add($exception);
34        }
35
36        return $this;
37    }
38
39    /**
40     * Add exceptions to the collection
41     *
42     * @param ExceptionCollection|\Exception $e Exception to add
43     *
44     * @return ExceptionCollection;
45     */
46    public function add($e)
47    {
48        $this->exceptions[] = $e;
49        if ($this->message) {
50            $this->message .= "\n";
51        }
52
53        $this->message .= $this->getExceptionMessage($e, 0);
54
55        return $this;
56    }
57
58    /**
59     * Get the total number of request exceptions
60     *
61     * @return int
62     */
63    public function count()
64    {
65        return count($this->exceptions);
66    }
67
68    /**
69     * Allows array-like iteration over the request exceptions
70     *
71     * @return \ArrayIterator
72     */
73    public function getIterator()
74    {
75        return new \ArrayIterator($this->exceptions);
76    }
77
78    /**
79     * Get the first exception in the collection
80     *
81     * @return \Exception
82     */
83    public function getFirst()
84    {
85        return $this->exceptions ? $this->exceptions[0] : null;
86    }
87
88    private function getExceptionMessage(\Exception $e, $depth = 0)
89    {
90        static $sp = '    ';
91        $prefix = $depth ? str_repeat($sp, $depth) : '';
92        $message = "{$prefix}(" . get_class($e) . ') ' . $e->getFile() . ' line ' . $e->getLine() . "\n";
93
94        if ($e instanceof self) {
95            if ($e->shortMessage) {
96                $message .= "\n{$prefix}{$sp}" . str_replace("\n", "\n{$prefix}{$sp}", $e->shortMessage) . "\n";
97            }
98            foreach ($e as $ee) {
99                $message .= "\n" . $this->getExceptionMessage($ee, $depth + 1);
100            }
101        }  else {
102            $message .= "\n{$prefix}{$sp}" . str_replace("\n", "\n{$prefix}{$sp}", $e->getMessage()) . "\n";
103            $message .= "\n{$prefix}{$sp}" . str_replace("\n", "\n{$prefix}{$sp}", $e->getTraceAsString()) . "\n";
104        }
105
106        return str_replace(getcwd(), '.', $message);
107    }
108}
109