/** * Adds identifiers from a PersistentCollection to $groupedIds. * * If the relation contains simple references, the mapping is assumed to * have a target document class defined. Without that, there is no way to * infer the class of the referenced documents. * * @param PersistentCollection $persistentCollection * @param array $groupedIds */ private function addManyReferences(PersistentCollection $persistentCollection, array &$groupedIds) { $mapping = $persistentCollection->getMapping(); if (!empty($mapping['simple'])) { $className = $mapping['targetDocument']; $class = $this->dm->getClassMetadata($className); } foreach ($persistentCollection->getMongoData() as $reference) { if (!empty($mapping['simple'])) { $id = $reference; } else { $id = $reference['$id']; $className = $this->uow->getClassNameForAssociation($mapping, $reference); $class = $this->dm->getClassMetadata($className); } $document = $this->uow->tryGetById($id, $class); if (!$document || $document instanceof Proxy && !$document->__isInitialized()) { $id = $class->getPHPIdentifierValue($id); $groupedIds[$className][serialize($id)] = $id; } } }
/** * INTERNAL: * Schedules a collection for update when this UnitOfWork commits. * * @param PersistentCollection $coll */ public function scheduleCollectionUpdate(PersistentCollection $coll) { $mapping = $coll->getMapping(); if (CollectionHelper::usesSet($mapping['strategy'])) { /* There is no need to $unset collection if it will be $set later * This is NOP if collection is not scheduled for deletion */ $this->unscheduleCollectionDeletion($coll); } $oid = spl_object_hash($coll); if (!isset($this->collectionUpdates[$oid])) { $this->collectionUpdates[$oid] = $coll; $this->scheduleCollectionOwner($coll); } }
/** * 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); }
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 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; }
/** * Returns the collection representation to be stored and unschedules it afterwards. * * @param PersistentCollection $coll * @param bool $includeNestedCollections * @return array */ public function prepareAssociatedCollectionValue(PersistentCollection $coll, $includeNestedCollections = false) { $mapping = $coll->getMapping(); $pb = $this; $callback = isset($mapping['embedded']) ? function ($v) use($pb, $mapping, $includeNestedCollections) { return $pb->prepareEmbeddedDocumentValue($mapping, $v, $includeNestedCollections); } : function ($v) use($pb, $mapping) { return $pb->prepareReferencedDocumentValue($mapping, $v); }; $setData = $coll->map($callback)->toArray(); if (CollectionHelper::isList($mapping['strategy'])) { $setData = array_values($setData); } $this->uow->unscheduleCollectionDeletion($coll); $this->uow->unscheduleCollectionUpdate($coll); return $setData; }
private function loadReferenceManyWithRepositoryMethod(PersistentCollection $collection) { $mapping = $collection->getMapping(); $cursor = $this->dm->getRepository($mapping['targetDocument'])->$mapping['repositoryMethod'](); 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); } }
/** * Initializes (loads) an uninitialized persistent collection of a document. * * @param PeristentCollection $collection The collection to initialize. */ public function loadCollection(PersistentCollection $collection) { $mapping = $collection->getMapping(); $this->getDocumentPersister(get_class($collection->getOwner()))->loadCollection($collection); }
/** * @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; }
/** * {@inheritdoc} */ public function getMapping() { return $this->collection->getMapping(); }
/** * @param PersistentCollection $collection * @param array $groupedIds * * @throws \Doctrine\ODM\MongoDB\MongoDBException */ private function loadActualDataForSortedReferenceManyCollectionByIds(PersistentCollection $collection, array $groupedIds) { $mapping = $collection->getMapping(); $hints = $collection->getHints(); foreach ($groupedIds as $className => $ids) { $class = $this->dm->getClassMetadata($className); $mongoCollection = $this->dm->getDocumentCollection($className); $criteria = $this->cm->merge(array('_id' => array('$in' => array_values($ids))), $this->dm->getFilterCollection()->getFilterCriteria($class), isset($mapping['criteria']) ? $mapping['criteria'] : array()); $criteria = $this->uow->getDocumentPersister($className)->prepareQueryOrNewObj($criteria); $cursor = $mongoCollection->find($criteria); 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]); } $documents = $cursor->toArray(false); foreach ($documents as $documentData) { $docId = $documentData['_id']; $document = $this->uow->getById($docId, $class); $data = $this->hydratorFactory->hydrate($document, $documentData); $this->uow->setOriginalDocumentData($document, $data); $document->__isInitialized__ = true; $collection->add($document); } } }
private function loadReferenceManyCollection(PersistentCollection $collection) { $mapping = $collection->getMapping(); $cmd = $this->cmd; $groupedIds = array(); foreach ($collection->getMongoData() as $reference) { $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $reference); $mongoId = $reference[$cmd . 'id']; $id = (string) $mongoId; $reference = $this->dm->getReference($className, $id); $collection->add($reference); if ($reference instanceof Proxy && !$reference->__isInitialized__) { if (!isset($groupedIds[$className])) { $groupedIds[$className] = array(); } $groupedIds[$className][] = $mongoId; } } foreach ($groupedIds as $className => $ids) { $class = $this->dm->getClassMetadata($className); $mongoCollection = $this->dm->getDocumentCollection($className); $data = $mongoCollection->find(array('_id' => array($cmd . 'in' => $ids))); foreach ($data as $documentData) { $document = $this->uow->getById((string) $documentData['_id'], $class->rootDocumentName); $data = $this->hydratorFactory->hydrate($document, $documentData); $this->uow->setOriginalDocumentData($document, $data); } } }
public function loadCollection(PersistentCollection $collection) { $mapping = $collection->getMapping(); $cmd = $this->dm->getConfiguration()->getMongoCmd(); $groupedIds = array(); foreach ($collection->getReferences() as $reference) { $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $reference); $id = $reference[$cmd . 'id']; $reference = $this->dm->getReference($className, (string) $id); $collection->add($reference); if ($reference instanceof Proxy && ! $reference->__isInitialized__) { if ( ! isset($groupedIds[$className])) { $groupedIds[$className] = array(); } $groupedIds[$className][] = $id; } } foreach ($groupedIds as $className => $ids) { $mongoCollection = $this->dm->getDocumentCollection($className); $data = $mongoCollection->find(array('_id' => array($cmd . 'in' => $ids))); $hints = array(Builder::HINT_REFRESH => true); foreach ($data as $id => $documentData) { $document = $this->uow->getOrCreateDocument($className, $documentData, $hints); } } }
/** * INTERNAL: * Schedules a collection for update when this UnitOfWork commits. * * @param PersistentCollection $coll */ public function scheduleCollectionUpdate(PersistentCollection $coll) { $mapping = $coll->getMapping(); if (isset($mapping['strategy']) && in_array($mapping['strategy'], array('set', 'setArray', 'atomicSet', 'atomicSetArray'))) { /* There is no need to $unset collection if it will be $set later * This is NOP if collection is not scheduled for deletion */ $this->unscheduleCollectionDeletion($coll); } $this->collectionUpdates[] = $coll; $this->scheduleCollectionOwner($coll); }