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\Query\Criteria;
12:
13: /**
14: * Represents an immutable collection of multiple entities of a common type. The
15: * entities themselves are mutable (i.e. you can modify the entity object inside
16: * the collection, but you can not add/remove/reorder/etc. entities from/to the collection.
17: *
18: * Works like a regular PHP array, but contains additional information about the
19: * number of entities that were not loaded due to a query limit.
20: *
21: * @method Entity[] getArrayCopy
22: */
23: class EntityCollection extends \ArrayObject
24: {
25:
26: private $criteria;
27: private $totalCount;
28: private $startIndex;
29: private $endIndex;
30: private static $immutableError = 'EntityCollection is immutable';
31:
32: /**
33: * Creates a collection based on an existing array
34: *
35: * @param array $data
36: * @param mixed $criteria Criteria that was used when querying for this colleciton. Any type
37: * that the can be passed to the constructor of {@see Criteria} can be used here. A copy of this
38: * argument will be made, so it is safe to pass a Criteria object - it will not be inadvertently
39: * modified at a later time.
40: * @param integer $startIndex the offset used in the query
41: * @param integer $endIndex the offset of the last loaded entity
42: * @param integer $totalCount total count of all entities that match the query
43: * @throws PipelinerClientException when the number of items in the array doesn't match the specified indexes
44: */
45: public function __construct($data, $criteria, $startIndex, $endIndex, $totalCount)
46: {
47: parent::__construct($data);
48:
49: //sanity check
50: if ($endIndex - $startIndex + 1 != $this->count()) {
51: //empty collections are a special case - Pipeliner's server currently returns 0 - -1 range in such a case
52: if ($endIndex != -1) {
53: throw new
54: PipelinerClientException('Returned content range doesn\'t match the number of returned entities');
55: }
56: }
57:
58: $this->criteria = new Criteria($criteria);
59: $this->startIndex = $startIndex;
60: $this->totalCount = $totalCount;
61: $this->endIndex = $endIndex;
62: }
63:
64: /**
65: * Returns the number of entities available on the server (ignoring the limit).
66: * @return integer
67: */
68: public function getTotalCount()
69: {
70: return $this->totalCount;
71: }
72:
73: /**
74: * Returns a copy of the criteria that was used to fetch this collection.
75: * @return Criteria
76: */
77: public function getCriteriaCopy()
78: {
79: return clone $this->criteria;
80: }
81:
82: /**
83: * Returns the index of the first item in this colleciton. It is
84: * identical to the offset that was used to fetch this collection.
85: * @return integer
86: */
87: public function getStartIndex()
88: {
89: return $this->startIndex;
90: }
91:
92: /**
93: * Returns the index of the last item in this collection.
94: * @return integer
95: */
96: public function getEndIndex()
97: {
98: return $this->endIndex;
99: }
100:
101: /** @ignore */
102: public function offsetSet($index, $newval)
103: {
104: throw new PipelinerClientException(self::$immutableError);
105: }
106:
107: /** @ignore */
108: public function offsetUnset($index)
109: {
110: throw new PipelinerClientException(self::$immutableError);
111: }
112:
113: /** @ignore */
114: public function exchangeArray($input)
115: {
116: throw new PipelinerClientException(self::$immutableError);
117: }
118:
119: /** @ignore */
120: public function asort()
121: {
122: throw new PipelinerClientException(self::$immutableError);
123: }
124:
125: /** @ignore */
126: public function natsort()
127: {
128: throw new PipelinerClientException(self::$immutableError);
129: }
130:
131: /** @ignore */
132: public function append($value)
133: {
134: throw new PipelinerClientException(self::$immutableError);
135: }
136:
137: /** @ignore */
138: public function natcasesort()
139: {
140: throw new PipelinerClientException(self::$immutableError);
141: }
142:
143: /** @ignore */
144: public function uasort($cmp_function)
145: {
146: throw new PipelinerClientException(self::$immutableError);
147: }
148:
149: /** @ignore */
150: public function uksort($cmp_function)
151: {
152: throw new PipelinerClientException(self::$immutableError);
153: }
154:
155: /** @ignore */
156: public function ksort()
157: {
158: throw new PipelinerClientException(self::$immutableError);
159: }
160: }
161: