/** * @param ClassMetadata $class * @param string $hydratorClassName * @param string $fileName */ 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 (!array_key_exists('%1\$s', \$data) && array_key_exists('{$name}', \$data)) { \$data['%1\$s'] = \$data['{$name}']; } EOF , $mapping['name']); } } 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->unitOfWork->getClassNameForAssociation(\$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->unitOfWork->getClassNameForAssociation(\$this->class->fieldMappings['%2\$s'], \$embeddedDocument); \$embeddedMetadata = \$this->dm->getClassMetadata(\$className); \$return = \$embeddedMetadata->newInstance(); \$this->unitOfWork->setParentAssociation(\$return, \$this->class->fieldMappings['%2\$s'], \$document, '%1\$s'); \$embeddedData = \$this->dm->getHydratorFactory()->hydrate(\$return, \$embeddedDocument, \$hints); \$embeddedId = \$embeddedMetadata->identifier && isset(\$embeddedData[\$embeddedMetadata->identifier]) ? \$embeddedData[\$embeddedMetadata->identifier] : null; \$this->unitOfWork->registerManaged(\$return, \$embeddedId, \$embeddedData); \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; } EOF , $mapping['name'], $mapping['fieldName']); } } $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); if ($fileName === false) { if (!class_exists($namespace . '\\' . $hydratorClassName)) { eval(substr($code, 5)); } } else { $parentDirectory = dirname($fileName); if (!is_dir($parentDirectory) && false === @mkdir($parentDirectory, 0775, true)) { throw HydratorException::hydratorDirectoryNotWritable(); } if (!is_writable($parentDirectory)) { throw HydratorException::hydratorDirectoryNotWritable(); } $tmpFileName = $fileName . '.' . uniqid('', true); file_put_contents($tmpFileName, $code); rename($tmpFileName, $fileName); chmod($fileName, 0664); } }
public function __construct(DocumentManager $dm, EventManager $evm, $hydratorDir, $hydratorNs, $autoGenerate, $cmd) { if ( ! $hydratorDir) { throw HydratorException::hydratorDirectoryRequired(); } if ( ! $hydratorNs) { throw HydratorException::hydratorNamespaceRequired(); } $this->dm = $dm; $this->evm = $evm; $this->hydratorDir = $hydratorDir; $this->hydratorNamespace = $hydratorNs; $this->autoGenerate = $autoGenerate; $this->cmd = $cmd; }