These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /* |
||
3 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||
4 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||
5 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||
6 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||
7 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||
8 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||
9 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||
10 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||
11 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
12 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||
13 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
14 | * |
||
15 | * This software consists of voluntary contributions made by many individuals |
||
16 | * and is licensed under the MIT license. For more information, see |
||
17 | * <http://www.doctrine-project.org>. |
||
18 | */ |
||
19 | |||
20 | namespace Doctrine\ODM\MongoDB; |
||
21 | |||
22 | use Doctrine\MongoDB\Collection; |
||
23 | use Doctrine\MongoDB\Connection; |
||
24 | use Doctrine\MongoDB\CursorInterface; |
||
25 | use Doctrine\MongoDB\EagerCursor as BaseEagerCursor; |
||
26 | use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; |
||
27 | use Doctrine\ODM\MongoDB\Query\Query; |
||
28 | use Doctrine\ODM\MongoDB\Query\ReferencePrimer; |
||
29 | |||
30 | /** |
||
31 | * Wrapper for the Doctrine\MongoDB\Cursor class. |
||
32 | * |
||
33 | * This class composes a Doctrine\MongoDB\Cursor instance and wraps its methods |
||
34 | * in order to return results as hydrated document class instances. Hydration |
||
35 | * behavior may be controlled with the {@link Cursor::hydrate()} method. |
||
36 | * |
||
37 | * For compatibility, this class also extends Doctrine\MongoDB\Cursor. |
||
38 | * |
||
39 | * @since 1.0 |
||
40 | */ |
||
41 | class Cursor implements CursorInterface |
||
42 | { |
||
43 | /** |
||
44 | * The Doctrine\MongoDB\Cursor instance being wrapped. |
||
45 | * |
||
46 | * @var CursorInterface |
||
47 | */ |
||
48 | private $baseCursor; |
||
49 | |||
50 | /** |
||
51 | * The ClassMetadata instance for the document class being queried. |
||
52 | * |
||
53 | * @var ClassMetadata |
||
54 | */ |
||
55 | private $class; |
||
56 | |||
57 | /** |
||
58 | * Whether or not to hydrate results as document class instances. |
||
59 | * |
||
60 | * @var boolean |
||
61 | */ |
||
62 | private $hydrate = true; |
||
63 | |||
64 | /** |
||
65 | * The UnitOfWork instance used for result hydration and preparing arguments |
||
66 | * for {@link Cursor::sort()}. |
||
67 | * |
||
68 | * @var UnitOfWork |
||
69 | */ |
||
70 | private $unitOfWork; |
||
71 | |||
72 | /** |
||
73 | * Hints for UnitOfWork behavior. |
||
74 | * |
||
75 | * @var array |
||
76 | */ |
||
77 | private $unitOfWorkHints = array(); |
||
78 | |||
79 | /** |
||
80 | * ReferencePrimer object for priming references |
||
81 | * |
||
82 | * @var ReferencePrimer |
||
83 | */ |
||
84 | private $referencePrimer; |
||
85 | |||
86 | /** |
||
87 | * Primers |
||
88 | * |
||
89 | * @var array |
||
90 | */ |
||
91 | private $primers = array(); |
||
92 | |||
93 | /** |
||
94 | * Whether references have been primed |
||
95 | * |
||
96 | * @var bool |
||
97 | */ |
||
98 | private $referencesPrimed = false; |
||
99 | |||
100 | /** |
||
101 | * Constructor. |
||
102 | * |
||
103 | * @param CursorInterface $baseCursor Cursor instance being wrapped |
||
104 | * @param UnitOfWork $unitOfWork UnitOfWork for result hydration and query preparation |
||
105 | * @param ClassMetadata $class ClassMetadata for the document class being queried |
||
106 | */ |
||
107 | 149 | public function __construct(CursorInterface $baseCursor, UnitOfWork $unitOfWork, ClassMetadata $class) |
|
108 | { |
||
109 | 149 | $this->baseCursor = $baseCursor; |
|
110 | 149 | $this->unitOfWork = $unitOfWork; |
|
111 | 149 | $this->class = $class; |
|
112 | 149 | } |
|
113 | |||
114 | /** |
||
115 | * Return the wrapped Doctrine\MongoDB\Cursor instance. |
||
116 | * |
||
117 | * @return CursorInterface |
||
118 | */ |
||
119 | public function getBaseCursor() |
||
120 | { |
||
121 | return $this->baseCursor; |
||
122 | } |
||
123 | |||
124 | /** |
||
125 | * Return the database connection for this cursor. |
||
126 | * |
||
127 | * @see \Doctrine\MongoDB\Cursor::getConnection() |
||
128 | * @return Connection |
||
129 | */ |
||
130 | public function getConnection() |
||
131 | { |
||
132 | return $this->baseCursor->getCollection()->getDatabase()->getConnection(); |
||
133 | } |
||
134 | |||
135 | /** |
||
136 | * Return the collection for this cursor. |
||
137 | * |
||
138 | * @see CursorInterface::getCollection() |
||
139 | * @return Collection |
||
140 | */ |
||
141 | public function getCollection() |
||
142 | { |
||
143 | return $this->baseCursor->getCollection(); |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * Return the selected fields (projection). |
||
148 | * |
||
149 | * @see CursorInterface::getFields() |
||
150 | * @return array |
||
151 | */ |
||
152 | public function getFields() |
||
153 | { |
||
154 | return $this->baseCursor->getFields(); |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * Get hints for UnitOfWork behavior. |
||
159 | * |
||
160 | * @return array |
||
161 | */ |
||
162 | 18 | public function getHints() |
|
163 | { |
||
164 | 18 | return $this->unitOfWorkHints; |
|
165 | } |
||
166 | |||
167 | /** |
||
168 | * Set hints for UnitOfWork behavior. |
||
169 | * |
||
170 | * @param array $hints |
||
171 | */ |
||
172 | 133 | public function setHints(array $hints) |
|
173 | { |
||
174 | 133 | $this->unitOfWorkHints = $hints; |
|
175 | 133 | } |
|
176 | |||
177 | /** |
||
178 | * Return the query criteria. |
||
179 | * |
||
180 | * @see CursorInterface::getQuery() |
||
181 | * @return array |
||
182 | */ |
||
183 | public function getQuery() |
||
184 | { |
||
185 | return $this->baseCursor->getQuery(); |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * Wrapper method for MongoCursor::addOption(). |
||
190 | * |
||
191 | * @see CursorInterface::addOption() |
||
192 | * @see http://php.net/manual/en/mongocursor.addoption.php |
||
193 | * @param string $key |
||
194 | * @param mixed $value |
||
195 | * @return $this |
||
196 | */ |
||
197 | public function addOption($key, $value) |
||
198 | { |
||
199 | $this->baseCursor->addOption($key, $value); |
||
200 | return $this; |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Wrapper method for MongoCursor::batchSize(). |
||
205 | * |
||
206 | * @see CursorInterface::batchSize() |
||
207 | * @see http://php.net/manual/en/mongocursor.batchsize.php |
||
208 | * @param integer $num |
||
209 | * @return $this |
||
210 | */ |
||
211 | public function batchSize($num) |
||
212 | { |
||
213 | $this->baseCursor->batchSize($num); |
||
214 | return $this; |
||
215 | } |
||
216 | |||
217 | /** |
||
218 | * Wrapper method for MongoCursor::count(). |
||
219 | * |
||
220 | * @see CursorInterface::count() |
||
221 | * @see http://php.net/manual/en/countable.count.php |
||
222 | * @see http://php.net/manual/en/mongocursor.count.php |
||
223 | * @param boolean $foundOnly |
||
224 | * @return integer |
||
225 | */ |
||
226 | 25 | public function count($foundOnly = false) |
|
227 | { |
||
228 | 25 | return $this->baseCursor->count($foundOnly); |
|
229 | } |
||
230 | |||
231 | /** |
||
232 | * Wrapper method for MongoCursor::current(). |
||
233 | * |
||
234 | * If configured, the result may be a hydrated document class instance. |
||
235 | * |
||
236 | * @see CursorInterface::current() |
||
237 | * @see http://php.net/manual/en/iterator.current.php |
||
238 | * @see http://php.net/manual/en/mongocursor.current.php |
||
239 | * @return array|object|null |
||
240 | */ |
||
241 | 60 | public function current() |
|
242 | { |
||
243 | 60 | $this->primeReferences(); |
|
244 | |||
245 | 58 | return $this->hydrateDocument($this->baseCursor->current()); |
|
246 | } |
||
247 | |||
248 | /** |
||
249 | * Wrapper method for MongoCursor::dead(). |
||
250 | * |
||
251 | * @see CursorInterface::dead() |
||
252 | * @see http://php.net/manual/en/mongocursor.dead.php |
||
253 | * @return boolean |
||
254 | */ |
||
255 | public function dead() |
||
256 | { |
||
257 | return $this->baseCursor->dead(); |
||
258 | } |
||
259 | |||
260 | /** |
||
261 | * Wrapper method for MongoCursor::explain(). |
||
262 | * |
||
263 | * @see CursorInterface::explain() |
||
264 | * @see http://php.net/manual/en/mongocursor.explain.php |
||
265 | * @return array |
||
266 | */ |
||
267 | public function explain() |
||
268 | { |
||
269 | return $this->baseCursor->explain(); |
||
270 | } |
||
271 | |||
272 | /** |
||
273 | * Wrapper method for MongoCursor::fields(). |
||
274 | * |
||
275 | * @param array $f Fields to return (or not return). |
||
276 | * |
||
277 | * @see CursorInterface::fields() |
||
278 | * @see http://php.net/manual/en/mongocursor.fields.php |
||
279 | * @return $this |
||
280 | */ |
||
281 | public function fields(array $f) |
||
282 | { |
||
283 | $this->baseCursor->fields($f); |
||
284 | return $this; |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * Wrapper method for MongoCursor::getNext(). |
||
289 | * |
||
290 | * If configured, the result may be a hydrated document class instance. |
||
291 | * |
||
292 | * @see CursorInterface::getNext() |
||
293 | * @see http://php.net/manual/en/mongocursor.getnext.php |
||
294 | * @return array|object|null |
||
295 | */ |
||
296 | 3 | public function getNext() |
|
297 | { |
||
298 | 3 | $this->primeReferences(); |
|
299 | |||
300 | 3 | return $this->hydrateDocument($this->baseCursor->getNext()); |
|
301 | } |
||
302 | |||
303 | /** |
||
304 | * Wrapper method for MongoCursor::getReadPreference(). |
||
305 | * |
||
306 | * @see CursorInterface::getReadPreference() |
||
307 | * @see http://php.net/manual/en/mongocursor.getreadpreference.php |
||
308 | * @return array |
||
309 | */ |
||
310 | public function getReadPreference() |
||
311 | { |
||
312 | return $this->baseCursor->getReadPreference(); |
||
313 | } |
||
314 | |||
315 | /** |
||
316 | * Wrapper method for MongoCursor::setReadPreference(). |
||
317 | * |
||
318 | * @see CursorInterface::setReadPreference() |
||
319 | * @see http://php.net/manual/en/mongocursor.setreadpreference.php |
||
320 | * @param string $readPreference |
||
321 | * @param array $tags |
||
322 | * @return $this |
||
323 | */ |
||
324 | public function setReadPreference($readPreference, array $tags = null) |
||
325 | { |
||
326 | $this->baseCursor->setReadPreference($readPreference, $tags); |
||
327 | $this->unitOfWorkHints[Query::HINT_READ_PREFERENCE] = $readPreference; |
||
328 | $this->unitOfWorkHints[Query::HINT_READ_PREFERENCE_TAGS] = $tags; |
||
329 | return $this; |
||
330 | } |
||
331 | |||
332 | /** |
||
333 | * Reset the cursor and return its first result. |
||
334 | * |
||
335 | * The cursor will be reset both before and after the single result is |
||
336 | * fetched. The original cursor limit (if any) will remain in place. |
||
337 | * |
||
338 | * @see Iterator::getSingleResult() |
||
339 | * @return array|object|null |
||
340 | */ |
||
341 | 89 | public function getSingleResult() |
|
342 | { |
||
343 | 89 | $document = $this->hydrateDocument($this->baseCursor->getSingleResult()); |
|
344 | 89 | $this->primeReferencesForSingleResult($document); |
|
345 | |||
346 | 89 | return $document; |
|
347 | } |
||
348 | |||
349 | /** |
||
350 | * {@inheritDoc} |
||
351 | */ |
||
352 | 54 | public function getUseIdentifierKeys() |
|
353 | { |
||
354 | 54 | return $this->baseCursor->getUseIdentifierKeys(); |
|
355 | } |
||
356 | |||
357 | /** |
||
358 | * {@inheritDoc} |
||
359 | */ |
||
360 | 54 | public function setUseIdentifierKeys($useIdentifierKeys) |
|
361 | { |
||
362 | 54 | $this->baseCursor->setUseIdentifierKeys($useIdentifierKeys); |
|
363 | |||
364 | 54 | return $this; |
|
365 | } |
||
366 | |||
367 | /** |
||
368 | * {@inheritDoc} |
||
369 | */ |
||
370 | public function hasNext() |
||
371 | { |
||
372 | return $this->baseCursor->hasNext(); |
||
373 | } |
||
374 | |||
375 | /** |
||
376 | * Wrapper method for MongoCursor::hint(). |
||
377 | * |
||
378 | * This method is intended for setting MongoDB query hints, which are |
||
379 | * unrelated to UnitOfWork hints. |
||
380 | * |
||
381 | * @see CursorInterface::hint() |
||
382 | * @see http://php.net/manual/en/mongocursor.hint.php |
||
383 | * @param array|string $keyPattern |
||
384 | * @return $this |
||
385 | */ |
||
386 | public function hint($keyPattern) |
||
387 | { |
||
388 | $this->baseCursor->hint($keyPattern); |
||
389 | return $this; |
||
390 | } |
||
391 | |||
392 | /** |
||
393 | * Set whether to hydrate results as document class instances. |
||
394 | * |
||
395 | * @param boolean $hydrate |
||
396 | * @return $this |
||
397 | */ |
||
398 | 133 | public function hydrate($hydrate = true) |
|
399 | { |
||
400 | 133 | $this->hydrate = (boolean) $hydrate; |
|
401 | 133 | return $this; |
|
402 | } |
||
403 | |||
404 | /** |
||
405 | * @param array $document |
||
406 | * @return array|object|null |
||
407 | */ |
||
408 | 133 | private function hydrateDocument($document) |
|
409 | { |
||
410 | 133 | if ($document !== null && $this->hydrate) { |
|
411 | 125 | return $this->unitOfWork->getOrCreateDocument($this->class->name, $document, $this->unitOfWorkHints); |
|
412 | } |
||
413 | |||
414 | 12 | return $document; |
|
415 | } |
||
416 | |||
417 | /** |
||
418 | * Wrapper method for MongoCursor::immortal(). |
||
419 | * |
||
420 | * @see CursorInterface::immortal() |
||
421 | * @see http://php.net/manual/en/mongocursor.immortal.php |
||
422 | * @param boolean $liveForever |
||
423 | * @return $this |
||
424 | */ |
||
425 | public function immortal($liveForever = true) |
||
426 | { |
||
427 | $this->baseCursor->immortal($liveForever); |
||
428 | return $this; |
||
429 | } |
||
430 | |||
431 | /** |
||
432 | * Wrapper method for MongoCursor::info(). |
||
433 | * |
||
434 | * @see CursorInterface::info() |
||
435 | * @see http://php.net/manual/en/mongocursor.info.php |
||
436 | * @return array |
||
437 | */ |
||
438 | public function info() |
||
439 | { |
||
440 | return $this->baseCursor->info(); |
||
441 | } |
||
442 | |||
443 | /** |
||
444 | * Wrapper method for MongoCursor::key(). |
||
445 | * |
||
446 | * @see CursorInterface::key() |
||
447 | * @see http://php.net/manual/en/iterator.key.php |
||
448 | * @see http://php.net/manual/en/mongocursor.key.php |
||
449 | * @return string |
||
450 | */ |
||
451 | 5 | public function key() |
|
452 | { |
||
453 | 5 | return $this->baseCursor->key(); |
|
454 | } |
||
455 | |||
456 | /** |
||
457 | * Wrapper method for MongoCursor::limit(). |
||
458 | * |
||
459 | * @see CursorInterface::limit() |
||
460 | * @see http://php.net/manual/en/mongocursor.limit.php |
||
461 | * @param integer $num |
||
462 | * @return $this |
||
463 | */ |
||
464 | 13 | public function limit($num) |
|
465 | { |
||
466 | 13 | $this->baseCursor->limit($num); |
|
467 | 13 | return $this; |
|
468 | } |
||
469 | |||
470 | /** |
||
471 | * Wrapper method for MongoCursor::next(). |
||
472 | * |
||
473 | * @see CursorInterface::next() |
||
474 | * @see http://php.net/manual/en/iterator.next.php |
||
475 | * @see http://php.net/manual/en/mongocursor.next.php |
||
476 | */ |
||
477 | 58 | public function next() |
|
478 | { |
||
479 | 58 | $this->baseCursor->next(); |
|
480 | 58 | } |
|
481 | |||
482 | /** |
||
483 | * Recreates the internal MongoCursor. |
||
484 | * |
||
485 | * @see CursorInterface::recreate() |
||
486 | */ |
||
487 | 2 | public function recreate() |
|
488 | { |
||
489 | 2 | $this->baseCursor->recreate(); |
|
490 | 2 | } |
|
491 | |||
492 | /** |
||
493 | * Set whether to refresh hydrated documents that are already in the |
||
494 | * identity map. |
||
495 | * |
||
496 | * This option has no effect if hydration is disabled. |
||
497 | * |
||
498 | * @param boolean $refresh |
||
499 | * @return $this |
||
500 | */ |
||
501 | public function refresh($refresh = true) |
||
502 | { |
||
503 | $this->unitOfWorkHints[Query::HINT_REFRESH] = (boolean) $refresh; |
||
504 | return $this; |
||
505 | } |
||
506 | |||
507 | /** |
||
508 | * Wrapper method for MongoCursor::reset(). |
||
509 | * |
||
510 | * @see CursorInterface::reset() |
||
511 | * @see http://php.net/manual/en/iterator.reset.php |
||
512 | * @see http://php.net/manual/en/mongocursor.reset.php |
||
513 | */ |
||
514 | 1 | public function reset() |
|
515 | { |
||
516 | 1 | $this->baseCursor->reset(); |
|
517 | 1 | } |
|
518 | |||
519 | /** |
||
520 | * Wrapper method for MongoCursor::rewind(). |
||
521 | * |
||
522 | * @see CursorInterface::rewind() |
||
523 | * @see http://php.net/manual/en/iterator.rewind.php |
||
524 | * @see http://php.net/manual/en/mongocursor.rewind.php |
||
525 | */ |
||
526 | 61 | public function rewind() |
|
527 | { |
||
528 | 61 | $this->baseCursor->rewind(); |
|
529 | 61 | } |
|
530 | |||
531 | /** |
||
532 | * Wrapper method for MongoCursor::skip(). |
||
533 | * |
||
534 | * @see CursorInterface::skip() |
||
535 | * @see http://php.net/manual/en/mongocursor.skip.php |
||
536 | * @param integer $num |
||
537 | * @return $this |
||
538 | */ |
||
539 | 2 | public function skip($num) |
|
540 | { |
||
541 | 2 | $this->baseCursor->skip($num); |
|
542 | 2 | return $this; |
|
543 | } |
||
544 | |||
545 | /** |
||
546 | * Wrapper method for MongoCursor::slaveOkay(). |
||
547 | * |
||
548 | * @see CursorInterface::slaveOkay() |
||
549 | * @see http://php.net/manual/en/mongocursor.slaveokay.php |
||
550 | * @param boolean $ok |
||
551 | * @return $this |
||
552 | * |
||
553 | * @deprecated in version 1.2 - use setReadPreference on the query instead. |
||
554 | */ |
||
555 | public function slaveOkay($ok = true) |
||
556 | { |
||
557 | $ok = (boolean) $ok; |
||
558 | if ($ok) { |
||
559 | @trigger_error( |
||
0 ignored issues
–
show
|
|||
560 | sprintf('%s was deprecated in version 1.2 - use setReadPreference on the query instead.', __METHOD__), |
||
561 | E_USER_DEPRECATED |
||
562 | ); |
||
563 | } |
||
564 | |||
565 | $this->baseCursor->slaveOkay($ok); |
||
566 | $this->unitOfWorkHints[Query::HINT_SLAVE_OKAY] = $ok; |
||
567 | return $this; |
||
568 | } |
||
569 | |||
570 | /** |
||
571 | * Wrapper method for MongoCursor::snapshot(). |
||
572 | * |
||
573 | * @see CursorInterface::snapshot() |
||
574 | * @see http://php.net/manual/en/mongocursor.snapshot.php |
||
575 | * @return $this |
||
576 | */ |
||
577 | public function snapshot() |
||
578 | { |
||
579 | $this->baseCursor->snapshot(); |
||
580 | return $this; |
||
581 | } |
||
582 | |||
583 | /** |
||
584 | * Wrapper method for MongoCursor::sort(). |
||
585 | * |
||
586 | * Field names will be prepared according to the document mapping. |
||
587 | * |
||
588 | * @see CursorInterface::sort() |
||
589 | * @see http://php.net/manual/en/mongocursor.sort.php |
||
590 | * @param array $fields |
||
591 | * @return $this |
||
592 | */ |
||
593 | 14 | public function sort($fields) |
|
594 | { |
||
595 | 14 | $fields = $this->unitOfWork |
|
596 | 14 | ->getDocumentPersister($this->class->name) |
|
597 | 14 | ->prepareSortOrProjection($fields); |
|
598 | |||
599 | 14 | $this->baseCursor->sort($fields); |
|
600 | 14 | return $this; |
|
601 | } |
||
602 | |||
603 | /** |
||
604 | * Wrapper method for MongoCursor::tailable(). |
||
605 | * |
||
606 | * @see CursorInterface::tailable() |
||
607 | * @see http://php.net/manual/en/mongocursor.tailable.php |
||
608 | * @param boolean $tail |
||
609 | * @return $this |
||
610 | */ |
||
611 | public function tailable($tail = true) |
||
612 | { |
||
613 | $this->baseCursor->tailable($tail); |
||
614 | return $this; |
||
615 | } |
||
616 | |||
617 | /** |
||
618 | * Wrapper method for MongoCursor::timeout(). |
||
619 | * |
||
620 | * @see CursorInterface::timeout() |
||
621 | * @see http://php.net/manual/en/mongocursor.timeout.php |
||
622 | * @param integer $ms |
||
623 | * @return $this |
||
624 | */ |
||
625 | public function timeout($ms) |
||
626 | { |
||
627 | $this->baseCursor->timeout($ms); |
||
628 | return $this; |
||
629 | } |
||
630 | |||
631 | /** |
||
632 | * Return the cursor's results as an array. |
||
633 | * |
||
634 | * If documents in the result set use BSON objects for their "_id", the |
||
635 | * $useKeys parameter may be set to false to avoid errors attempting to cast |
||
636 | * arrays (i.e. BSON objects) to string keys. |
||
637 | * |
||
638 | * @see Iterator::toArray() |
||
639 | * @param boolean $useIdentifierKeys |
||
640 | * @return array |
||
641 | */ |
||
642 | 54 | public function toArray($useIdentifierKeys = null) |
|
643 | { |
||
644 | 54 | $originalUseIdentifierKeys = $this->getUseIdentifierKeys(); |
|
645 | 54 | $useIdentifierKeys = isset($useIdentifierKeys) ? (boolean) $useIdentifierKeys : $this->baseCursor->getUseIdentifierKeys(); |
|
646 | |||
647 | /* Let iterator_to_array() decide to use keys or not. This will avoid |
||
648 | * superfluous MongoCursor::info() from the key() method until the |
||
649 | * cursor position is tracked internally. |
||
650 | */ |
||
651 | 54 | $this->setUseIdentifierKeys(true); |
|
652 | |||
653 | 54 | $results = iterator_to_array($this, $useIdentifierKeys); |
|
654 | |||
655 | 52 | $this->setUseIdentifierKeys($originalUseIdentifierKeys); |
|
656 | |||
657 | 52 | return $results; |
|
658 | } |
||
659 | |||
660 | /** |
||
661 | * Wrapper method for MongoCursor::valid(). |
||
662 | * |
||
663 | * @see CursorInterface::valid() |
||
664 | * @see http://php.net/manual/en/iterator.valid.php |
||
665 | * @see http://php.net/manual/en/mongocursor.valid.php |
||
666 | * @return boolean |
||
667 | */ |
||
668 | 65 | public function valid() |
|
669 | { |
||
670 | 65 | return $this->baseCursor->valid(); |
|
671 | } |
||
672 | |||
673 | /** |
||
674 | * @param array $primers |
||
675 | * @param ReferencePrimer $referencePrimer |
||
676 | * @return $this |
||
677 | */ |
||
678 | 23 | public function enableReferencePriming(array $primers, ReferencePrimer $referencePrimer) |
|
679 | { |
||
680 | 23 | if ( ! $this->baseCursor instanceof BaseEagerCursor) { |
|
681 | 1 | throw new \BadMethodCallException("Can't enable reference priming when not using eager cursors."); |
|
682 | } |
||
683 | |||
684 | 22 | $this->referencePrimer = $referencePrimer; |
|
685 | 22 | $this->primers = $primers; |
|
686 | 22 | return $this; |
|
687 | } |
||
688 | |||
689 | /** |
||
690 | * Prime references |
||
691 | */ |
||
692 | 62 | protected function primeReferences() |
|
693 | { |
||
694 | 62 | if ($this->referencesPrimed || ! $this->hydrate || empty($this->primers)) { |
|
695 | 60 | return; |
|
696 | } |
||
697 | |||
698 | 16 | $this->referencesPrimed = true; |
|
699 | |||
700 | 16 | foreach ($this->primers as $fieldName => $primer) { |
|
701 | 16 | $primer = is_callable($primer) ? $primer : null; |
|
702 | 16 | $this->referencePrimer->primeReferences($this->class, $this, $fieldName, $this->unitOfWorkHints, $primer); |
|
703 | } |
||
704 | |||
705 | 14 | $this->rewind(); |
|
706 | 14 | } |
|
707 | |||
708 | /** |
||
709 | * Primes all references for a single document only. This avoids iterating |
||
710 | * over the entire cursor when getSingleResult() is called. |
||
711 | * |
||
712 | * @param object $document |
||
713 | */ |
||
714 | 89 | protected function primeReferencesForSingleResult($document) |
|
715 | { |
||
716 | 89 | if ($this->referencesPrimed || ! $this->hydrate || empty($this->primers) || null === $document) { |
|
717 | 85 | return; |
|
718 | } |
||
719 | |||
720 | 4 | View Code Duplication | foreach ($this->primers as $fieldName => $primer) { |
721 | 4 | $primer = is_callable($primer) ? $primer : null; |
|
722 | 4 | $this->referencePrimer->primeReferences($this->class, array($document), $fieldName, $this->unitOfWorkHints, $primer); |
|
723 | } |
||
724 | 4 | } |
|
725 | } |
||
726 |
If you suppress an error, we recommend checking for the error condition explicitly: