Chris@0: items[$name])) { Chris@0: $this->count++; Chris@0: } Chris@0: Chris@0: $this->sorted = false; Chris@0: Chris@0: $this->items[$name] = [ Chris@0: 'data' => $value, Chris@0: 'priority' => (int) $priority, Chris@0: 'serial' => $this->serial++, Chris@0: ]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @param string $name Chris@0: * @param int $priority Chris@0: * Chris@0: * @return $this Chris@0: * Chris@0: * @throws \Exception Chris@0: */ Chris@0: public function setPriority($name, $priority) Chris@0: { Chris@12: if (! isset($this->items[$name])) { Chris@0: throw new \Exception("item $name not found"); Chris@0: } Chris@0: Chris@0: $this->items[$name]['priority'] = (int) $priority; Chris@0: $this->sorted = false; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Remove a item. Chris@0: * Chris@0: * @param string $name Chris@0: * @return void Chris@0: */ Chris@0: public function remove($name) Chris@0: { Chris@0: if (isset($this->items[$name])) { Chris@0: $this->count--; Chris@0: } Chris@0: Chris@0: unset($this->items[$name]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Remove all items. Chris@0: * Chris@0: * @return void Chris@0: */ Chris@0: public function clear() Chris@0: { Chris@0: $this->items = []; Chris@0: $this->serial = 0; Chris@0: $this->count = 0; Chris@0: $this->sorted = false; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get a item. Chris@0: * Chris@0: * @param string $name Chris@0: * @return mixed Chris@0: */ Chris@0: public function get($name) Chris@0: { Chris@12: if (! isset($this->items[$name])) { Chris@0: return; Chris@0: } Chris@0: Chris@0: return $this->items[$name]['data']; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sort all items. Chris@0: * Chris@0: * @return void Chris@0: */ Chris@0: protected function sort() Chris@0: { Chris@12: if (! $this->sorted) { Chris@0: uasort($this->items, [$this, 'compare']); Chris@0: $this->sorted = true; Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Compare the priority of two items. Chris@0: * Chris@0: * @param array $item1, Chris@0: * @param array $item2 Chris@0: * @return int Chris@0: */ Chris@0: protected function compare(array $item1, array $item2) Chris@0: { Chris@0: return ($item1['priority'] === $item2['priority']) Chris@12: ? ($item1['serial'] > $item2['serial'] ? -1 : 1) * $this->isLIFO Chris@0: : ($item1['priority'] > $item2['priority'] ? -1 : 1); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Get/Set serial order mode Chris@0: * Chris@0: * @param bool|null $flag Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function isLIFO($flag = null) Chris@0: { Chris@0: if ($flag !== null) { Chris@0: $isLifo = $flag === true ? 1 : -1; Chris@0: Chris@0: if ($isLifo !== $this->isLIFO) { Chris@0: $this->isLIFO = $isLifo; Chris@0: $this->sorted = false; Chris@0: } Chris@0: } Chris@0: Chris@0: return 1 === $this->isLIFO; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritDoc} Chris@0: */ Chris@0: public function rewind() Chris@0: { Chris@0: $this->sort(); Chris@0: reset($this->items); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritDoc} Chris@0: */ Chris@0: public function current() Chris@0: { Chris@0: $this->sorted || $this->sort(); Chris@0: $node = current($this->items); Chris@0: Chris@0: return $node ? $node['data'] : false; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritDoc} Chris@0: */ Chris@0: public function key() Chris@0: { Chris@0: $this->sorted || $this->sort(); Chris@0: return key($this->items); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritDoc} Chris@0: */ Chris@0: public function next() Chris@0: { Chris@0: $node = next($this->items); Chris@0: Chris@0: return $node ? $node['data'] : false; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritDoc} Chris@0: */ Chris@0: public function valid() Chris@0: { Chris@0: return current($this->items) !== false; Chris@0: } Chris@0: Chris@0: /** Chris@0: * @return self Chris@0: */ Chris@0: public function getIterator() Chris@0: { Chris@0: return clone $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritDoc} Chris@0: */ Chris@0: public function count() Chris@0: { Chris@0: return $this->count; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Return list as array Chris@0: * Chris@0: * @param int $flag Chris@0: * Chris@0: * @return array Chris@0: */ Chris@0: public function toArray($flag = self::EXTR_DATA) Chris@0: { Chris@0: $this->sort(); Chris@0: Chris@0: if ($flag == self::EXTR_BOTH) { Chris@0: return $this->items; Chris@0: } Chris@0: Chris@0: return array_map( Chris@0: function ($item) use ($flag) { Chris@0: return ($flag == PriorityList::EXTR_PRIORITY) ? $item['priority'] : $item['data']; Chris@0: }, Chris@0: $this->items Chris@0: ); Chris@0: } Chris@0: }