Beispiel #1
0
 /** {@inheritdoc} */
 public function getFieldMapping($fieldName)
 {
     if (!$this->hasField($fieldName)) {
         throw new MetadataException("Field '{$fieldName}' not found in class '{$this->getClass()}'.");
     }
     return $this->classMetadata->getFieldMapping($fieldName);
 }
Beispiel #2
0
 /**
  * @param string $fieldName
  * @return $this
  * @throws MappingException
  */
 private function fromReference($fieldName)
 {
     if (!$this->class->hasReference($fieldName)) {
         MappingException::referenceMappingNotFound($this->class->name, $fieldName);
     }
     $referenceMapping = $this->class->getFieldMapping($fieldName);
     $targetMapping = $this->dm->getClassMetadata($referenceMapping['targetDocument']);
     parent::from($targetMapping->getCollection());
     if ($referenceMapping['isOwningSide']) {
         if ($referenceMapping['storeAs'] !== ClassMetadataInfo::REFERENCE_STORE_AS_ID) {
             throw MappingException::cannotLookupNonIdReference($this->class->name, $fieldName);
         }
         $this->foreignField('_id')->localField($referenceMapping['name']);
     } else {
         if (isset($referenceMapping['repositoryMethod'])) {
             throw MappingException::repositoryMethodLookupNotAllowed($this->class->name, $fieldName);
         }
         $mappedByMapping = $targetMapping->getFieldMapping($referenceMapping['mappedBy']);
         if ($mappedByMapping['storeAs'] !== ClassMetadataInfo::REFERENCE_STORE_AS_ID) {
             throw MappingException::cannotLookupNonIdReference($this->class->name, $fieldName);
         }
         $this->localField('_id')->foreignField($mappedByMapping['name']);
     }
     return $this;
 }
Beispiel #3
0
 /** {@inheritdoc} */
 public function getAssociationMapping($name)
 {
     if (!$this->classMetadata->hasAssociation($name)) {
         throw new MetadataException("Association '{$name}' not found in class '{$this->getClass()}'.");
     }
     return $this->classMetadata->getFieldMapping($name);
 }
Beispiel #4
0
 /**
  * Checks that the current field includes a reference to the supplied document.
  */
 public function includesReferenceTo($document)
 {
     if ($this->currentField) {
         $this->query[$this->currentField][$this->cmd . 'elemMatch'] = $this->class ? $this->dm->createDBRef($document, $this->class->getFieldMapping($this->currentField)) : $this->dm->createDBRef($document);
     } else {
         $this->query[$this->cmd . 'elemMatch'] = $this->dm->createDBRef($document);
     }
     return $this;
 }
Beispiel #5
0
 public function getFieldsMetadata($class)
 {
     $result = array();
     foreach ($this->odmMetadata->getReflectionProperties() as $property) {
         $name = $property->getName();
         $mapping = $this->odmMetadata->getFieldMapping($name);
         $values = array('title' => $name, 'source' => true);
         if (isset($mapping['fieldName'])) {
             $values['field'] = $mapping['fieldName'];
         }
         if (isset($mapping['id']) && $mapping['id'] == 'id') {
             $values['primary'] = true;
         }
         switch ($mapping['type']) {
             case 'id':
             case 'int':
             case 'string':
             case 'float':
             case 'many':
                 $values['type'] = 'text';
                 break;
             case 'boolean':
                 $values['type'] = 'boolean';
                 break;
             case 'date':
                 $values['type'] = 'date';
                 break;
         }
         $result[$name] = $values;
     }
     return $result;
 }
