d5ca136bd3987b56514ca0d8c4eff700113566f4
[yaffs-website] / vendor / zendframework / zend-stdlib / src / PriorityList.php
1 <?php
2 /**
3  * Zend Framework (http://framework.zend.com/)
4  *
5  * @link      http://github.com/zendframework/zf2 for the canonical source repository
6  * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7  * @license   http://framework.zend.com/license/new-bsd New BSD License
8  */
9
10 namespace Zend\Stdlib;
11
12 use Countable;
13 use Iterator;
14
15 class PriorityList implements Iterator, Countable
16 {
17     const EXTR_DATA     = 0x00000001;
18     const EXTR_PRIORITY = 0x00000002;
19     const EXTR_BOTH     = 0x00000003;
20     /**
21      * Internal list of all items.
22      *
23      * @var array[]
24      */
25     protected $items = [];
26
27     /**
28      * Serial assigned to items to preserve LIFO.
29      *
30      * @var int
31      */
32     protected $serial = 0;
33
34     /**
35      * Serial order mode
36      * @var integer
37      */
38     protected $isLIFO = 1;
39
40     /**
41      * Internal counter to avoid usage of count().
42      *
43      * @var int
44      */
45     protected $count = 0;
46
47     /**
48      * Whether the list was already sorted.
49      *
50      * @var bool
51      */
52     protected $sorted = false;
53
54     /**
55      * Insert a new item.
56      *
57      * @param  string  $name
58      * @param  mixed   $value
59      * @param  int     $priority
60      *
61      * @return void
62      */
63     public function insert($name, $value, $priority = 0)
64     {
65         if (! isset($this->items[$name])) {
66             $this->count++;
67         }
68
69         $this->sorted = false;
70
71         $this->items[$name] = [
72             'data'     => $value,
73             'priority' => (int) $priority,
74             'serial'   => $this->serial++,
75         ];
76     }
77
78     /**
79      * @param string $name
80      * @param int    $priority
81      *
82      * @return $this
83      *
84      * @throws \Exception
85      */
86     public function setPriority($name, $priority)
87     {
88         if (! isset($this->items[$name])) {
89             throw new \Exception("item $name not found");
90         }
91
92         $this->items[$name]['priority'] = (int) $priority;
93         $this->sorted                   = false;
94
95         return $this;
96     }
97
98     /**
99      * Remove a item.
100      *
101      * @param  string $name
102      * @return void
103      */
104     public function remove($name)
105     {
106         if (isset($this->items[$name])) {
107             $this->count--;
108         }
109
110         unset($this->items[$name]);
111     }
112
113     /**
114      * Remove all items.
115      *
116      * @return void
117      */
118     public function clear()
119     {
120         $this->items  = [];
121         $this->serial = 0;
122         $this->count  = 0;
123         $this->sorted = false;
124     }
125
126     /**
127      * Get a item.
128      *
129      * @param  string $name
130      * @return mixed
131      */
132     public function get($name)
133     {
134         if (! isset($this->items[$name])) {
135             return;
136         }
137
138         return $this->items[$name]['data'];
139     }
140
141     /**
142      * Sort all items.
143      *
144      * @return void
145      */
146     protected function sort()
147     {
148         if (! $this->sorted) {
149             uasort($this->items, [$this, 'compare']);
150             $this->sorted = true;
151         }
152     }
153
154     /**
155      * Compare the priority of two items.
156      *
157      * @param  array $item1,
158      * @param  array $item2
159      * @return int
160      */
161     protected function compare(array $item1, array $item2)
162     {
163         return ($item1['priority'] === $item2['priority'])
164             ? ($item1['serial'] > $item2['serial'] ? -1 : 1) * $this->isLIFO
165             : ($item1['priority'] > $item2['priority'] ? -1 : 1);
166     }
167
168     /**
169      * Get/Set serial order mode
170      *
171      * @param bool|null $flag
172      *
173      * @return bool
174      */
175     public function isLIFO($flag = null)
176     {
177         if ($flag !== null) {
178             $isLifo = $flag === true ? 1 : -1;
179
180             if ($isLifo !== $this->isLIFO) {
181                 $this->isLIFO = $isLifo;
182                 $this->sorted = false;
183             }
184         }
185
186         return 1 === $this->isLIFO;
187     }
188
189     /**
190      * {@inheritDoc}
191      */
192     public function rewind()
193     {
194         $this->sort();
195         reset($this->items);
196     }
197
198     /**
199      * {@inheritDoc}
200      */
201     public function current()
202     {
203         $this->sorted || $this->sort();
204         $node = current($this->items);
205
206         return $node ? $node['data'] : false;
207     }
208
209     /**
210      * {@inheritDoc}
211      */
212     public function key()
213     {
214         $this->sorted || $this->sort();
215         return key($this->items);
216     }
217
218     /**
219      * {@inheritDoc}
220      */
221     public function next()
222     {
223         $node = next($this->items);
224
225         return $node ? $node['data'] : false;
226     }
227
228     /**
229      * {@inheritDoc}
230      */
231     public function valid()
232     {
233         return current($this->items) !== false;
234     }
235
236     /**
237      * @return self
238      */
239     public function getIterator()
240     {
241         return clone $this;
242     }
243
244     /**
245      * {@inheritDoc}
246      */
247     public function count()
248     {
249         return $this->count;
250     }
251
252     /**
253      * Return list as array
254      *
255      * @param int $flag
256      *
257      * @return array
258      */
259     public function toArray($flag = self::EXTR_DATA)
260     {
261         $this->sort();
262
263         if ($flag == self::EXTR_BOTH) {
264             return $this->items;
265         }
266
267         return array_map(
268             function ($item) use ($flag) {
269                 return ($flag == PriorityList::EXTR_PRIORITY) ? $item['priority'] : $item['data'];
270             },
271             $this->items
272         );
273     }
274 }