Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
/**
3
 * Whoops - php errors for cool kids
4
 * @author Filipe Dobreira <http://github.com/filp>
5
 */
6
 
7
namespace Whoops\Exception;
8
 
9
use ArrayAccess;
10
use ArrayIterator;
11
use Countable;
12
use IteratorAggregate;
13
use ReturnTypeWillChange;
14
use Serializable;
15
use UnexpectedValueException;
16
 
17
/**
18
 * Exposes a fluent interface for dealing with an ordered list
19
 * of stack-trace frames.
20
 */
21
class FrameCollection implements ArrayAccess, IteratorAggregate, Serializable, Countable
22
{
23
    /**
24
     * @var array[]
25
     */
26
    private $frames;
27
 
28
    public function __construct(array $frames)
29
    {
30
        $this->frames = array_map(function ($frame) {
31
            return new Frame($frame);
32
        }, $frames);
33
    }
34
 
35
    /**
36
     * Filters frames using a callable, returns the same FrameCollection
37
     *
38
     * @param  callable        $callable
39
     * @return FrameCollection
40
     */
41
    public function filter($callable)
42
    {
43
        $this->frames = array_values(array_filter($this->frames, $callable));
44
        return $this;
45
    }
46
 
47
    /**
48
     * Map the collection of frames
49
     *
50
     * @param  callable        $callable
51
     * @return FrameCollection
52
     */
53
    public function map($callable)
54
    {
55
        // Contain the map within a higher-order callable
56
        // that enforces type-correctness for the $callable
57
        $this->frames = array_map(function ($frame) use ($callable) {
58
            $frame = call_user_func($callable, $frame);
59
 
60
            if (!$frame instanceof Frame) {
61
                throw new UnexpectedValueException(
62
                    "Callable to " . __CLASS__ . "::map must return a Frame object"
63
                );
64
            }
65
 
66
            return $frame;
67
        }, $this->frames);
68
 
69
        return $this;
70
    }
71
 
72
    /**
73
     * Returns an array with all frames, does not affect
74
     * the internal array.
75
     *
76
     * @todo   If this gets any more complex than this,
77
     *         have getIterator use this method.
78
     * @see    FrameCollection::getIterator
79
     * @return array
80
     */
81
    public function getArray()
82
    {
83
        return $this->frames;
84
    }
85
 
86
    /**
87
     * @see IteratorAggregate::getIterator
88
     * @return ArrayIterator
89
     */
90
    #[ReturnTypeWillChange]
91
    public function getIterator()
92
    {
93
        return new ArrayIterator($this->frames);
94
    }
95
 
96
    /**
97
     * @see ArrayAccess::offsetExists
98
     * @param int $offset
99
     */
100
    #[ReturnTypeWillChange]
101
    public function offsetExists($offset)
102
    {
103
        return isset($this->frames[$offset]);
104
    }
105
 
106
    /**
107
     * @see ArrayAccess::offsetGet
108
     * @param int $offset
109
     */
110
    #[ReturnTypeWillChange]
111
    public function offsetGet($offset)
112
    {
113
        return $this->frames[$offset];
114
    }
115
 
116
    /**
117
     * @see ArrayAccess::offsetSet
118
     * @param int $offset
119
     */
120
    #[ReturnTypeWillChange]
121
    public function offsetSet($offset, $value)
122
    {
123
        throw new \Exception(__CLASS__ . ' is read only');
124
    }
125
 
126
    /**
127
     * @see ArrayAccess::offsetUnset
128
     * @param int $offset
129
     */
130
    #[ReturnTypeWillChange]
131
    public function offsetUnset($offset)
132
    {
133
        throw new \Exception(__CLASS__ . ' is read only');
134
    }
135
 
136
    /**
137
     * @see Countable::count
138
     * @return int
139
     */
140
    #[ReturnTypeWillChange]
141
    public function count()
142
    {
143
        return count($this->frames);
144
    }
145
 
146
    /**
147
     * Count the frames that belongs to the application.
148
     *
149
     * @return int
150
     */
151
    public function countIsApplication()
152
    {
153
        return count(array_filter($this->frames, function (Frame $f) {
154
            return $f->isApplication();
155
        }));
156
    }
157
 
158
    /**
159
     * @see Serializable::serialize
160
     * @return string
161
     */
162
    #[ReturnTypeWillChange]
163
    public function serialize()
164
    {
165
        return serialize($this->frames);
166
    }
167
 
168
    /**
169
     * @see Serializable::unserialize
170
     * @param string $serializedFrames
171
     */
172
    #[ReturnTypeWillChange]
173
    public function unserialize($serializedFrames)
174
    {
175
        $this->frames = unserialize($serializedFrames);
176
    }
177
 
178
    public function __serialize()
179
    {
180
        return $this->frames;
181
    }
182
 
183
    public function __unserialize(array $serializedFrames)
184
    {
185
        $this->frames = $serializedFrames;
186
    }
187
 
188
    /**
189
     * @param Frame[] $frames Array of Frame instances, usually from $e->getPrevious()
190
     */
191
    public function prependFrames(array $frames)
192
    {
193
        $this->frames = array_merge($frames, $this->frames);
194
    }
195
 
196
    /**
197
     * Gets the innermost part of stack trace that is not the same as that of outer exception
198
     *
199
     * @param  FrameCollection $parentFrames Outer exception frames to compare tail against
200
     * @return Frame[]
201
     */
202
    public function topDiff(FrameCollection $parentFrames)
203
    {
204
        $diff = $this->frames;
205
 
206
        $parentFrames = $parentFrames->getArray();
207
        $p = count($parentFrames)-1;
208
 
209
        for ($i = count($diff)-1; $i >= 0 && $p >= 0; $i--) {
210
            /** @var Frame $tailFrame */
211
            $tailFrame = $diff[$i];
212
            if ($tailFrame->equals($parentFrames[$p])) {
213
                unset($diff[$i]);
214
            }
215
            $p--;
216
        }
217
        return $diff;
218
    }
219
}