/**
  * 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;
 }
 /**
  * Prepares insert data for document
  *
  * @param mixed $document
  * @return array
  */
 public function prepareInsertData($document)
 {
     $oid = spl_object_hash($document);
     $changeset = $this->uow->getDocumentChangeSet($document);
     $insertData = array();
     foreach ($this->class->fieldMappings as $mapping) {
         if (isset($mapping['notSaved']) && $mapping['notSaved'] === true) {
             continue;
         }
         $new = isset($changeset[$mapping['fieldName']][1]) ? $changeset[$mapping['fieldName']][1] : null;
         if ($new === null && $mapping['nullable'] === false) {
             continue;
         }
         if ($this->class->isIdentifier($mapping['fieldName'])) {
             $insertData['_id'] = $this->prepareValue($mapping, $new);
             continue;
         }
         $value = $this->prepareValue($mapping, $new);
         if ($value === null && $mapping['nullable'] === false) {
             continue;
         }
         $insertData[$mapping['name']] = $value;
         if (isset($mapping['reference'])) {
             $scheduleForUpdate = false;
             if ($mapping['type'] === 'one') {
                 if (!isset($insertData[$mapping['name']][$this->cmd . 'id'])) {
                     $scheduleForUpdate = true;
                 }
             } elseif ($mapping['type'] === 'many') {
                 foreach ($insertData[$mapping['name']] as $ref) {
                     if (!isset($ref[$this->cmd . 'id'])) {
                         $scheduleForUpdate = true;
                         break;
                     }
                 }
             }
             if ($scheduleForUpdate) {
                 unset($insertData[$mapping['name']]);
                 $id = spl_object_hash($document);
                 $this->documentsToUpdate[$id] = $document;
                 $this->fieldsToUpdate[$id][$mapping['fieldName']] = array($mapping, $new);
             }
         }
     }
     // add discriminator if the class has one
     if ($this->class->hasDiscriminator()) {
         $insertData[$this->class->discriminatorField['name']] = $this->class->discriminatorValue;
     }
     return $insertData;
 }
    /**
     * 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;
    }
 /**
  * Prepares update array for document, using atomic operators
  *
  * @param mixed $document
  * @return array
  */
 public function prepareUpdateData($document)
 {
     $oid = spl_object_hash($document);
     $changeset = $this->_uow->getDocumentChangeSet($document);
     $result = array();
     foreach ($this->_class->fieldMappings as $mapping) {
         if (isset($mapping['notSaved']) && $mapping['notSaved'] === true) {
             continue;
         }
         $old = isset($changeset[$mapping['fieldName']][0]) ? $changeset[$mapping['fieldName']][0] : null;
         $new = isset($changeset[$mapping['fieldName']][1]) ? $changeset[$mapping['fieldName']][1] : null;
         $new = $this->_prepareValue($mapping, $new);
         $old = $this->_prepareValue($mapping, $old);
         if ($this->_class->isIdentifier($mapping['fieldName']) && !$this->_equals($new, $old)) {
             throw MongoDBException::identifierCannotBeUpdated();
         }
         if ($mapping['type'] === 'many' || $mapping['type'] === 'collection') {
             $this->_addArrayUpdateAtomicOperator($mapping, (array) $new, (array) $old, $result);
         } else {
             $this->_addFieldUpdateAtomicOperator($mapping, $new, $old, $result);
         }
     }
     return $result;
 }
 /**
  * {@inheritdoc}
  */
 public function isIdentifier($fieldName)
 {
     return $this->classMetadata->isIdentifier($fieldName);
 }