示例#1
0
 /**
  * Releases any lock that exists on this document.
  *
  * @param object $document
  */
 public function unlock($document)
 {
     $id = $this->uow->getDocumentIdentifier($document);
     $criteria = array('_id' => $this->class->getDatabaseIdentifierValue($id));
     $lockMapping = $this->class->fieldMappings[$this->class->lockField];
     $this->collection->update($criteria, array('$unset' => array($lockMapping['name'] => true)));
     $this->class->reflFields[$this->class->lockField]->setValue($document, null);
 }
示例#2
0
 /**
  * Prime references within a mapped field of one or more documents.
  *
  * If a $primer callable is provided, it should have the same signature as
  * the default primer defined in the constructor. If $primer is not
  * callable, the default primer will be used.
  *
  * @param ClassMetadata      $class     Class metadata for the document
  * @param array|\Traversable $documents Documents containing references to prime
  * @param string             $fieldName Field name containing references to prime
  * @param array              $hints     UnitOfWork hints for priming queries
  * @param callable           $primer    Optional primer callable
  * @throws \InvalidArgumentException If the mapped field is not the owning
  *                                   side of a reference relationship.
  * @throws \InvalidArgumentException If $primer is not callable
  * @throws \LogicException If the mapped field is a simple reference and is
  *                         missing a target document class.
  */
 public function primeReferences(ClassMetadata $class, $documents, $fieldName, array $hints = array(), $primer = null)
 {
     $data = $this->parseDotSyntaxForPrimer($fieldName, $class, $documents);
     $mapping = $data['mapping'];
     $fieldName = $data['fieldName'];
     $class = $data['class'];
     $documents = $data['documents'];
     /* Inverse-side references would need to be populated before we can
      * collect references to be primed. This is not supported.
      */
     if (!isset($mapping['reference']) || !$mapping['isOwningSide']) {
         throw new \InvalidArgumentException(sprintf('Field "%s" is not the owning side of a reference relationship in class "%s"', $fieldName, $class->name));
     }
     /* Simple reference require a target document class so we can construct
      * the priming query.
      */
     if (!empty($mapping['simple']) && empty($mapping['targetDocument'])) {
         throw new \LogicException(sprintf('Field "%s" is a simple reference without a target document class in class "%s"', $fieldName, $class->name));
     }
     if ($primer !== null && !is_callable($primer)) {
         throw new \InvalidArgumentException('$primer is not callable');
     }
     $primer = $primer ?: $this->defaultPrimer;
     $groupedIds = array();
     /* @var $document PersistentCollection */
     foreach ($documents as $document) {
         $fieldValue = $class->getFieldValue($document, $fieldName);
         /* The field will need to be either a Proxy (reference-one) or
          * PersistentCollection (reference-many) in order to prime anything.
          */
         if (!is_object($fieldValue)) {
             continue;
         }
         if ($mapping['type'] === 'one' && $fieldValue instanceof Proxy && !$fieldValue->__isInitialized()) {
             $refClass = $this->dm->getClassMetadata(get_class($fieldValue));
             $id = $this->uow->getDocumentIdentifier($fieldValue);
             $groupedIds[$refClass->name][serialize($id)] = $id;
         } elseif ($mapping['type'] == 'many' && $fieldValue instanceof PersistentCollection) {
             $this->addManyReferences($fieldValue, $groupedIds);
         }
     }
     foreach ($groupedIds as $className => $ids) {
         $refClass = $this->dm->getClassMetadata($className);
         call_user_func($primer, $this->dm, $refClass, array_values($ids), $hints);
     }
 }
示例#3
0
 /**
  * Returns a DBRef array for the supplied document.
  *
  * @param mixed $document A document object
  * @param array $referenceMapping Mapping for the field that references the document
  *
  * @throws \InvalidArgumentException
  * @return array A DBRef array
  */
 public function createDBRef($document, array $referenceMapping = null)
 {
     if (!is_object($document)) {
         throw new \InvalidArgumentException('Cannot create a DBRef, the document is not an object');
     }
     $class = $this->getClassMetadata(get_class($document));
     $id = $this->unitOfWork->getDocumentIdentifier($document);
     if (!$id) {
         throw new \RuntimeException(sprintf('Cannot create a DBRef for class %s without an identifier. Have you forgotten to persist/merge the document first?', $class->name));
     }
     if (!empty($referenceMapping['simple'])) {
         if ($class->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION) {
             throw MappingException::simpleReferenceMustNotTargetDiscriminatedDocument($referenceMapping['targetDocument']);
         }
         return $class->getDatabaseIdentifierValue($id);
     }
     $dbRef = array('$ref' => $class->getCollection(), '$id' => $class->getDatabaseIdentifierValue($id), '$db' => $this->getDocumentDatabase($class->name)->getName());
     /* If the class has a discriminator (field and value), use it. A child
      * class that is not defined in the discriminator map may only have a
      * discriminator field and no value, so default to the full class name.
      */
     if (isset($class->discriminatorField)) {
         $dbRef[$class->discriminatorField] = isset($class->discriminatorValue) ? $class->discriminatorValue : $class->name;
     }
     /* Add a discriminator value if the referenced document is not mapped
      * explicitly to a targetDocument class.
      */
     if ($referenceMapping !== null && !isset($referenceMapping['targetDocument'])) {
         $discriminatorField = $referenceMapping['discriminatorField'];
         $discriminatorValue = isset($referenceMapping['discriminatorMap']) ? array_search($class->name, $referenceMapping['discriminatorMap']) : $class->name;
         /* If the discriminator value was not found in the map, use the full
          * class name. In the future, it may be preferable to throw an
          * exception here (perhaps based on some strictness option).
          *
          * @see PersistenceBuilder::prepareEmbeddedDocumentValue()
          */
         if ($discriminatorValue === false) {
             $discriminatorValue = $class->name;
         }
         $dbRef[$discriminatorField] = $discriminatorValue;
     }
     return $dbRef;
 }