Beispiel #6
0
 /**
  * Gets reference mapping for current field from current class or its descendants.
  *
  * @return array
  * @throws MappingException
  */
 private function getReferenceMapping()
 {
     $mapping = null;
     try {
         $mapping = $this->class->getFieldMapping($this->currentField);
     } catch (MappingException $e) {
         if (empty($this->class->discriminatorMap)) {
             throw $e;
         }
         $foundIn = null;
         foreach ($this->class->discriminatorMap as $child) {
             $childClass = $this->dm->getClassMetadata($child);
             if ($childClass->hasAssociation($this->currentField)) {
                 if ($mapping !== null && $mapping !== $childClass->getFieldMapping($this->currentField)) {
                     throw MappingException::referenceFieldConflict($this->currentField, $foundIn->name, $childClass->name);
                 }
                 $mapping = $childClass->getFieldMapping($this->currentField);
                 $foundIn = $childClass;
             }
         }
         if ($mapping === null) {
             throw MappingException::mappingNotFoundInClassNorDescendants($this->class->name, $this->currentField);
         }
     }
     return $mapping;
 }
 /**
  * Prepares a query value and converts the php value to the database value if it is an identifier.
  * It also handles converting $fieldName to the database name if they are different.
  *
  * @param string $fieldName
  * @param string $value
  * @return mixed $value
  */
 private function prepareQueryValue(&$fieldName, $value)
 {
     // Process "association.fieldName"
     if (strpos($fieldName, '.') !== false) {
         $e = explode('.', $fieldName);
         $mapping = $this->class->getFieldMapping($e[0]);
         if ($this->class->hasField($e[0])) {
             $name = $this->class->fieldMappings[$e[0]]['name'];
             if ($name !== $e[0]) {
                 $e[0] = $name;
             }
         }
         if (isset($mapping['targetDocument'])) {
             $targetClass = $this->dm->getClassMetadata($mapping['targetDocument']);
             if ($targetClass->hasField($e[1])) {
                 if ($targetClass->identifier === $e[1] || $e[1] === '$id') {
                     $fieldName = $e[0] . '.$id';
                     $value = $targetClass->getDatabaseIdentifierValue($value);
                 }
             }
         }
         // Process all non identifier fields
     } elseif ($this->class->hasField($fieldName) && !$this->class->isIdentifier($fieldName)) {
         $name = $this->class->fieldMappings[$fieldName]['name'];
         $mapping = $this->class->fieldMappings[$fieldName];
         if ($name !== $fieldName) {
             $fieldName = $name;
         }
         // Process identifier
     } elseif ($fieldName === $this->class->identifier || $fieldName === '_id') {
         $fieldName = '_id';
         $value = $this->class->getDatabaseIdentifierValue($value);
     }
     return $value;
 }
 /**
  * Prepares a query value and converts the php value to the database value if it is an identifier.
  * It also handles converting $fieldName to the database name if they are different.
  *
  * @param string $fieldName
  * @param string $value
  * @return mixed $value
  */
 private function prepareQueryValue(&$fieldName, $value)
 {
     // Process "association.fieldName"
     if (strpos($fieldName, '.') !== false) {
         $e = explode('.', $fieldName);
         $mapping = $this->class->getFieldMapping($e[0]);
         $name = $mapping['name'];
         if ($name !== $e[0]) {
             $e[0] = $name;
         }
         if (isset($mapping['targetDocument'])) {
             $targetClass = $this->dm->getClassMetadata($mapping['targetDocument']);
             if ($targetClass->hasField($e[1])) {
                 if ($targetClass->identifier === $e[1]) {
                     $e[1] = '$id';
                     if (is_array($value)) {
                         foreach ($value as $k => $v) {
                             $value[$k] = $targetClass->getDatabaseIdentifierValue($v);
                         }
                     } else {
                         $value = $targetClass->getDatabaseIdentifierValue($value);
                     }
                 } else {
                     $targetMapping = $targetClass->getFieldMapping($e[1]);
                     $targetName = $targetMapping['name'];
                     if ($targetName !== $e[1]) {
                         $e[1] = $targetName;
                     }
                 }
                 $fieldName = $e[0] . '.' . $e[1];
             }
         }
         // Process all non identifier fields
         // We only change the field names here to the mongodb field name used for persistence
     } elseif ($this->class->hasField($fieldName) && !$this->class->isIdentifier($fieldName)) {
         $name = $this->class->fieldMappings[$fieldName]['name'];
         $mapping = $this->class->fieldMappings[$fieldName];
         if ($name !== $fieldName) {
             $fieldName = $name;
         }
         // Process identifier
     } elseif ($this->class->hasField($fieldName) && $this->class->isIdentifier($fieldName) || $fieldName === '_id') {
         $fieldName = '_id';
         if (is_array($value)) {
             foreach ($value as $k => $v) {
                 if ($k[0] === '$' && is_array($v)) {
                     foreach ($v as $k2 => $v2) {
                         $value[$k][$k2] = $this->class->getDatabaseIdentifierValue($v2);
                     }
                 } else {
                     $value[$k] = $this->class->getDatabaseIdentifierValue($v);
                 }
             }
         } else {
             $value = $this->class->getDatabaseIdentifierValue($value);
         }
     }
     return $value;
 }
