1: <?php
2: /**
3: * This file is part of the Pipeliner API client library for PHP
4: *
5: * Copyright 2014 Pipelinersales, Inc. All Rights Reserved.
6: * For the full license information, see the attached LICENSE file.
7: */
8:
9: namespace PipelinerSales\ApiClient;
10:
11: use PipelinerSales\ApiClient\Repository\RepositoryInterface;
12:
13: /**
14: * Class for conveniently iterating through collections of entities beyond the
15: * ones which have been loaded from the server.
16: *
17: * Represents a range 0-n, where n is the number of entities that the query
18: * would have returned if no limit was set. Only a part of this range is loaded
19: * at a time, so iterating may cause additional HTTP requests to be issued.
20: */
21: class EntityCollectionIterator implements \SeekableIterator
22: {
23: /** @var Query\Criteria */
24: private $criteria;
25: private $repository;
26: private $collection;
27: private $position;
28:
29: /**
30: * @param RepositoryInterface $repository repository for loading additional entities
31: * @param EntityCollection $collection initial collection of already loaded entities
32: */
33: public function __construct(RepositoryInterface $repository, EntityCollection $collection)
34: {
35: $this->repository = $repository;
36: $this->collection = $collection;
37:
38: $this->criteria = $this->collection->getCriteriaCopy();
39: $this->position = $this->criteria->getOffset(true);
40: }
41:
42: /**
43: * @return Entity
44: */
45: public function current()
46: {
47: if ($this->dataAvailable()) {
48: return $this->collection->offsetGet($this->position - $this->collection->getStartIndex());
49: } else {
50: $this->criteria->offset($this->position);
51: $this->collection = $this->repository->get($this->criteria);
52: return $this->collection->offsetGet($this->position - $this->collection->getStartIndex());
53: }
54: }
55:
56: /**
57: * @return integer
58: */
59: public function key()
60: {
61: return $this->position;
62: }
63:
64: public function next()
65: {
66: $this->position++;
67: }
68:
69: public function rewind()
70: {
71: $this->position = 0;
72: }
73:
74: public function valid()
75: {
76: return ($this->position >= 0 and $this->position < $this->collection->getTotalCount());
77: }
78:
79: /**
80: * True if data for the current position has been loaded from the server and is
81: * locally available.
82: * @return boolean
83: */
84: public function dataAvailable()
85: {
86: return ($this->position >= $this->collection->getStartIndex() and
87: $this->position <= $this->collection->getEndIndex());
88: }
89:
90: /**
91: * True if data for the next position has been loaded from the server and is
92: * locally available. This is useful in foreach loops to determine whether the
93: * next iteration will issue a HTTP request.
94: * @return boolean
95: */
96: public function nextDataAvailable()
97: {
98: return ($this->position+1 >= $this->collection->getStartIndex() and
99: $this->position+1 <= $this->collection->getEndIndex());
100: }
101:
102: /**
103: * True if the current position is the last position within the range.
104: * @return boolean
105: */
106: public function atEnd()
107: {
108: return ($this->position == $this->collection->getTotalCount()-1);
109: }
110:
111: public function seek($position)
112: {
113: $this->position = $position;
114: }
115: }
116: