phpdoc
[m6w6/pq-gateway] / lib / pq / Mapper / ObjectManager.php
1 <?php
2
3 namespace pq\Mapper;
4
5 use OutOfBoundsException;
6 use pq\Exception\BadMethodCallException;
7 use pq\Gateway\Row;
8
9 class ObjectManager
10 {
11 /**
12 * @var MapInterface
13 */
14 private $map;
15
16 /**
17 * @var object[]
18 */
19 private $obj = [];
20
21 /**
22 * @var Row[]
23 */
24 private $row = [];
25
26 /**
27 * Create a new ObjectManager for a mapping
28 * @param MapInterface $map
29 */
30 function __construct(MapInterface $map) {
31 $this->map = $map;
32 }
33
34 /**
35 * Reset all managed objects
36 */
37 function reset() {
38 $this->obj = [];
39 $this->row = [];
40 }
41
42 /**
43 * Get the serialized row identity
44 *
45 * When $check is true, the identity will only be serialized if all columns
46 * of the primary key are set.
47 *
48 * @param Row $row
49 * @param bool $check
50 * @return string|false serialized row id or false on failure
51 */
52 function rowId(Row $row, $check = false) {
53 try {
54 $identity = $row->getIdentity();
55 } catch (OutOfBoundsException $e) {
56 return false;
57 }
58 return $this->serializeRowId($identity, $check);
59 }
60
61 /**
62 * Get an object's identity
63 * @param object $object
64 * @return string
65 */
66 function objectId($object) {
67 return spl_object_hash($object);
68 }
69
70 /**
71 * Extract a row's identity from a mapped object
72 * @param object $object
73 * @return string serialized row identity
74 */
75 function extractRowId($object) {
76 $id = [];
77 foreach ($this->map->getGateway()->getIdentity() as $col) {
78 foreach ($this->map->getProperties() as $property) {
79 if ($property->exposes($col)) {
80 $id[$col] = $property->extract($object);
81 }
82 }
83 }
84 return $this->serializeRowId($id, true);
85 }
86
87 /**
88 * Serialize a row's identity
89 * @param mixed $identity
90 * @param bool $check
91 * @return string|false the serialized row identity or false on failure
92 */
93 function serializeRowId($identity, $check = false) {
94 if (is_scalar($identity)) {
95 return $identity;
96 }
97
98 if ($check && !isset($identity)) {
99 return false;
100 }
101
102 if (is_array($identity)) {
103 if ($check && array_search(null, $identity, true)) {
104 return false;
105 }
106 /* one level is better than no level */
107 asort($identity);
108 }
109 return json_encode($identity);
110 }
111
112 /**
113 * Check whether a mapped object is already cached in the manager
114 * @param string $row_id
115 * @return bool
116 */
117 function hasObject($row_id) {
118 return isset($this->obj[$row_id]);
119 }
120
121 /**
122 * Create a mapped object from $row
123 * @param Row $row
124 * @return object
125 */
126 function createObject(Row $row) {
127 $rid = $this->rowId($row);
128 $cls = $this->map->getClass();
129 $obj = new $cls;
130 $oid = $this->objectId($obj);
131 $this->obj[$rid] = $obj;
132 $this->row[$oid] = $row;
133 return $obj;
134 }
135
136 /**
137 * Forget the mapped object of $row
138 * @param Row $row
139 */
140 function resetObject(Row $row) {
141 unset($this->obj[$this->rowId($row)]);
142 }
143
144 /**
145 * Get the mapped object of $row
146 * @param Row $row
147 * @return object
148 */
149 function getObject(Row $row) {
150 $id = $this->rowId($row);
151 return $this->getObjectById($id);
152 }
153
154 /**
155 * Get the mapped object of $row
156 * @param string $row_id
157 * @return object
158 * @throws BadMethodCallException
159 */
160 function getObjectById($row_id) {
161 if (!$this->hasObject($row_id)) {
162 throw new BadMethodCallException("Object of row with id $row_id does not exist");
163 }
164 return $this->obj[$row_id];
165 }
166
167 /**
168 * Check for a mapped object of $row, and create if necessary
169 * @param Row $row
170 * @return object
171 */
172 function asObject(Row $row){
173 return $this->hasObject($this->rowId($row))
174 ? $this->getObject($row)
175 : $this->createObject($row);
176 }
177
178 /**
179 * Check whether a row for a mapped object exists
180 * @param string $obj_id
181 * @return Row
182 */
183 function hasRow($obj_id) {
184 return isset($this->row[$obj_id]);
185 }
186
187 /**
188 * Initialize a Row from a mapped object
189 * @param object $object
190 * @return Row
191 */
192 function createRow($object) {
193 $oid = $this->objectId($object);
194 $row = new Row($this->map->getGateway());
195 $this->row[$oid] = $row;
196 return $row;
197 }
198
199 /**
200 * Forget about a row of a mapped object
201 * @param object $object
202 */
203 function resetRow($object) {
204 unset($this->row [$this->objectId($object)]);
205 }
206
207 /**
208 * Get the row of a mapped object
209 * @param object $object
210 * @return Row
211 * @throws BadMethodCallException
212 */
213 function getRow($object) {
214 $id = $this->objectId($object);
215
216 if (!$this->hasRow($id)) {
217 throw new BadMethodCallException("Row for object with id $id does not exist");
218 }
219 return $this->row[$id];
220 }
221
222 /**
223 * Check for a row of a mapped object, create from object if neccessary
224 * @param object $object
225 * @return Row
226 */
227 function asRow($object) {
228 return $this->hasRow($this->objectId($object))
229 ? $this->getRow($object)
230 : $this->createRow($object);
231 }
232 }