1 | <?php |
||
271 | class SS_Map_Iterator implements Iterator { |
||
272 | |||
273 | protected $items; |
||
274 | protected $keyField, $titleField; |
||
275 | |||
276 | protected $firstItemIdx = 0; |
||
277 | |||
278 | protected $endItemIdx; |
||
279 | |||
280 | protected $firstItems = array(); |
||
281 | protected $lastItems = array(); |
||
282 | |||
283 | protected $excludedItems = array(); |
||
284 | |||
285 | /** |
||
286 | * @param Iterator $items The iterator to build this map from |
||
287 | * @param string $keyField The field to use for the keys |
||
288 | * @param string $titleField The field to use for the values |
||
289 | * @param array $fristItems An optional map of items to show first |
||
290 | * @param array $lastItems An optional map of items to show last |
||
291 | */ |
||
292 | public function __construct(Iterator $items, $keyField, $titleField, $firstItems = null, $lastItems = null) { |
||
293 | $this->items = $items; |
||
294 | $this->keyField = $keyField; |
||
295 | $this->titleField = $titleField; |
||
296 | $this->endItemIdx = null; |
||
297 | |||
298 | if($firstItems) { |
||
299 | foreach($firstItems as $k => $v) { |
||
300 | $this->firstItems[] = array($k,$v); |
||
301 | $this->excludedItems[] = $k; |
||
302 | } |
||
303 | } |
||
304 | |||
305 | if($lastItems) { |
||
306 | foreach($lastItems as $k => $v) { |
||
307 | $this->lastItems[] = array($k, $v); |
||
308 | $this->excludedItems[] = $k; |
||
309 | } |
||
310 | } |
||
311 | |||
312 | } |
||
313 | |||
314 | /** |
||
315 | * Rewind the Iterator to the first element. |
||
316 | * |
||
317 | * @return mixed |
||
318 | */ |
||
319 | public function rewind() { |
||
320 | $this->firstItemIdx = 0; |
||
321 | $this->endItemIdx = null; |
||
322 | |||
323 | $rewoundItem = $this->items->rewind(); |
||
324 | |||
325 | if(isset($this->firstItems[$this->firstItemIdx])) { |
||
326 | return $this->firstItems[$this->firstItemIdx][1]; |
||
327 | } else { |
||
328 | if($rewoundItem) { |
||
329 | if($rewoundItem->hasMethod($this->titleField)) { |
||
330 | return $rewoundItem->{$this->titleField}(); |
||
331 | } |
||
332 | |||
333 | return $rewoundItem->{$this->titleField}; |
||
334 | } else if(!$this->items->valid() && $this->lastItems) { |
||
335 | $this->endItemIdx = 0; |
||
336 | |||
337 | return $this->lastItems[0][1]; |
||
338 | } |
||
339 | } |
||
340 | } |
||
341 | |||
342 | /** |
||
343 | * Return the current element. |
||
344 | * |
||
345 | * @return mixed |
||
346 | */ |
||
347 | public function current() { |
||
348 | if(($this->endItemIdx !== null) && isset($this->lastItems[$this->endItemIdx])) { |
||
349 | return $this->lastItems[$this->endItemIdx][1]; |
||
350 | } else if(isset($this->firstItems[$this->firstItemIdx])) { |
||
351 | return $this->firstItems[$this->firstItemIdx][1]; |
||
352 | } else { |
||
353 | if($this->items->current()->hasMethod($this->titleField)) { |
||
354 | return $this->items->current()->{$this->titleField}(); |
||
355 | } |
||
356 | |||
357 | return $this->items->current()->{$this->titleField}; |
||
358 | } |
||
359 | } |
||
360 | |||
361 | /** |
||
362 | * Return the key of the current element. |
||
363 | * |
||
364 | * @return string |
||
365 | */ |
||
366 | public function key() { |
||
375 | |||
376 | /** |
||
377 | * Move forward to next element. |
||
378 | * |
||
379 | * @return mixed |
||
380 | */ |
||
381 | public function next() { |
||
382 | $this->firstItemIdx++; |
||
383 | |||
384 | if(isset($this->firstItems[$this->firstItemIdx])) { |
||
385 | return $this->firstItems[$this->firstItemIdx][1]; |
||
386 | } else { |
||
387 | if(!isset($this->firstItems[$this->firstItemIdx-1])) { |
||
388 | $this->items->next(); |
||
389 | } |
||
390 | |||
391 | if($this->excludedItems) { |
||
392 | while(($c = $this->items->current()) && in_array($c->{$this->keyField}, $this->excludedItems, true)) { |
||
393 | $this->items->next(); |
||
394 | } |
||
395 | } |
||
396 | } |
||
397 | |||
398 | if(!$this->items->valid()) { |
||
399 | // iterator has passed the preface items, off the end of the items |
||
400 | // list. Track through the end items to go through to the next |
||
401 | if($this->endItemIdx === null) { |
||
402 | $this->endItemIdx = -1; |
||
403 | } |
||
404 | |||
405 | $this->endItemIdx++; |
||
406 | |||
407 | if(isset($this->lastItems[$this->endItemIdx])) { |
||
408 | return $this->lastItems[$this->endItemIdx]; |
||
409 | } |
||
410 | |||
411 | return false; |
||
412 | } |
||
413 | } |
||
414 | |||
415 | /** |
||
416 | * Checks if current position is valid. |
||
417 | * |
||
418 | * @return boolean |
||
419 | */ |
||
420 | public function valid() { |
||
427 | } |
||
428 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.