Beispiel #9
0
 public function getFieldsMetadata($class, $group = 'default')
 {
     $result = array();
     foreach ($this->odmMetadata->getReflectionProperties() as $property) {
         $name = $property->getName();
         $mapping = $this->odmMetadata->getFieldMapping($name);
         $values = array('title' => $name, 'source' => true);
         if (isset($mapping['fieldName'])) {
             $values['field'] = $mapping['fieldName'];
             $values['id'] = $mapping['fieldName'];
         }
         if (isset($mapping['id']) && $mapping['id'] == 'id') {
             $values['primary'] = true;
         }
         switch ($mapping['type']) {
             case 'id':
             case 'string':
             case 'bin_custom':
             case 'bin_func':
             case 'bin_md5':
             case 'bin':
             case 'bin_uuid':
             case 'file':
             case 'key':
             case 'increment':
                 $values['type'] = 'text';
                 break;
             case 'int':
             case 'float':
                 $values['type'] = 'number';
                 break;
                 /*case 'hash':
                   $values['type'] = 'array';*/
             /*case 'hash':
               $values['type'] = 'array';*/
             case 'boolean':
                 $values['type'] = 'boolean';
                 break;
             case 'date':
             case 'timestamp':
                 $values['type'] = 'date';
                 break;
             case 'collection':
                 $values['type'] = 'array';
                 break;
             case 'one':
                 $values['type'] = 'array';
                 break;
             case 'many':
                 $values['type'] = 'array';
                 break;
             default:
                 $values['type'] = 'text';
         }
         $result[$name] = $values;
     }
     return $result;
 }
Beispiel #10
0
 /**
  * Checks that the current field includes a reference to the supplied document.
  */
 public function includesReferenceTo($document)
 {
     $dbRef = $this->dm->createDBRef($document);
     if ($this->currentField) {
         $keys = array('ref' => true, 'id' => true, 'db' => true);
         if ($this->class) {
             $mapping = $this->class->getFieldMapping($this->currentField);
             if (isset($mapping['targetDocument'])) {
                 unset($keys['ref'], $keys['db']);
             }
         }
         foreach ($keys as $key => $value) {
             $this->query[$this->currentField][$this->cmd . 'elemMatch'][$this->cmd . $key] = $dbRef[$this->cmd . $key];
         }
     } else {
         $this->query[$this->cmd . 'elemMatch'] = $dbRef;
     }
     return $this;
 }
 public function testClassMetadataInstanceSerialization()
 {
     $cm = new ClassMetadata('Documents\\CmsUser');
     // Test initial state
     $this->assertTrue(count($cm->getReflectionProperties()) == 0);
     $this->assertTrue($cm->reflClass instanceof \ReflectionClass);
     $this->assertEquals('Documents\\CmsUser', $cm->name);
     $this->assertEquals('Documents\\CmsUser', $cm->rootDocumentName);
     $this->assertEquals(array(), $cm->subClasses);
     $this->assertEquals(array(), $cm->parentClasses);
     $this->assertEquals(ClassMetadata::INHERITANCE_TYPE_NONE, $cm->inheritanceType);
     // Customize state
     $cm->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_SINGLE_COLLECTION);
     $cm->setSubclasses(array("One", "Two", "Three"));
     $cm->setParentClasses(array("UserParent"));
     $cm->setCustomRepositoryClass("UserRepository");
     $cm->setDiscriminatorField('disc');
     $cm->mapOneEmbedded(array('fieldName' => 'phonenumbers', 'targetDocument' => 'Bar'));
     $cm->setFile('customFileProperty');
     $cm->setDistance('customDistanceProperty');
     $cm->setSlaveOkay(true);
     $cm->setShardKey(array('_id' => '1'));
     $cm->setCollectionCapped(true);
     $cm->setCollectionMax(1000);
     $cm->setCollectionSize(500);
     $this->assertTrue(is_array($cm->getFieldMapping('phonenumbers')));
     $this->assertEquals(1, count($cm->fieldMappings));
     $this->assertEquals(1, count($cm->associationMappings));
     $serialized = serialize($cm);
     $cm = unserialize($serialized);
     // Check state
     $this->assertTrue(count($cm->getReflectionProperties()) > 0);
     $this->assertEquals('Documents', $cm->namespace);
     $this->assertTrue($cm->reflClass instanceof \ReflectionClass);
     $this->assertEquals('Documents\\CmsUser', $cm->name);
     $this->assertEquals('UserParent', $cm->rootDocumentName);
     $this->assertEquals(array('Documents\\One', 'Documents\\Two', 'Documents\\Three'), $cm->subClasses);
     $this->assertEquals(array('UserParent'), $cm->parentClasses);
     $this->assertEquals('Documents\\UserRepository', $cm->customRepositoryClassName);
     $this->assertEquals('disc', $cm->discriminatorField);
     $this->assertTrue(is_array($cm->getFieldMapping('phonenumbers')));
     $this->assertEquals(1, count($cm->fieldMappings));
     $this->assertEquals(1, count($cm->associationMappings));
     $this->assertEquals('customFileProperty', $cm->file);
     $this->assertEquals('customDistanceProperty', $cm->distance);
     $this->assertTrue($cm->slaveOkay);
     $this->assertEquals(array('keys' => array('_id' => 1), 'options' => array()), $cm->getShardKey());
     $mapping = $cm->getFieldMapping('phonenumbers');
     $this->assertEquals('Documents\\Bar', $mapping['targetDocument']);
     $this->assertTrue($cm->getCollectionCapped());
     $this->assertEquals(1000, $cm->getCollectionMax());
     $this->assertEquals(500, $cm->getCollectionSize());
 }
    /**
     * Prepare where values converting document object field names to the document collection
     * field name.
     *
     * @param string $fieldName
     * @param string $value
     * @return string $value
     */
    private function prepareWhereValue(&$fieldName, $value)
    {
        if (strpos($fieldName, '.') !== false) {
            $e = explode('.', $fieldName);

            $mapping = $this->class->getFieldMapping($e[0]);

            if ($this->class->hasField($e[0])) {
                $name = $this->class->fieldMappings[$e[0]]['name'];
                if ($name !== $e[0]) {
                    $e[0] = $name;
                }
            }

            if (isset($mapping['targetDocument'])) {
                $targetClass = $this->dm->getClassMetadata($mapping['targetDocument']);
                if ($targetClass->hasField($e[1]) && $targetClass->identifier === $e[1]) {
                    $fieldName = $e[0] . '.$id';
                    $value = $targetClass->getDatabaseIdentifierValue($value);
                } elseif ($e[1] === '$id') {
                    $value = $targetClass->getDatabaseIdentifierValue($value);
                }
            }
        } elseif ($this->class->hasField($fieldName) && ! $this->class->isIdentifier($fieldName)) {
            $name = $this->class->fieldMappings[$fieldName]['name'];
            if ($name !== $fieldName) {
                $fieldName = $name;
            }
        } else {
            if ($fieldName === $this->class->identifier || $fieldName === '_id') {
                $fieldName = '_id';
                if (is_array($value)) {
                    if (isset($value[$this->cmd.'in'])) {
                        foreach ($value[$this->cmd.'in'] as $k => $v) {
                            $value[$this->cmd.'in'][$k] = $this->class->getDatabaseIdentifierValue($v);
                        }
                    } else {
                        foreach ($value as $k => $v) {
                            $value[$k] = $this->class->getDatabaseIdentifierValue($v);
                        }
                    }
                } else {
                    $value = $this->class->getDatabaseIdentifierValue($value);
                }
            }
        }
        return $value;
    }
