Beispiel #1
0
 /**
  * Hydrate array of MongoDB document data into the given document object
  * based on the mapping information provided in the ClassMetadata instance.
  *
  * @param ClassMetadata $metadata  The ClassMetadata instance for mapping information.
  * @param string $document  The document object to hydrate the data into.
  * @param array $data The array of document data.
  * @return array $values The array of hydrated values.
  */
 public function hydrate(ClassMetadata $metadata, $document, $data)
 {
     $values = array();
     foreach ($metadata->fieldMappings as $mapping) {
         $rawValue = $this->_getFieldValue($mapping, $document, $data);
         if (!isset($rawValue)) {
             continue;
         }
         if (isset($mapping['embedded'])) {
             $embeddedMetadata = $this->_dm->getClassMetadata($mapping['targetDocument']);
             $embeddedDocument = $embeddedMetadata->newInstance();
             if ($mapping['type'] === 'many') {
                 $documents = new ArrayCollection();
                 foreach ($rawValue as $docArray) {
                     $doc = clone $embeddedDocument;
                     $this->hydrate($embeddedMetadata, $doc, $docArray);
                     $documents->add($doc);
                 }
                 $metadata->setFieldValue($document, $mapping['fieldName'], $documents);
                 $value = $documents;
             } else {
                 $value = clone $embeddedDocument;
                 $this->hydrate($embeddedMetadata, $value, $rawValue);
                 $metadata->setFieldValue($document, $mapping['fieldName'], $value);
             }
         } elseif (isset($mapping['reference'])) {
             $targetMetadata = $this->_dm->getClassMetadata($mapping['targetDocument']);
             $targetDocument = $targetMetadata->newInstance();
             if ($mapping['type'] === 'one' && isset($rawValue[$this->_cmd . 'id'])) {
                 $id = $targetMetadata->getPHPIdentifierValue($rawValue[$this->_cmd . 'id']);
                 $proxy = $this->_dm->getReference($mapping['targetDocument'], $id);
                 $metadata->setFieldValue($document, $mapping['fieldName'], $proxy);
             } elseif ($mapping['type'] === 'many' && (is_array($rawValue) || $rawValue instanceof Collection)) {
                 $documents = new PersistentCollection($this->_dm, $targetMetadata, new ArrayCollection());
                 $documents->setInitialized(false);
                 foreach ($rawValue as $v) {
                     $id = $targetMetadata->getPHPIdentifierValue($v[$this->_cmd . 'id']);
                     $proxy = $this->_dm->getReference($mapping['targetDocument'], $id);
                     $documents->add($proxy);
                 }
                 $metadata->setFieldValue($document, $mapping['fieldName'], $documents);
             }
         } else {
             $value = Type::getType($mapping['type'])->convertToPHPValue($rawValue);
             $metadata->setFieldValue($document, $mapping['fieldName'], $value);
         }
         if (isset($value)) {
             $values[$mapping['fieldName']] = $value;
         }
     }
     if (isset($data['_id'])) {
         $metadata->setIdentifierValue($document, $data['_id']);
     }
     return $values;
 }
Beispiel #2
0
 /**
  * @param ClassMetadata $class
  * @param object $document
  * @throws \InvalidArgumentException If there is something wrong with document's identifier.
  */
 private function persistNew(ClassMetadata $class, $document)
 {
     $oid = spl_object_hash($document);
     if (!empty($class->lifecycleCallbacks[Events::prePersist])) {
         $class->invokeLifecycleCallbacks(Events::prePersist, $document);
     }
     if ($this->evm->hasListeners(Events::prePersist)) {
         $this->evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($document, $this->dm));
     }
     $upsert = false;
     if ($class->identifier) {
         $idValue = $class->getIdentifierValue($document);
         $upsert = !$class->isEmbeddedDocument && $idValue !== null;
         if ($class->generatorType === ClassMetadata::GENERATOR_TYPE_NONE && $idValue === null) {
             throw new \InvalidArgumentException(sprintf("%s uses NONE identifier generation strategy but no identifier was provided when persisting.", get_class($document)));
         }
         // \MongoId::isValid($idValue) was introduced in 1.5.0 so it's no good
         if ($class->generatorType === ClassMetadata::GENERATOR_TYPE_AUTO && $idValue !== null && !preg_match('/^[0-9a-f]{24}$/', $idValue)) {
             throw new \InvalidArgumentException(sprintf("%s uses AUTO identifier generation strategy but provided identifier is not valid MongoId.", get_class($document)));
         }
         if ($class->generatorType !== ClassMetadata::GENERATOR_TYPE_NONE && $idValue === null) {
             $idValue = $class->idGenerator->generate($this->dm, $document);
             $idValue = $class->getPHPIdentifierValue($class->getDatabaseIdentifierValue($idValue));
             $class->setIdentifierValue($document, $idValue);
         }
         $this->documentIdentifiers[$oid] = $idValue;
     } else {
         // this is for embedded documents without identifiers
         $this->documentIdentifiers[$oid] = $oid;
     }
     $this->documentStates[$oid] = self::STATE_MANAGED;
     if ($upsert) {
         $this->scheduleForUpsert($class, $document);
     } else {
         $this->scheduleForInsert($class, $document);
     }
 }
Beispiel #3
0
 /**
  * Executes all document insertions for documents of the specified type.
  *
  * @param Doctrine\ODM\MongoDB\Mapping\ClassMetadata $class
  * @param array $options Array of options to be used with batchInsert()
  */
 private function executeInserts($class, array $options = array())
 {
     $className = $class->name;
     $persister = $this->getDocumentPersister($className);
     $collection = $this->dm->getDocumentCollection($className);
     $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postPersist]);
     $hasListeners = $this->evm->hasListeners(Events::postPersist);
     if ($hasLifecycleCallbacks || $hasListeners) {
         $documents = array();
     }
     $inserts = array();
     foreach ($this->documentInsertions as $oid => $document) {
         if (get_class($document) === $className) {
             $persister->addInsert($document);
             unset($this->documentInsertions[$oid]);
             if ($hasLifecycleCallbacks || $hasListeners) {
                 $documents[] = $document;
             }
         }
     }
     $postInsertIds = $persister->executeInserts($options);
     if ($postInsertIds) {
         foreach ($postInsertIds as $pair) {
             list($id, $document) = $pair;
             $oid = spl_object_hash($document);
             $class->setIdentifierValue($document, $id);
             $this->documentIdentifiers[$oid] = $id;
             $this->documentStates[$oid] = self::STATE_MANAGED;
             $this->originalDocumentData[$oid][$class->identifier] = $id;
             $this->addToIdentityMap($document);
             if ($hasLifecycleCallbacks || $hasListeners) {
                 if ($hasLifecycleCallbacks) {
                     $class->invokeLifecycleCallbacks(Events::postPersist, $document);
                 }
                 if ($hasListeners) {
                     $this->evm->dispatchEvent(Events::postPersist, new LifecycleEventArgs($document, $this->dm));
                 }
             }
             $this->cascadePostPersist($class, $document);
         }
     }
 }