Subversion-Projekte lars-tiefland.laravel_shop

Revision

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