예제 #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) {
         if (!isset($data[$mapping['fieldName']])) {
             continue;
         }
         if (isset($mapping['embedded'])) {
             $embeddedMetadata = $this->_dm->getClassMetadata($mapping['targetDocument']);
             $embeddedDocument = $embeddedMetadata->newInstance();
             if ($mapping['type'] === 'many') {
                 $documents = new ArrayCollection();
                 foreach ($data[$mapping['fieldName']] 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, $data[$mapping['fieldName']]);
                 $metadata->setFieldValue($document, $mapping['fieldName'], $value);
             }
         } elseif (isset($mapping['reference'])) {
             $targetMetadata = $this->_dm->getClassMetadata($mapping['targetDocument']);
             $targetDocument = $targetMetadata->newInstance();
             $value = isset($data[$mapping['fieldName']]) ? $data[$mapping['fieldName']] : null;
             if ($mapping['type'] === 'one' && isset($value['$id'])) {
                 $id = (string) $value['$id'];
                 $proxy = $this->_dm->getReference($mapping['targetDocument'], $id);
                 $metadata->setFieldValue($document, $mapping['fieldName'], $proxy);
             } elseif ($mapping['type'] === 'many' && (is_array($value) || $value instanceof Collection)) {
                 $documents = new PersistentCollection($this->_dm, $targetMetadata, new ArrayCollection());
                 $documents->setInitialized(false);
                 foreach ($value as $v) {
                     $id = (string) $v['$id'];
                     $proxy = $this->_dm->getReference($mapping['targetDocument'], $id);
                     $documents->add($proxy);
                 }
                 $metadata->setFieldValue($document, $mapping['fieldName'], $documents);
             }
         } else {
             $value = $data[$mapping['fieldName']];
             $value = Type::getType($mapping['type'])->convertToPHPValue($value);
             $metadata->setFieldValue($document, $mapping['fieldName'], $value);
         }
         if (isset($value)) {
             $values[$mapping['fieldName']] = $value;
         }
     }
     if (isset($data['_id'])) {
         $metadata->setIdentifierValue($document, (string) $data['_id']);
     }
     return $values;
 }
    /**
     * Updates the already persisted document if it has any new changesets.
     *
     * @param object $document
     * @param array $options Array of options to be used with update()
     */
    public function update($document, array $options = array())
    {
        $id = $this->uow->getDocumentIdentifier($document);
        $update = $this->dp->prepareUpdateData($document);

        if ( ! empty($update)) {

            $id = $this->class->getDatabaseIdentifierValue($id);
            $query = array('_id' => $id);

            // Include versioning updates
            if ($this->class->isVersioned) {
                $versionMapping = $this->class->fieldMappings[$this->class->versionField];
                $currentVersion = $this->class->getFieldValue($document, $this->class->versionField);
                if ($versionMapping['type'] === 'int') {
                    $nextVersion = $currentVersion + 1;
                    $update[$this->cmd . 'inc'][$versionMapping['name']] = 1;
                    $query[$versionMapping['name']] = $currentVersion;
                    $this->class->setFieldValue($document, $this->class->versionField, $nextVersion);
                } elseif ($versionMapping['type'] === 'date') {
                    $nextVersion = new \DateTime();
                    $update[$this->cmd . 'set'][$versionMapping['name']] = new \MongoDate($nextVersion->getTimestamp());
                    $query[$versionMapping['name']] = new \MongoDate($currentVersion->getTimestamp());
                    $this->class->setFieldValue($document, $this->class->versionField, $nextVersion);
                }
                $options['safe'] = true;
            }

            if ($this->class->isLockable) {
                $isLocked = $this->class->getFieldValue($document, $this->class->lockField);
                $lockMapping = $this->class->fieldMappings[$this->class->lockField];
                if ($isLocked) {
                    $update[$this->cmd . 'unset'] = array($lockMapping['name'] => true);
                } else {
                    $query[$lockMapping['name']] = array($this->cmd . 'exists' => false);
                }
            }

            if ($this->dm->getEventManager()->hasListeners(Events::onUpdatePrepared)) {
                $this->dm->getEventManager()->dispatchEvent(
                    Events::onUpdatePrepared, new OnUpdatePreparedArgs($this->dm, $document, $update)
                );
            }

            $result = $this->collection->update($query, $update, $options);

            if (($this->class->isVersioned || $this->class->isLockable) && ! $result['n']) {
                throw LockException::lockFailed($document);
            }
        }
    }
예제 #3
0
 /**
  * @param $object
  * @param $fieldName
  * @return ArrayCollection|mixed
  * @throws \NForms\Exceptions\MetadataException
  */
 protected function getCollection($object, $fieldName)
 {
     if ($this->isSingleValuedAssociation($fieldName)) {
         throw new MetadataException("Can't get collection from association toOne.");
     }
     $collection = $this->classMetadata->getFieldValue($object, $fieldName);
     if ($collection === NULL) {
         $collection = new ArrayCollection();
         $this->classMetadata->setFieldValue($object, $fieldName, $collection);
     }
     if (!$collection instanceof Collection) {
         throw new MetadataException('Expected Doctrine\\Common\\Collections\\Collection, given ' . (is_object($collection) ? get_class($collection) : gettype($collection)));
     }
     return $collection;
 }