1: <?php
2: 3: 4: 5: 6: 7: 8:
9:
10: namespace OpenCloud\Common\Collection;
11:
12: use Iterator;
13: use OpenCloud\Common\Log\Logger;
14: use OpenCloud\Common\Exceptions\InvalidArgumentError;
15:
16: class ResourceIterator extends ArrayCollection implements Iterator
17: {
18: 19: 20:
21: protected $position;
22:
23: 24: 25: 26:
27: protected $resourceParent;
28:
29: 30: 31:
32: protected $options;
33:
34: 35: 36:
37: protected $defaults = array();
38:
39: 40: 41:
42: protected $required = array();
43:
44: public static function factory($parent, array $options = array(), array $data = array())
45: {
46: $iterator = new static($data);
47:
48: $iterator->setResourceParent($parent)
49: ->setElements($data)
50: ->setOptions($iterator->parseOptions($options))
51: ->rewind();
52:
53: return $iterator;
54: }
55:
56: protected function parseOptions(array $options)
57: {
58: $options = $options + $this->defaults;
59:
60: if ($missing = array_diff($this->required, array_keys($options))) {
61: throw new InvalidArgumentError(sprintf('%s is a required option', implode(',', $missing)));
62: }
63:
64: return $options;
65: }
66:
67: 68: 69: 70:
71: public function setResourceParent($parent)
72: {
73: $this->resourceParent = $parent;
74: return $this;
75: }
76:
77: 78: 79: 80:
81: public function setOptions(array $options)
82: {
83: $this->options = $options;
84: return $this;
85: }
86:
87: 88: 89: 90: 91: 92: 93:
94: public function setOption($key, $value)
95: {
96: $this->options[$key] = $value;
97: return $this;
98: }
99:
100: 101: 102: 103:
104: public function getOption($key)
105: {
106: return (isset($this->options[$key])) ? $this->options[$key] : null;
107: }
108:
109: 110: 111: 112: 113:
114: public function valid()
115: {
116: return $this->offsetExists($this->position) && $this->position < $this->limit;
117: }
118:
119: 120: 121:
122: public function next()
123: {
124: $this->position++;
125: return $this->current();
126: }
127:
128: 129: 130:
131: public function rewind()
132: {
133: $this->position = 0;
134: }
135:
136: 137: 138:
139: public function current()
140: {
141: return $this->constructResource($this->currentElement());
142: }
143:
144: 145: 146:
147: public function currentElement()
148: {
149: return $this->offsetGet($this->key());
150: }
151:
152: 153: 154: 155: 156: 157: 158: 159:
160: public function constructResource($object)
161: {
162: $className = $this->getOption('resourceClass');
163:
164: if (substr_count($className, '\\')) {
165: $array = explode('\\', $className);
166: $className = end($array);
167: }
168:
169: $parent = $this->resourceParent;
170: $getter = sprintf('get%s', ucfirst($className));
171:
172: if (method_exists($parent, $className)) {
173:
174: return call_user_func(array($parent, $className), $object);
175: } elseif (method_exists($parent, $getter)) {
176:
177: return call_user_func(array($parent, $getter), $object);
178: } elseif (method_exists($parent, 'resource')) {
179:
180: return $parent->resource($className, $object);
181: } else {
182: return $object;
183: }
184: }
185:
186: 187: 188: 189: 190:
191: public function key()
192: {
193: return $this->position;
194: }
195:
196: public function getElement($offset)
197: {
198: return (!$this->offsetExists($offset)) ? false : $this->constructResource($this->offsetGet($offset));
199: }
200:
201: 202: 203:
204: public function first()
205: {
206: Logger::newInstance()->deprecated(__METHOD__, 'getElement');
207: return $this->getElement(0);
208: }
209:
210: 211: 212:
213: public function sort()
214: {
215: }
216:
217: }