00001 <?php
00095 class ElggPriorityList
00096 implements Iterator, Countable {
00097
00103 private $elements = array();
00104
00110 public function __construct(array $elements = array()) {
00111 if ($elements) {
00112 foreach ($elements as $priority => $element) {
00113 $this->add($element, $priority);
00114 }
00115 }
00116 }
00117
00133 public function add($element, $priority = null, $exact = false) {
00134 if ($priority !== null && !is_numeric($priority)) {
00135 return false;
00136 } else {
00137 $priority = $this->getNextPriority($priority);
00138 }
00139
00140 $this->elements[$priority] = $element;
00141 $this->sorted = false;
00142 return $priority;
00143 }
00144
00155 public function remove($element, $strict = false) {
00156 $index = array_search($element, $this->elements, $strict);
00157 if ($index !== false) {
00158 unset($this->elements[$index]);
00159 return true;
00160 } else {
00161 return false;
00162 }
00163 }
00164
00173 public function move($element, $new_priority, $strict = false) {
00174 $new_priority = (int) $new_priority;
00175
00176 $current_priority = $this->getPriority($element, $strict);
00177 if ($current_priority === false) {
00178 return false;
00179 }
00180
00181 if ($current_priority == $new_priority) {
00182 return true;
00183 }
00184
00185
00186 $element = $this->getElement($current_priority);
00187 unset($this->elements[$current_priority]);
00188 return $this->add($element, $new_priority);
00189 }
00190
00196 public function getElements() {
00197 $this->sortIfUnsorted();
00198 return $this->elements;
00199 }
00200
00214 public function sort($callback = null) {
00215 if (!$callback) {
00216 ksort($this->elements, SORT_NUMERIC);
00217 } else {
00218 $sorted = call_user_func($callback, $this->elements);
00219
00220 if (!$sorted) {
00221 return false;
00222 }
00223
00224 $this->elements = $sorted;
00225 }
00226
00227 $this->sorted = true;
00228 return true;
00229 }
00230
00236 private function sortIfUnsorted() {
00237 if (!$this->sorted) {
00238 return $this->sort();
00239 }
00240 }
00241
00248 public function getNextPriority($near = 0) {
00249 $near = (int) $near;
00250
00251 while (array_key_exists($near, $this->elements)) {
00252 $near++;
00253 }
00254
00255 return $near;
00256 }
00257
00267 public function getPriority($element, $strict = false) {
00268 return array_search($element, $this->elements, $strict);
00269 }
00270
00277 public function getElement($priority) {
00278 return (isset($this->elements[$priority])) ? $this->elements[$priority] : false;
00279 }
00280
00288 public function contains($element, $strict = false) {
00289 return $this->getPriority($element, $strict) !== false;
00290 }
00291
00292
00293
00294
00295
00296
00307 public function rewind() {
00308 $this->sortIfUnsorted();
00309 return reset($this->elements);
00310 }
00311
00318 public function current() {
00319 $this->sortIfUnsorted();
00320 return current($this->elements);
00321 }
00322
00329 public function key() {
00330 $this->sortIfUnsorted();
00331 return key($this->elements);
00332 }
00333
00340 public function next() {
00341 $this->sortIfUnsorted();
00342 return next($this->elements);
00343 }
00344
00351 public function valid() {
00352 $this->sortIfUnsorted();
00353 $key = key($this->elements);
00354 return ($key !== NULL && $key !== FALSE);
00355 }
00356
00363 public function count() {
00364 return count($this->elements);
00365 }
00366 }