/** * Gets the parent information for a given PersistentCollection. It will * retrieve the top-level persistent Document that the PersistentCollection * lives in. We can use this to issue queries when updating a * PersistentCollection that is multiple levels deep inside an embedded * document. * * <code> * list($path, $parent) = $this->getPathAndParent($coll) * </code> * * @param PersistentCollection $coll * @return array $pathAndParent */ private function getPathAndParent(PersistentCollection $coll) { $mapping = $coll->getMapping(); $fields = array(); $parent = $coll->getOwner(); while (null !== ($association = $this->uow->getParentAssociation($parent))) { list($m, $owner, $field) = $association; if (isset($m['reference'])) { break; } $parent = $owner; $fields[] = $field; } $propertyPath = implode('.', array_reverse($fields)); $path = $mapping['name']; if ($propertyPath) { $path = $propertyPath . '.' . $path; } return array($path, $parent); }
/** * @param PersistentCollection $collection * * @return CursorInterface */ public function createReferenceManyWithRepositoryMethodCursor(PersistentCollection $collection) { $hints = $collection->getHints(); $mapping = $collection->getMapping(); $repositoryMethod = $mapping['repositoryMethod']; $cursor = $this->dm->getRepository($mapping['targetDocument'])->{$repositoryMethod}($collection->getOwner()); if (!$cursor instanceof CursorInterface) { throw new \BadMethodCallException("Expected repository method {$repositoryMethod} to return a CursorInterface"); } if (isset($mapping['sort'])) { $cursor->sort($mapping['sort']); } if (isset($mapping['limit'])) { $cursor->limit($mapping['limit']); } if (isset($mapping['skip'])) { $cursor->skip($mapping['skip']); } if (!empty($hints[Query::HINT_SLAVE_OKAY])) { $cursor->slaveOkay(true); } if (!empty($hints[Query::HINT_READ_PREFERENCE])) { $cursor->setReadPreference($hints[Query::HINT_READ_PREFERENCE], $hints[Query::HINT_READ_PREFERENCE_TAGS]); } return $cursor; }
/** * Marks the PersistentCollection's top-level owner as having a relation to * a collection scheduled for update or deletion. * * If the owner is not scheduled for any lifecycle action, it will be * scheduled for update to ensure that versioning takes place if necessary. * * If the collection is nested within atomic collection, it is immediately * unscheduled and atomic one is scheduled for update instead. This makes * calculating update data way easier. * * @param PersistentCollection $coll */ private function scheduleCollectionOwner(PersistentCollection $coll) { $document = $this->getOwningDocument($coll->getOwner()); $this->hasScheduledCollections[spl_object_hash($document)][spl_object_hash($coll)] = $coll; if ($document !== $coll->getOwner()) { $parent = $coll->getOwner(); while (null !== ($parentAssoc = $this->getParentAssociation($parent))) { list($mapping, $parent, ) = $parentAssoc; } if (isset($mapping['strategy']) && CollectionHelper::isAtomic($mapping['strategy'])) { $class = $this->dm->getClassMetadata(get_class($document)); $atomicCollection = $class->getFieldValue($document, $mapping['fieldName']); $this->scheduleCollectionUpdate($atomicCollection); $this->unscheduleCollectionDeletion($coll); $this->unscheduleCollectionUpdate($coll); } } if (!$this->isDocumentScheduled($document)) { $this->scheduleForUpdate($document); } }
private function loadReferenceManyCollectionInverseSide(PersistentCollection $collection) { $mapping = $collection->getMapping(); $owner = $collection->getOwner(); $ownerClass = $this->dm->getClassMetadata(get_class($owner)); $criteria = array_merge( array($mapping['mappedBy'].'.'.$this->cmd.'id' => $ownerClass->getIdentifierObject($owner)), $mapping['criteria'] ); $qb = $this->dm->createQueryBuilder($mapping['targetDocument']) ->setQueryArray($criteria); if ($mapping['sort']) { $qb->sort($mapping['sort']); } if ($mapping['limit']) { $qb->limit($mapping['limit']); } if ($mapping['skip']) { $qb->skip($mapping['skip']); } $query = $qb->getQuery(); $cursor = $query->execute(); foreach ($cursor as $document) { $collection->add($document); } }
private function loadReferenceManyWithRepositoryMethod(PersistentCollection $collection) { $mapping = $collection->getMapping(); $cursor = $this->dm->getRepository($mapping['targetDocument'])->{$mapping}['repositoryMethod']($collection->getOwner()); if (isset($mapping['sort']) && $mapping['sort']) { $cursor->sort($mapping['sort']); } if (isset($mapping['limit']) && $mapping['limit']) { $cursor->limit($mapping['limit']); } if (isset($mapping['skip']) && $mapping['skip']) { $cursor->skip($mapping['skip']); } if (isset($hints[Query::HINT_SLAVE_OKAY])) { $cursor->slaveOkay(true); } $documents = $cursor->toArray(); foreach ($documents as $document) { $collection->add($document); } }
/** * @param PersistentCollection $collection * * @return Cursor */ public function createReferenceManyWithRepositoryMethodCursor(PersistentCollection $collection) { $hints = $collection->getHints(); $mapping = $collection->getMapping(); $cursor = $this->dm->getRepository($mapping['targetDocument'])->{$mapping}['repositoryMethod']($collection->getOwner()); if (isset($mapping['sort'])) { $cursor->sort($mapping['sort']); } if (isset($mapping['limit'])) { $cursor->limit($mapping['limit']); } if (isset($mapping['skip'])) { $cursor->skip($mapping['skip']); } if (!empty($hints[Query::HINT_SLAVE_OKAY])) { $cursor->slaveOkay(true); } if (!empty($hints[Query::HINT_READ_PREFERENCE])) { $cursor->setReadPreference($hints[Query::HINT_READ_PREFERENCE], $hints[Query::HINT_READ_PREFERENCE_TAGS]); } return $cursor; }
/** * Marks the PersistentCollection's top-level owner as having a relation to * a collection scheduled for update or deletion. * * If the owner is not scheduled for any lifecycle action, it will be * scheduled for update to ensure that versioning takes place if necessary. * * @param PersistentCollection $coll */ private function scheduleCollectionOwner(PersistentCollection $coll) { $document = $coll->getOwner(); $class = $this->dm->getClassMetadata(get_class($document)); while ($class->isEmbeddedDocument) { list(, $document, ) = $this->getParentAssociation($document); $class = $this->dm->getClassMetadata(get_class($document)); } $this->hasScheduledCollections[spl_object_hash($document)] = true; if (!$this->isDocumentScheduled($document)) { $this->scheduleForUpdate($document); } }
/** * {@inheritdoc} */ public function getOwner() { return $this->collection->getOwner(); }
private function loadEmbedManyCollection(PersistentCollection $collection) { $embeddedDocuments = $collection->getMongoData(); $mapping = $collection->getMapping(); $owner = $collection->getOwner(); if ($embeddedDocuments) { foreach ($embeddedDocuments as $key => $embeddedDocument) { $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $embeddedDocument); $embeddedMetadata = $this->dm->getClassMetadata($className); $embeddedDocumentObject = $embeddedMetadata->newInstance(); $data = $this->hydratorFactory->hydrate($embeddedDocumentObject, $embeddedDocument); $this->uow->registerManaged($embeddedDocumentObject, null, $data); $this->uow->setParentAssociation($embeddedDocumentObject, $mapping, $owner, $mapping['name'] . '.' . $key); $collection->add($embeddedDocumentObject); } } }
private function loadReferenceManyWithRepositoryMethod(PersistentCollection $collection) { $mapping = $collection->getMapping(); $cursor = $this->dm->getRepository($mapping['targetDocument'])->{$mapping}['repositoryMethod']($collection->getOwner()); if ($mapping['sort']) { $cursor->sort($mapping['sort']); } if ($mapping['limit']) { $cursor->limit($mapping['limit']); } if ($mapping['skip']) { $cursor->skip($mapping['skip']); } foreach ($cursor as $document) { $collection->add($document); } }