3 * Zend Framework (http://framework.zend.com/)
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
10 namespace Zend\Stdlib;
15 class PriorityList implements Iterator, Countable
17 const EXTR_DATA = 0x00000001;
18 const EXTR_PRIORITY = 0x00000002;
19 const EXTR_BOTH = 0x00000003;
21 * Internal list of all items.
25 protected $items = [];
28 * Serial assigned to items to preserve LIFO.
32 protected $serial = 0;
38 protected $isLIFO = 1;
41 * Internal counter to avoid usage of count().
48 * Whether the list was already sorted.
52 protected $sorted = false;
59 * @param int $priority
63 public function insert($name, $value, $priority = 0)
65 if (! isset($this->items[$name])) {
69 $this->sorted = false;
71 $this->items[$name] = [
73 'priority' => (int) $priority,
74 'serial' => $this->serial++,
80 * @param int $priority
86 public function setPriority($name, $priority)
88 if (! isset($this->items[$name])) {
89 throw new \Exception("item $name not found");
92 $this->items[$name]['priority'] = (int) $priority;
93 $this->sorted = false;
101 * @param string $name
104 public function remove($name)
106 if (isset($this->items[$name])) {
110 unset($this->items[$name]);
118 public function clear()
123 $this->sorted = false;
129 * @param string $name
132 public function get($name)
134 if (! isset($this->items[$name])) {
138 return $this->items[$name]['data'];
146 protected function sort()
148 if (! $this->sorted) {
149 uasort($this->items, [$this, 'compare']);
150 $this->sorted = true;
155 * Compare the priority of two items.
157 * @param array $item1,
158 * @param array $item2
161 protected function compare(array $item1, array $item2)
163 return ($item1['priority'] === $item2['priority'])
164 ? ($item1['serial'] > $item2['serial'] ? -1 : 1) * $this->isLIFO
165 : ($item1['priority'] > $item2['priority'] ? -1 : 1);
169 * Get/Set serial order mode
171 * @param bool|null $flag
175 public function isLIFO($flag = null)
177 if ($flag !== null) {
178 $isLifo = $flag === true ? 1 : -1;
180 if ($isLifo !== $this->isLIFO) {
181 $this->isLIFO = $isLifo;
182 $this->sorted = false;
186 return 1 === $this->isLIFO;
192 public function rewind()
201 public function current()
203 $this->sorted || $this->sort();
204 $node = current($this->items);
206 return $node ? $node['data'] : false;
212 public function key()
214 $this->sorted || $this->sort();
215 return key($this->items);
221 public function next()
223 $node = next($this->items);
225 return $node ? $node['data'] : false;
231 public function valid()
233 return current($this->items) !== false;
239 public function getIterator()
247 public function count()
253 * Return list as array
259 public function toArray($flag = self::EXTR_DATA)
263 if ($flag == self::EXTR_BOTH) {
268 function ($item) use ($flag) {
269 return ($flag == PriorityList::EXTR_PRIORITY) ? $item['priority'] : $item['data'];