/**
  * 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;
 }
예제 #2
0
 /**
  * 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;
 }
    /**
     * 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;
    }
 /**
  * Add mapping data to a translation entity.
  *
  * @param ClassMetadata $metadata
  */
 private function mapTranslation(ClassMetadata $metadata)
 {
     // In the case A -> B -> TranslationInterface, B might not have mapping defined as it
     // is probably defined in A, so in that case, we just return.
     if (!isset($this->configs[$metadata->name])) {
         return;
     }
     $metadata->mapManyToOne(array('fieldName' => 'translatable', 'targetEntity' => $this->configs[$metadata->name]['model'], 'inversedBy' => 'translations', 'joinColumns' => array(array('name' => 'translatable_id', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE', 'nullable' => false))));
     if (!$metadata->hasField('locale')) {
         $metadata->mapField(array('fieldName' => 'locale', 'type' => 'string', 'nullable' => false));
     }
     // Map unique index.
     $columns = array($metadata->getSingleAssociationJoinColumnName('translatable'), 'locale');
     if (!$this->hasUniqueConstraint($metadata, $columns)) {
         $constraints = isset($metadata->table['uniqueConstraints']) ? $metadata->table['uniqueConstraints'] : array();
         $constraints[$metadata->getTableName() . '_uniq_trans'] = array('columns' => $columns);
         $metadata->setPrimaryTable(array('uniqueConstraints' => $constraints));
     }
 }
예제 #5
0
 /**
  * Adds support for magic finders.
  *
  * @param string $method
  * @param array $arguments
  * @throws MongoDBException
  * @throws \BadMethodCallException If the method called is an invalid find* method
  *                                 or no find* method at all and therefore an invalid
  *                                 method call.
  * @return array|object The found document/documents.
  */
 public function __call($method, $arguments)
 {
     if (substr($method, 0, 6) == 'findBy') {
         $by = substr($method, 6, strlen($method));
         $method = 'findBy';
     } elseif (substr($method, 0, 9) == 'findOneBy') {
         $by = substr($method, 9, strlen($method));
         $method = 'findOneBy';
     } else {
         throw new \BadMethodCallException("Undefined method '{$method}'. The method name must start with " . "either findBy or findOneBy!");
     }
     if (!isset($arguments[0])) {
         throw MongoDBException::findByRequiresParameter($method . $by);
     }
     $fieldName = lcfirst(\Doctrine\Common\Util\Inflector::classify($by));
     if ($this->class->hasField($fieldName)) {
         return $this->{$method}(array($fieldName => $arguments[0]));
     } else {
         throw MongoDBException::invalidFindByCall($this->documentName, $fieldName, $method . $by);
     }
 }
예제 #6
0
 /**
  * Adds support for magic finders.
  *
  * @param string $method
  * @param array $arguments
  * @throws MongoDBException
  * @throws \BadMethodCallException If the method called is an invalid find* method
  *                                 or no find* method at all and therefore an invalid
  *                                 method call.
  * @return array|object The found document/documents.
  */
 public function __call($method, $arguments)
 {
     if (strpos($method, 'findBy') === 0) {
         $by = substr($method, 6, strlen($method));
         $method = 'findBy';
     } elseif (strpos($method, 'findOneBy') === 0) {
         $by = substr($method, 9, strlen($method));
         $method = 'findOneBy';
     } else {
         throw new \BadMethodCallException("Undefined method: '{$method}'. The method name must start with 'findBy' or 'findOneBy'!");
     }
     if (!isset($arguments[0])) {
         throw MongoDBException::findByRequiresParameter($method . $by);
     }
     $fieldName = Inflector::camelize($by);
     if ($this->class->hasField($fieldName)) {
         return $this->{$method}(array($fieldName => $arguments[0]));
     } else {
         throw MongoDBException::invalidFindByCall($this->documentName, $fieldName, $method . $by);
     }
 }
예제 #7
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);
 }
예제 #8
0
 /**
  * Add mapping data to a translation entity
  *
  * @param ClassMetadata $metadata
  */
 private function mapTranslation(ClassMetadata $metadata)
 {
     // In the case A -> B -> TranslationInterface, B might not have mapping defined as it
     // is probably defined in A, so in that case, we just return;
     if (!isset($this->mappings[$metadata->name])) {
         return;
     }
     $config = $this->mappings[$metadata->name];
     $mapping = $config['translation']['mapping'];
     $metadata->isEmbeddedDocument = true;
     $metadata->isMappedSuperclass = false;
     $metadata->setIdentifier(null);
     // Map locale field.
     if (!$metadata->hasField($mapping['translation']['locale'])) {
         $metadata->mapField(array('fieldName' => $mapping['translation']['locale'], 'type' => 'string'));
     }
     // Map unique index.
     $keys = array($mapping['translation']['translatable'] => 1, $mapping['translation']['locale'] => 1);
     if (!$this->hasUniqueIndex($metadata, $keys)) {
         $metadata->addIndex($keys, array('unique' => true));
     }
 }
예제 #9
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;
 }
예제 #10
0
 /**
  * Check if the method is a short identifier getter.
  *
  * What does this mean? For proxy objects the identifier is already known,
  * however accessing the getter for this identifier usually triggers the
  * lazy loading, leading to a query that may not be necessary if only the
  * ID is interesting for the userland code (for example in views that
  * generate links to the document, but do not display anything else).
  *
  * @param ReflectionMethod $method
  * @param ClassMetadata $class
  * @return bool
  */
 private function isShortIdentifierGetter($method, $class)
 {
     $identifier = lcfirst(substr($method->getName(), 3));
     $cheapCheck = $method->getNumberOfParameters() == 0 && substr($method->getName(), 0, 3) == "get" && $class->identifier === $identifier && $class->hasField($identifier) && $method->getEndLine() - $method->getStartLine() <= 4 && in_array($class->fieldMappings[$identifier]['type'], array('id', 'custom_id'));
     if ($cheapCheck) {
         $code = file($method->getDeclaringClass()->getFileName());
         $code = trim(implode(" ", array_slice($code, $method->getStartLine() - 1, $method->getEndLine() - $method->getStartLine() + 1)));
         $pattern = sprintf(self::PATTERN_MATCH_ID_METHOD, $method->getName(), $identifier);
         if (preg_match($pattern, $code)) {
             return true;
         }
     }
     return false;
 }
예제 #11
0
 /** {@inheritdoc} */
 public function hasField($name)
 {
     return $this->classMetadata->hasField($name) && !$this->classMetadata->hasAssociation($name);
 }
예제 #12
0
 /**
  * {@inheritdoc}
  */
 public function hasField($fieldName)
 {
     return $this->classMetadata->hasField($fieldName);
 }