Beispiel #13
0
 /**
  * Return the document field mapping for a property path.
  *
  * @param ClassMetadata $metadata
  * @param object        $document
  * @param string        $path
  * @return array
  * @throw ConstraintDefinitionException if no field mapping exists for the property path
  */
 private function getFieldMappingForPropertyPath(ClassMetadata $metadata, $document, $path)
 {
     // Extract the first part of the property path before any dot separator
     $fieldName = false !== ($beforeDot = strstr($path, '.', true)) ? $beforeDot : $path;
     if (!$metadata->hasField($fieldName)) {
         throw new ConstraintDefinitionException(sprintf('Mapping for "%s" does not exist for "%s"', $path, $metadata->name));
     }
     return $metadata->getFieldMapping($fieldName);
 }
Beispiel #14
0
 /**
  * Checks if $field type is valid
  *
  * @param \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $meta
  * @param string                                      $field
  *
  * @return boolean
  */
 protected function isValidField($meta, $field)
 {
     $mapping = $meta->getFieldMapping($field);
     return $mapping && in_array($mapping['type'], $this->validTypes);
 }
Beispiel #15
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)
 {
     $mapping = $class->getFieldMapping($fieldName);
     /* 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();
     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);
     }
 }
 private function prepareIndexes(ClassMetadata $class)
 {
     $indexes = $class->getIndexes();
     $newIndexes = array();
     foreach ($indexes as $index) {
         $newIndex = array('keys' => array(), 'options' => $index['options']);
         foreach ($index['keys'] as $key => $value) {
             $mapping = $class->getFieldMapping($key);
             $newIndex['keys'][$mapping['name']] = $value;
         }
         $newIndexes[] = $newIndex;
     }
     return $newIndexes;
 }
Beispiel #17
0
 /**
  * @param ClassMetadata $class
  * @return array
  */
 private function prepareIndexes(ClassMetadata $class)
 {
     $persister = $this->dm->getUnitOfWork()->getDocumentPersister($class->name);
     $indexes = $class->getIndexes();
     $newIndexes = array();
     foreach ($indexes as $index) {
         $newIndex = array('keys' => array(), 'options' => $index['options']);
         foreach ($index['keys'] as $key => $value) {
             $key = $persister->prepareFieldName($key);
             if ($class->hasField($key)) {
                 $mapping = $class->getFieldMapping($key);
                 $newIndex['keys'][$mapping['name']] = $value;
             } else {
                 $newIndex['keys'][$key] = $value;
             }
         }
         $newIndexes[] = $newIndex;
     }
     return $newIndexes;
 }