/** * Makes additional translation of $document $field into $locale * using $value * * @param object $document * @param string $field * @param string $locale * @param mixed $value * @return TranslationRepository */ public function translate($document, $field, $locale, $value) { $meta = $this->dm->getClassMetadata(get_class($document)); $listener = $this->getTranslatableListener(); $config = $listener->getConfiguration($this->dm, $meta->name); if (!isset($config['fields']) || !in_array($field, $config['fields'])) { throw new \Gedmo\Exception\InvalidArgumentException("Document: {$meta->name} does not translate field - {$field}"); } $modRecordValue = !$listener->getPersistDefaultLocaleTranslation() && $locale === $listener->getDefaultLocale() || $listener->getTranslatableLocale($document, $meta) === $locale; if ($modRecordValue) { $meta->getReflectionProperty($field)->setValue($document, $value); $this->dm->persist($document); } else { if (isset($config['translationClass'])) { $class = $config['translationClass']; } else { $ea = new TranslatableAdapterODM(); $class = $listener->getTranslationClass($ea, $config['useObjectClass']); } $foreignKey = $meta->getReflectionProperty($meta->identifier)->getValue($document); $objectClass = $config['useObjectClass']; $transMeta = $this->dm->getClassMetadata($class); $trans = $this->findOneBy(compact('locale', 'field', 'objectClass', 'foreignKey')); if (!$trans) { $trans = $transMeta->newInstance(); $transMeta->getReflectionProperty('foreignKey')->setValue($trans, $foreignKey); $transMeta->getReflectionProperty('objectClass')->setValue($trans, $objectClass); $transMeta->getReflectionProperty('field')->setValue($trans, $field); $transMeta->getReflectionProperty('locale')->setValue($trans, $locale); } $mapping = $meta->getFieldMapping($field); $type = Type::getType($mapping['type']); $transformed = $type->convertToDatabaseValue($value); $transMeta->getReflectionProperty('content')->setValue($trans, $transformed); if ($this->dm->getUnitOfWork()->isInIdentityMap($document)) { $this->dm->persist($trans); } else { $oid = spl_object_hash($document); $listener->addPendingTranslationInsert($oid, $trans); } } return $this; }
/** * Converts any local PHP variable types to their related MongoDB type. * * @param array $query * @return array $query */ private function convertTypes(array $query) { foreach ($query as $key => $value) { if (is_array($value)) { $query[$key] = $this->convertTypes($value); } else { $query[$key] = Type::convertPHPToDatabaseValue($value); } } return $query; }
private function getType($type) { // due to change in ODM beta 9 return class_exists('Doctrine\\ODM\\MongoDB\\Types\\Type') ? \Doctrine\ODM\MongoDB\Types\Type::getType($type) : \Doctrine\ODM\MongoDB\Mapping\Types\Type::getType($type); }
/** * Prepares array of values to be stored in mongo to represent embedded object. * * @param array $embeddedMapping * @param Document $embeddedDocument * @return array */ private function prepareEmbeddedDocValue(array $embeddedMapping, $embeddedDocument) { if (is_array($embeddedDocument) && isset($embeddedDocument['originalObject'])) { $embeddedDocument = $embeddedDocument['originalObject']; } $className = get_class($embeddedDocument); $class = $this->dm->getClassMetadata($className); $embeddedDocumentValue = array(); foreach ($class->fieldMappings as $mapping) { // Skip not saved fields if (isset($mapping['notSaved']) && $mapping['notSaved'] === true) { continue; } $rawValue = $class->getFieldValue($embeddedDocument, $mapping['fieldName']); // Don't store null values unless nullable is specified if ($rawValue === null && $mapping['nullable'] === false) { continue; } if (isset($mapping['embedded']) || isset($mapping['reference'])) { if (isset($mapping['embedded'])) { if ($mapping['type'] == 'many') { $value = array(); foreach ($rawValue as $embeddedDoc) { $value[] = $this->prepareEmbeddedDocValue($mapping, $embeddedDoc); } if (empty($value)) { $value = null; } } elseif ($mapping['type'] == 'one') { $value = $this->prepareEmbeddedDocValue($mapping, $rawValue); } } elseif (isset($mapping['reference'])) { if ($mapping['type'] == 'many') { $value = array(); foreach ($rawValue as $referencedDoc) { $value[] = $this->prepareReferencedDocValue($mapping, $referencedDoc); } if (empty($value)) { $value = null; } } else { $value = $this->prepareReferencedDocValue($mapping, $rawValue); } } } else { $value = Type::getType($mapping['type'])->convertToDatabaseValue($rawValue); } if ($value === null && $mapping['nullable'] === false) { continue; } $embeddedDocumentValue[$mapping['fieldName']] = $value; } if (!isset($embeddedMapping['targetDocument'])) { $discriminatorField = isset($embeddedMapping['discriminatorField']) ? $embeddedMapping['discriminatorField'] : '_doctrine_class_name'; $discriminatorValue = isset($embeddedMapping['discriminatorMap']) ? array_search($class->getName(), $embeddedMapping['discriminatorMap']) : $class->getName(); $embeddedDocumentValue[$discriminatorField] = $discriminatorValue; } return $embeddedDocumentValue; }
/** * Prepares array of values to be stored in mongo to represent embedded object. * * @param array $embeddedMapping * @param Document $embeddedDocument * @return array */ public function prepareEmbeddedDocValue(array $embeddedMapping, $embeddedDocument) { $className = get_class($embeddedDocument); $class = $this->dm->getClassMetadata($className); $embeddedDocumentValue = array(); foreach ($class->fieldMappings as $mapping) { // Skip not saved fields if (isset($mapping['notSaved']) && $mapping['notSaved'] === true) { continue; } $rawValue = $class->getFieldValue($embeddedDocument, $mapping['fieldName']); // Generate embedded document identifiers if ($class->isIdentifier($mapping['fieldName'])) { if ( ! $class->isIdGeneratorNone() && $rawValue === null) { $rawValue = $class->idGenerator->generate($this->dm, $embeddedDocument); $class->setIdentifierValue($embeddedDocument, $rawValue); } $embeddedDocumentValue['_id'] = Type::getType($mapping['type'])->convertToDatabaseValue($rawValue); continue; } // Don't store null values unless nullable is specified if ($rawValue === null && $mapping['nullable'] === false) { continue; } $value = null; if (isset($mapping['embedded']) && $mapping['type'] == 'one') { $value = $this->prepareEmbeddedDocValue($mapping, $rawValue); } elseif (isset($mapping['embedded']) && $mapping['type'] == 'many') { // do nothing for embedded many // CollectionPersister will take care of this } elseif (isset($mapping['reference']) && $mapping['type'] === 'one') { $value = $this->prepareReferencedDocValue($mapping, $rawValue); } else { $value = Type::getType($mapping['type'])->convertToDatabaseValue($rawValue); } if ($value === null && $mapping['nullable'] === false) { continue; } $embeddedDocumentValue[$mapping['name']] = $value; } // Store a discriminator value if the embedded document is not mapped explicitely to a targetDocument if ( ! isset($embeddedMapping['targetDocument'])) { $discriminatorField = isset($embeddedMapping['discriminatorField']) ? $embeddedMapping['discriminatorField'] : '_doctrine_class_name'; $discriminatorValue = isset($embeddedMapping['discriminatorMap']) ? array_search($class->getName(), $embeddedMapping['discriminatorMap']) : $class->getName(); $embeddedDocumentValue[$discriminatorField] = $discriminatorValue; } // Fix so that we can force empty embedded document to store itself as a hash instead of an array if (empty($embeddedDocumentValue)) { return (object) $embeddedDocumentValue; } return $embeddedDocumentValue; }
private function doGenericHydration(ClassMetadata $metadata, $document, $data) { foreach ($metadata->fieldMappings as $mapping) { // Find the raw value. It may be in one of the mapped alsoLoadFields. $found = false; if (isset($mapping['alsoLoadFields']) && $mapping['alsoLoadFields']) { foreach ($mapping['alsoLoadFields'] as $name) { if (isset($data[$name])) { $rawValue = $data[$name]; $found = true; break; } } } // If nothing then lets get it from the default mapping field name if ($found === false) { $rawValue = isset($data[$mapping['name']]) ? $data[$mapping['name']] : null; } $value = null; // Prepare the different types of mapped values converting them from the MongoDB // types to the portable Doctrine types. // @Field if (!isset($mapping['association'])) { $value = Type::getType($mapping['type'])->convertToPHPValue($rawValue); // @ReferenceOne } elseif ($mapping['association'] === ClassMetadata::REFERENCE_ONE) { $reference = $rawValue; if ($reference === null || !isset($reference[$this->cmd . 'id'])) { continue; } $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $reference); $targetMetadata = $this->dm->getClassMetadata($className); $id = $targetMetadata->getPHPIdentifierValue($reference[$this->cmd . 'id']); $value = $this->dm->getReference($className, $id); // @ReferenceMany and @EmbedMany } elseif ($mapping['association'] === ClassMetadata::REFERENCE_MANY || $mapping['association'] === ClassMetadata::EMBED_MANY) { $value = new PersistentCollection(new ArrayCollection(), $this->dm, $this->unitOfWork, $this->cmd); $value->setOwner($document, $mapping); $value->setInitialized(false); if ($rawValue) { $value->setMongoData($rawValue); } // @EmbedOne } elseif ($mapping['association'] === ClassMetadata::EMBED_ONE) { if ($rawValue === null) { continue; } $embeddedDocument = $rawValue; $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $embeddedDocument); $embeddedMetadata = $this->dm->getClassMetadata($className); $value = $embeddedMetadata->newInstance(); $embeddedHydratedData = $this->hydrate($value, $embeddedDocument); $this->unitOfWork->registerManaged($value, null, $embeddedHydratedData); $this->unitOfWork->setParentAssociation($value, $mapping, $document, $mapping['name']); } unset($data[$mapping['name']]); // Hydrate the prepared value to the document if ($value !== null) { $metadata->reflFields[$mapping['fieldName']]->setValue($document, $value); $data[$mapping['fieldName']] = $value; } } return $data; }
private function prepareTypeValue($type, $value) { if (is_array($value)) { if (isset($value[$this->cmd . 'type'])) { // do nothing } elseif (isset($value[$this->cmd . 'not'])) { $value[$this->cmd . 'not'] = $this->prepareTypeValue($type, $value[$this->cmd . 'not']); } elseif (isset($value[$this->cmd . 'in'])) { foreach ($value[$this->cmd . 'in'] as $k => $v) { $value[$this->cmd . 'in'][$k] = Type::getType($type)->convertToDatabaseValue($v); } } else { foreach ($value as $k => $v) { $value[$k] = Type::getType($type)->convertToDatabaseValue($v); } } } else { $value = Type::getType($type)->convertToDatabaseValue($value); } return $value; }
/** * Prepares array of values to be stored in mongo to represent embedded object. * * @param array $embeddedMapping * @param object $embeddedDocument * @return array|object $embeddedDocumentValue */ public function prepareEmbeddedDocumentValue(array $embeddedMapping, $embeddedDocument) { $className = get_class($embeddedDocument); $class = $this->dm->getClassMetadata($className); $embeddedDocumentValue = array(); foreach ($class->fieldMappings as $mapping) { // Skip not saved fields if (isset($mapping['notSaved']) && $mapping['notSaved'] === true) { continue; } $rawValue = $class->reflFields[$mapping['fieldName']]->getValue($embeddedDocument); // Generate a document identifier if ($rawValue === null && $class->identifier === $mapping['fieldName'] && $class->generatorType !== ClassMetadata::GENERATOR_TYPE_NONE) { $rawValue = $class->idGenerator->generate($this->dm, $embeddedDocument); $class->setIdentifierValue($embeddedDocument, $rawValue); } $value = null; if ($rawValue !== null) { /** @Field, @String, @Date, etc. */ if (!isset($mapping['association'])) { $value = Type::getType($mapping['type'])->convertToDatabaseValue($rawValue); /** @EmbedOne */ } elseif (isset($mapping['association']) && $mapping['association'] == ClassMetadata::EMBED_ONE) { $value = $this->prepareEmbeddedDocumentValue($mapping, $rawValue); /** @EmbedMany */ } elseif (isset($mapping['association']) && $mapping['association'] == ClassMetadata::EMBED_MANY) { // do nothing for embedded many // CollectionPersister will take care of this /** @ReferenceOne */ } elseif (isset($mapping['association']) && $mapping['association'] == ClassMetadata::REFERENCE_ONE) { $value = $this->prepareReferencedDocumentValue($mapping, $rawValue); } } if ($value === null && $mapping['nullable'] === false) { continue; } $embeddedDocumentValue[$mapping['name']] = $value; } // Store a discriminator value if the embedded document is not mapped explicitely to a targetDocument if (!isset($embeddedMapping['targetDocument'])) { $discriminatorField = isset($embeddedMapping['discriminatorField']) ? $embeddedMapping['discriminatorField'] : '_doctrine_class_name'; $discriminatorValue = isset($embeddedMapping['discriminatorMap']) ? array_search($class->getName(), $embeddedMapping['discriminatorMap']) : $class->getName(); $embeddedDocumentValue[$discriminatorField] = $discriminatorValue; } // Fix so that we can force empty embedded document to store itself as a hash instead of an array if (empty($embeddedDocumentValue)) { return (object) $embeddedDocumentValue; } if ($class->discriminatorField) { $embeddedDocumentValue[$class->discriminatorField['name']] = $class->discriminatorValue; } return $embeddedDocumentValue; }
/** * Hydrate array of MongoDB document data into the given document object. * * @param object $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($document, &$data) { $metadata = $this->dm->getClassMetadata(get_class($document)); if (isset($metadata->alsoLoadMethods)) { foreach ($metadata->alsoLoadMethods as $fieldName => $method) { if (isset($data[$fieldName])) { $document->{$method}($data[$fieldName]); } } } foreach ($metadata->fieldMappings as $mapping) { if (isset($mapping['alsoLoadFields'])) { $rawValue = null; $names = isset($mapping['alsoLoadFields']) ? $mapping['alsoLoadFields'] : array(); array_unshift($names, $mapping['name']); foreach ($names as $name) { if (isset($data[$name])) { $rawValue = $data[$name]; break; } } } else { $rawValue = isset($data[$mapping['name']]) ? $data[$mapping['name']] : null; } if ($rawValue === null) { continue; } $value = null; // Hydrate embedded if (isset($mapping['embedded'])) { if ($mapping['type'] === 'one') { $embeddedDocument = $rawValue; $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $embeddedDocument); $embeddedMetadata = $this->dm->getClassMetadata($className); $value = $embeddedMetadata->newInstance(); $this->hydrate($value, $embeddedDocument); $this->dm->getUnitOfWork()->registerManagedEmbeddedDocument($value, $embeddedDocument); } elseif ($mapping['type'] === 'many') { $embeddedDocuments = $rawValue; $coll = new PersistentCollection(new ArrayCollection()); foreach ($embeddedDocuments as $embeddedDocument) { $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $embeddedDocument); $embeddedMetadata = $this->dm->getClassMetadata($className); $embeddedDocumentObject = $embeddedMetadata->newInstance(); $this->hydrate($embeddedDocumentObject, $embeddedDocument); $this->dm->getUnitOfWork()->registerManagedEmbeddedDocument($embeddedDocumentObject, $embeddedDocument); $coll->add($embeddedDocumentObject); } $coll->setOwner($document, $mapping); $coll->takeSnapshot(); $value = $coll; } // Hydrate reference } elseif (isset($mapping['reference'])) { $reference = $rawValue; if ($mapping['type'] === 'one' && isset($reference[$this->cmd . 'id'])) { $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $reference); $targetMetadata = $this->dm->getClassMetadata($className); $id = $targetMetadata->getPHPIdentifierValue($reference[$this->cmd . 'id']); $value = $this->dm->getReference($className, $id); } elseif ($mapping['type'] === 'many' && (is_array($reference) || $reference instanceof Collection)) { $references = $reference; $value = new PersistentCollection(new ArrayCollection(), $this->dm); $value->setInitialized(false); $value->setOwner($document, $mapping); // Delay any hydration of reference objects until the collection is // accessed and initialized for the first ime $value->setReferences($references); } // Hydrate regular field } else { $value = Type::getType($mapping['type'])->convertToPHPValue($rawValue); } // Set hydrated field value to document if ($value !== null) { $data[$mapping['name']] = $value; $metadata->setFieldValue($document, $mapping['fieldName'], $value); } } // Set the document identifier if (isset($data['_id'])) { $metadata->setIdentifierValue($document, $data['_id']); $data[$metadata->identifier] = $data['_id']; unset($data['_id']); } return $document; }
/** * {@inheritDoc} */ public function setTranslationValue($object, $field, $value) { $dm = $this->getObjectManager(); $wrapped = AbstractWrapper::wrap($object, $dm); $meta = $wrapped->getMetadata(); $mapping = $meta->getFieldMapping($field); $type = Type::getType($mapping['type']); $value = $type->convertToPHPValue($value); $wrapped->setPropertyValue($field, $value); }
public static function setUpBeforeClass() { Type::addType('date_collection', __NAMESPACE__ . '\\DateCollectionType'); }
/** * {@inheritDoc} */ public function setTranslationValue($object, $field, $value) { $dm = $this->getObjectManager(); $meta = $dm->getClassMetadata(get_class($object)); $mapping = $meta->getFieldMapping($field); $type = Type::getType($mapping['type']); $value = $type->convertToPHPValue($value); $meta->getReflectionProperty($field)->setValue($object, $value); }
private function generateHydratorClass(ClassMetadata $class, $hydratorClassName, $fileName) { $code = ''; foreach ($class->fieldMappings as $fieldName => $mapping) { if (isset($mapping['alsoLoadFields'])) { foreach ($mapping['alsoLoadFields'] as $name) { $code .= sprintf(<<<EOF /** @AlsoLoad("{$name}") */ if (isset(\$data['{$name}'])) { \$data['{$fieldName}'] = \$data['{$name}']; } EOF ); } } if ($mapping['type'] === 'date') { $code .= sprintf(<<<EOF /** @Field(type="date") */ if (isset(\$data['%1\$s'])) { \$value = \$data['%1\$s']; %3\$s \$this->class->reflFields['%2\$s']->setValue(\$document, clone \$return); \$hydratedData['%2\$s'] = \$return; } EOF , $mapping['name'], $mapping['fieldName'], Type::getType($mapping['type'])->closureToPHP()); } elseif (!isset($mapping['association'])) { $code .= sprintf(<<<EOF /** @Field(type="{$mapping['type']}") */ if (isset(\$data['%1\$s'])) { \$value = \$data['%1\$s']; %3\$s \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; } EOF , $mapping['name'], $mapping['fieldName'], Type::getType($mapping['type'])->closureToPHP()); } elseif ($mapping['association'] === ClassMetadata::REFERENCE_ONE && $mapping['isOwningSide']) { $code .= sprintf(<<<EOF /** @ReferenceOne */ if (isset(\$data['%1\$s'])) { \$reference = \$data['%1\$s']; if (isset(\$this->class->fieldMappings['%2\$s']['simple']) && \$this->class->fieldMappings['%2\$s']['simple']) { \$className = \$this->class->fieldMappings['%2\$s']['targetDocument']; \$mongoId = \$reference; } else { \$className = \$this->dm->getClassNameFromDiscriminatorValue(\$this->class->fieldMappings['%2\$s'], \$reference); \$mongoId = \$reference['\$id']; } \$targetMetadata = \$this->dm->getClassMetadata(\$className); \$id = \$targetMetadata->getPHPIdentifierValue(\$mongoId); \$return = \$this->dm->getReference(\$className, \$id); \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; } EOF , $mapping['name'], $mapping['fieldName']); } elseif ($mapping['association'] === ClassMetadata::REFERENCE_ONE && $mapping['isInverseSide']) { if (isset($mapping['repositoryMethod']) && $mapping['repositoryMethod']) { $code .= sprintf(<<<EOF \$className = \$this->class->fieldMappings['%2\$s']['targetDocument']; \$return = \$this->dm->getRepository(\$className)->%3\$s(\$document); \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; EOF , $mapping['name'], $mapping['fieldName'], $mapping['repositoryMethod']); } else { $code .= sprintf(<<<EOF \$mapping = \$this->class->fieldMappings['%2\$s']; \$className = \$mapping['targetDocument']; \$targetClass = \$this->dm->getClassMetadata(\$mapping['targetDocument']); \$mappedByMapping = \$targetClass->fieldMappings[\$mapping['mappedBy']]; \$mappedByFieldName = isset(\$mappedByMapping['simple']) && \$mappedByMapping['simple'] ? \$mapping['mappedBy'] : \$mapping['mappedBy'].'.id'; \$criteria = array_merge( array(\$mappedByFieldName => \$data['_id']), isset(\$this->class->fieldMappings['%2\$s']['criteria']) ? \$this->class->fieldMappings['%2\$s']['criteria'] : array() ); \$sort = isset(\$this->class->fieldMappings['%2\$s']['sort']) ? \$this->class->fieldMappings['%2\$s']['sort'] : array(); \$return = \$this->unitOfWork->getDocumentPersister(\$className)->load(\$criteria, null, array(), 0, \$sort); \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; EOF , $mapping['name'], $mapping['fieldName']); } } elseif ($mapping['association'] === ClassMetadata::REFERENCE_MANY || $mapping['association'] === ClassMetadata::EMBED_MANY) { $code .= sprintf(<<<EOF /** @Many */ \$mongoData = isset(\$data['%1\$s']) ? \$data['%1\$s'] : null; \$return = new \\Doctrine\\ODM\\MongoDB\\PersistentCollection(new \\Doctrine\\Common\\Collections\\ArrayCollection(), \$this->dm, \$this->unitOfWork, '\$'); \$return->setHints(\$hints); \$return->setOwner(\$document, \$this->class->fieldMappings['%2\$s']); \$return->setInitialized(false); if (\$mongoData) { \$return->setMongoData(\$mongoData); } \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; EOF , $mapping['name'], $mapping['fieldName']); } elseif ($mapping['association'] === ClassMetadata::EMBED_ONE) { $code .= sprintf(<<<EOF /** @EmbedOne */ if (isset(\$data['%1\$s'])) { \$embeddedDocument = \$data['%1\$s']; \$className = \$this->dm->getClassNameFromDiscriminatorValue(\$this->class->fieldMappings['%2\$s'], \$embeddedDocument); \$embeddedMetadata = \$this->dm->getClassMetadata(\$className); \$return = \$embeddedMetadata->newInstance(); \$embeddedData = \$this->dm->getHydratorFactory()->hydrate(\$return, \$embeddedDocument, \$hints); \$this->unitOfWork->registerManaged(\$return, null, \$embeddedData); \$this->unitOfWork->setParentAssociation(\$return, \$this->class->fieldMappings['%2\$s'], \$document, '%1\$s'); \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; } EOF , $mapping['name'], $mapping['fieldName']); } } $className = $class->name; $namespace = $this->hydratorNamespace; $code = sprintf(<<<EOF <?php namespace {$namespace}; use Doctrine\\ODM\\MongoDB\\DocumentManager; use Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata; use Doctrine\\ODM\\MongoDB\\Hydrator\\HydratorInterface; use Doctrine\\ODM\\MongoDB\\UnitOfWork; /** * THIS CLASS WAS GENERATED BY THE DOCTRINE ODM. DO NOT EDIT THIS FILE. */ class {$hydratorClassName} implements HydratorInterface { private \$dm; private \$unitOfWork; private \$class; public function __construct(DocumentManager \$dm, UnitOfWork \$uow, ClassMetadata \$class) { \$this->dm = \$dm; \$this->unitOfWork = \$uow; \$this->class = \$class; } public function hydrate(\$document, \$data, array \$hints = array()) { \$hydratedData = array(); %s return \$hydratedData; } } EOF , $code); file_put_contents($fileName, $code); }
private function generateDocumentStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null) { $methodName = $type . Inflector::classify($fieldName); if ($this->hasMethod($methodName, $metadata)) { return; } $var = sprintf('%sMethodTemplate', $type); $template = self::${$var}; $variableType = $typeHint ? $typeHint . ' ' : null; $types = \Doctrine\ODM\MongoDB\Mapping\Types\Type::getTypesMap(); $methodTypeHint = $typeHint && !isset($types[$typeHint]) ? '\\' . $typeHint . ' ' : null; $replacements = array('<description>' => ucfirst($type) . ' ' . $fieldName, '<methodTypeHint>' => $methodTypeHint, '<variableType>' => $variableType, '<variableName>' => Inflector::camelize($fieldName), '<methodName>' => $methodName, '<fieldName>' => $fieldName); $method = str_replace(array_keys($replacements), array_values($replacements), $template); return $this->prefixCodeWithSpaces($method); }
/** * Prepares array of values to be stored in mongo to represent embedded object. * * @param ClassMetadata $class * @param Document $doc * @return array */ private function _prepareDocEmbeded(ClassMetadata $class, $doc) { if (!is_object($doc)) { return $doc; } $changeset = array(); foreach ($class->fieldMappings as $mapping) { $rawValue = $class->getFieldValue($doc, $mapping['fieldName']); if (!isset($rawValue)) { continue; } if (isset($mapping['embedded']) || isset($mapping['reference'])) { $classMetadata = $this->_dm->getClassMetadata($mapping['targetDocument']); if (isset($mapping['embedded'])) { if ($mapping['type'] == 'many') { $value = array(); foreach ($rawValue as $doc) { $value[] = $this->_prepareDocEmbeded($classMetadata, $doc); } } elseif ($mapping['type'] == 'one') { $value = $this->_prepareDocEmbeded($classMetadata, $rawValue); } } elseif (isset($mapping['reference'])) { if ($mapping['type'] == 'many') { $value = array(); foreach ($rawValue as $doc) { $value[] = $this->_prepareDocReference($classMetadata, $doc); } } else { $value = $this->_prepareDocReference($classMetadata, $rawValue); } } } else { $value = Type::getType($mapping['type'])->convertToDatabaseValue($rawValue); } $changeset[$mapping['fieldName']] = $value; } return $changeset; }
public function getDatabaseIdentifierValue($id) { $idType = $this->fieldMappings[$this->identifier]['type']; return Types\Type::getType($idType)->convertToDatabaseValue($id); }
private function generateHydratorClass(ClassMetadata $class, $hydratorClassName, $fileName) { $code = ''; foreach ($class->fieldMappings as $fieldName => $mapping) { if (isset($mapping['alsoLoadFields'])) { foreach ($mapping['alsoLoadFields'] as $name) { $code .= sprintf(<<<EOF /** @AlsoLoad("$name") */ if (isset(\$data['$name'])) { \$data['$fieldName'] = \$data['$name']; } EOF ); } } if ( ! isset($mapping['association'])) { $code .= sprintf(<<<EOF /** @Field(type="{$mapping['type']}") */ if (isset(\$data['%1\$s'])) { \$value = \$data['%1\$s']; %3\$s \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; } EOF , $mapping['name'], $mapping['fieldName'], Type::getType($mapping['type'])->closureToPHP() ); } elseif ($mapping['association'] === ClassMetadata::REFERENCE_ONE) { $code .= sprintf(<<<EOF /** @ReferenceOne */ if (isset(\$data['%1\$s'])) { \$reference = \$data['%1\$s']; \$className = \$this->dm->getClassNameFromDiscriminatorValue(\$this->class->fieldMappings['%2\$s'], \$reference); \$targetMetadata = \$this->dm->getClassMetadata(\$className); \$id = \$targetMetadata->getPHPIdentifierValue(\$reference['\$id']); \$return = \$this->dm->getReference(\$className, \$id); \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; } EOF , $mapping['name'], $mapping['fieldName'] ); } elseif ($mapping['association'] === ClassMetadata::REFERENCE_MANY || $mapping['association'] === ClassMetadata::EMBED_MANY) { $code .= sprintf(<<<EOF /** @Many */ \$mongoData = isset(\$data['%1\$s']) ? \$data['%1\$s'] : null; \$return = new \Doctrine\ODM\MongoDB\PersistentCollection(new \Doctrine\Common\Collections\ArrayCollection(), \$this->dm, \$this->unitOfWork, '$'); \$return->setOwner(\$document, \$this->class->fieldMappings['%2\$s']); \$return->setInitialized(false); if (\$mongoData) { \$return->setMongoData(\$mongoData); } \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; EOF , $mapping['name'], $mapping['fieldName'] ); } elseif ($mapping['association'] === ClassMetadata::EMBED_ONE) { $code .= sprintf(<<<EOF /** @EmbedOne */ if (isset(\$data['%1\$s'])) { \$embeddedDocument = \$data['%1\$s']; \$className = \$this->dm->getClassNameFromDiscriminatorValue(\$this->class->fieldMappings['%2\$s'], \$embeddedDocument); \$embeddedMetadata = \$this->dm->getClassMetadata(\$className); \$return = \$embeddedMetadata->newInstance(); \$embeddedData = \$this->dm->getHydratorFactory()->hydrate(\$return, \$embeddedDocument); \$this->unitOfWork->registerManaged(\$return, null, \$embeddedData); \$this->unitOfWork->setParentAssociation(\$return, \$this->class->fieldMappings['%2\$s'], \$document, '%1\$s'); \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; } EOF , $mapping['name'], $mapping['fieldName'] ); } } $className = $class->name; $namespace = $this->hydratorNamespace; $code = sprintf(<<<EOF <?php namespace $namespace; use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; use Doctrine\ODM\MongoDB\Hydrator\HydratorInterface; use Doctrine\ODM\MongoDB\UnitOfWork; /** * THIS CLASS WAS GENERATED BY THE DOCTRINE ODM. DO NOT EDIT THIS FILE. */ class $hydratorClassName implements HydratorInterface { private \$dm; private \$unitOfWork; private \$class; public function __construct(DocumentManager \$dm, UnitOfWork \$uow, ClassMetadata \$class) { \$this->dm = \$dm; \$this->unitOfWork = \$uow; \$this->class = \$class; } public function hydrate(\$document, \$data) { \$hydratedData = array(); %s return \$hydratedData; } } EOF , $code ); file_put_contents($fileName, $code); }
/** * 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) { $rawValue = $this->_getFieldValue($mapping, $document, $data); if (!isset($rawValue)) { continue; } if (isset($mapping['embedded'])) { $embeddedMetadata = $this->_dm->getClassMetadata($mapping['targetDocument']); $embeddedDocument = $embeddedMetadata->newInstance(); if ($mapping['type'] === 'many') { $documents = new ArrayCollection(); foreach ($rawValue 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, $rawValue); $metadata->setFieldValue($document, $mapping['fieldName'], $value); } } elseif (isset($mapping['reference'])) { $targetMetadata = $this->_dm->getClassMetadata($mapping['targetDocument']); $targetDocument = $targetMetadata->newInstance(); if ($mapping['type'] === 'one' && isset($rawValue[$this->_cmd . 'id'])) { $id = $targetMetadata->getPHPIdentifierValue($rawValue[$this->_cmd . 'id']); $proxy = $this->_dm->getReference($mapping['targetDocument'], $id); $metadata->setFieldValue($document, $mapping['fieldName'], $proxy); } elseif ($mapping['type'] === 'many' && (is_array($rawValue) || $rawValue instanceof Collection)) { $documents = new PersistentCollection($this->_dm, $targetMetadata, new ArrayCollection()); $documents->setInitialized(false); foreach ($rawValue as $v) { $id = $targetMetadata->getPHPIdentifierValue($v[$this->_cmd . 'id']); $proxy = $this->_dm->getReference($mapping['targetDocument'], $id); $documents->add($proxy); } $metadata->setFieldValue($document, $mapping['fieldName'], $documents); } } else { $value = Type::getType($mapping['type'])->convertToPHPValue($rawValue); $metadata->setFieldValue($document, $mapping['fieldName'], $value); } if (isset($value)) { $values[$mapping['fieldName']] = $value; } } if (isset($data['_id'])) { $metadata->setIdentifierValue($document, $data['_id']); } return $values; }
/** * Hydrate array of MongoDB document data into the given document object. * * @param object $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($document, &$data) { $metadata = $this->dm->getClassMetadata(get_class($document)); if (isset($metadata->lifecycleCallbacks[Events::preLoad])) { $args = array(&$data); $metadata->invokeLifecycleCallbacks(Events::preLoad, $document, $args); } if ($this->evm->hasListeners(Events::preLoad)) { $this->evm->dispatchEvent(Events::preLoad, new PreLoadEventArgs($document, $this->dm, $data)); } if (isset($metadata->alsoLoadMethods)) { foreach ($metadata->alsoLoadMethods as $fieldName => $method) { if (isset($data[$fieldName])) { $document->$method($data[$fieldName]); } } } foreach ($metadata->fieldMappings as $mapping) { if (isset($mapping['alsoLoadFields'])) { $rawValue = null; $names = isset($mapping['alsoLoadFields']) ? $mapping['alsoLoadFields'] : array(); array_unshift($names, $mapping['name']); foreach ($names as $name) { if (isset($data[$name])) { $rawValue = $data[$name]; break; } } } else { $rawValue = isset($data[$mapping['name']]) ? $data[$mapping['name']] : null; } $value = null; if (isset($mapping['embedded'])) { $uow = $this->dm->getUnitOfWork(); if ($mapping['type'] === 'one') { if ($rawValue === null) { continue; } $embeddedDocument = $rawValue; $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $embeddedDocument); $embeddedMetadata = $this->dm->getClassMetadata($className); $value = $embeddedMetadata->newInstance(); // unset a potential discriminator map field (unless it's a persisted property) $discriminatorField = isset($mapping['discriminatorField']) ? $mapping['discriminatorField'] : '_doctrine_class_name'; if (!isset($embeddedMetadata->fieldMappings[$discriminatorField])) { unset($embeddedDocument[$discriminatorField]); } $this->hydrate($value, $embeddedDocument); $uow->registerManaged($value, null, $embeddedDocument); $uow->setParentAssociation($value, $mapping, $document, $mapping['name']); } elseif ($mapping['type'] === 'many') { $embeddedDocuments = $rawValue; $coll = new PersistentCollection(new ArrayCollection(), $this->dm, $this->dm->getConfiguration()); if ($embeddedDocuments) { foreach ($embeddedDocuments as $key => $embeddedDocument) { $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $embeddedDocument); $embeddedMetadata = $this->dm->getClassMetadata($className); $embeddedDocumentObject = $embeddedMetadata->newInstance(); // unset a potential discriminator map field (unless it's a persisted property) $discriminatorField = isset($mapping['discriminatorField']) ? $mapping['discriminatorField'] : '_doctrine_class_name'; if (!isset($embeddedMetadata->fieldMappings[$discriminatorField])) { unset($embeddedDocument[$discriminatorField]); } $this->hydrate($embeddedDocumentObject, $embeddedDocument); $uow->registerManaged($embeddedDocumentObject, null, $embeddedDocument); $uow->setParentAssociation($embeddedDocumentObject, $mapping, $document, $mapping['name'].'.'.$key); $coll->add($embeddedDocumentObject); } } $coll->setOwner($document, $mapping); $coll->takeSnapshot(); $value = $coll; } // Hydrate reference } elseif (isset($mapping['reference'])) { $reference = $rawValue; if ($mapping['type'] === 'one' && isset($reference[$this->cmd . 'id'])) { if ($reference === null) { continue; } $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $reference); $targetMetadata = $this->dm->getClassMetadata($className); $id = $targetMetadata->getPHPIdentifierValue($reference[$this->cmd . 'id']); $value = $this->dm->getReference($className, $id); } elseif ($mapping['type'] === 'many' && (is_array($reference) || $reference instanceof Collection)) { $references = $reference; $value = new PersistentCollection(new ArrayCollection(), $this->dm, $this->dm->getConfiguration()); $value->setInitialized(false); $value->setOwner($document, $mapping); // Delay any hydration of reference objects until the collection is // accessed and initialized for the first ime $value->setReferences($references); } // Hydrate regular field } else { $value = Type::getType($mapping['type'])->convertToPHPValue($rawValue); } unset($data[$mapping['name']]); // Set hydrated field value to document if ($value !== null) { $metadata->setFieldValue($document, $mapping['fieldName'], $value); $data[$mapping['fieldName']] = $value; } } // Set the document identifier if (isset($data['_id'])) { $metadata->setIdentifierValue($document, $data['_id']); $data[$metadata->identifier] = Type::getType($metadata->fieldMappings[$metadata->identifier]['type'])->convertToPHPValue($data['_id']); unset($data['_id']); } if (isset($metadata->lifecycleCallbacks[Events::postLoad])) { $metadata->invokeLifecycleCallbacks(Events::postLoad, $document); } if ($this->evm->hasListeners(Events::postLoad)) { $this->evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($document, $this->dm)); } return $document; }