/**
  * Register custom doctrine types
  */
 public function __construct()
 {
     if (class_exists('\\Doctrine\\ODM\\MongoDB\\Types\\Type')) {
         \Doctrine\ODM\MongoDB\Types\Type::registerType(self::ODM_ENTITIES_TYPE, 'Akeneo\\Bundle\\StorageUtilsBundle\\Doctrine\\MongoDBODM\\Types\\Entities');
         \Doctrine\ODM\MongoDB\Types\Type::registerType(self::ODM_ENTITY_TYPE, 'Akeneo\\Bundle\\StorageUtilsBundle\\Doctrine\\MongoDBODM\\Types\\Entity');
     }
 }
 /**
  * Register cuctom doctrine types
  */
 public function __construct()
 {
     if (class_exists('\\Doctrine\\ODM\\MongoDB\\Types\\Type')) {
         \Doctrine\ODM\MongoDB\Types\Type::registerType(self::ODM_ENTITIES_TYPE, 'Pim\\Bundle\\CatalogBundle\\MongoDB\\Type\\Entities');
         \Doctrine\ODM\MongoDB\Types\Type::registerType(self::ODM_ENTITY_TYPE, 'Pim\\Bundle\\CatalogBundle\\MongoDB\\Type\\Entity');
     }
 }
예제 #3
0
 /**
  * @dataProvider convertToPHPValueProvider
  *
  * @param array  $ref     reference as from mongo
  * @param string $routeId name of route that should get loaded
  * @param string $url     url we expect to result from the conversion
  *
  * @return void
  */
 public function testConvertToPHPValue($ref, $routeId, $url)
 {
     $this->doubles['router']->expects($this->once())->method('generate')->with($this->equalTo($routeId), $this->equalTo(array('id' => $ref['$id'])))->will($this->returnValue($url));
     $sut = Type::getType('extref');
     $sut->setRouter($this->doubles['router']);
     $this->assertEquals($url, $sut->convertToPHPValue($ref));
 }
 public function installTypes()
 {
     foreach ($this->types as $type => $class) {
         if (!MongoDBType::hasType($type)) {
             MongoDBType::addType($type, $class);
         }
     }
 }
예제 #5
0
 /**
  * @param mixed|self $expression
  * @return mixed
  */
 protected function ensureArray($expression)
 {
     // Convert field names in expressions
     if (is_string($expression) && substr($expression, 0, 1) === '$') {
         return '$' . $this->getDocumentPersister()->prepareFieldName(substr($expression, 1));
     }
     // Convert PHP types to MongoDB types for everything else
     return Type::convertPHPToDatabaseValue(parent::ensureArray($expression));
 }
 /**
  * inject services into custom type
  *
  * @return void
  */
 public function boot()
 {
     /* @var $router Router */
     $router = $this->container->get('router');
     /* @var $type \Graviton\DocumentBundle\Types\ExtReference */
     $type = Type::getType('extref');
     $type->setRouter($router);
     $type->setMapping($this->container->getParameter('graviton.document.type.extref.mapping'));
 }
예제 #7
0
 /**
  * @dataProvider provideDatabaseToPHPValues
  */
 public function testClosureToPHP($input, $output)
 {
     $type = Type::getType(Type::DATE);
     $return = null;
     call_user_func(function ($value) use($type, &$return) {
         eval($type->closureToPHP());
     }, $input);
     $this->assertInstanceOf('DateTime', $return);
     $this->assertTimestampEquals($output, $return);
 }
예제 #8
0
파일: Module.php 프로젝트: vfulco/YAWIK
 /**
  * Sets up services on the bootstrap event.
  * 
  * @internal
  *     Creates the translation service and a ModuleRouteListener
  *      
  * @param MvcEvent $e
  */
 public function onBootstrap(MvcEvent $e)
 {
     // Register the TimezoneAwareDate type with DoctrineMongoODM
     // Use it in Annotions ( @Field(type="tz_date") )
     if (!DoctrineType::hasType('tz_date')) {
         DoctrineType::addType('tz_date', '\\Core\\Repository\\DoctrineMongoODM\\Types\\TimezoneAwareDate');
     }
     $sm = $e->getApplication()->getServiceManager();
     $translator = $sm->get('translator');
     // initialise translator!
     \Zend\Validator\AbstractValidator::setDefaultTranslator($translator);
     $eventManager = $e->getApplication()->getEventManager();
     $sharedManager = $eventManager->getSharedManager();
     #       $LogListener = new LogListener();
     #       $LogListener->attach($eventManager);
     if (!\Zend\Console\Console::isConsole()) {
         $redirectCallback = function () use($e) {
             $routeMatch = $e->getRouteMatch();
             $lang = $routeMatch ? $routeMatch->getParam('lang', 'en') : 'en';
             $uri = $e->getRouter()->getBaseUrl() . '/' . $lang . '/error';
             header('Location: ' . $uri);
         };
         $errorHandlerListener = new ErrorHandlerListener($sm->get('ErrorLogger'), $redirectCallback);
         $errorHandlerListener->attach($eventManager);
         $languageRouteListener = new LanguageRouteListener();
         $languageRouteListener->attach($eventManager);
         $ajaxRenderListener = new AjaxRenderListener();
         $ajaxRenderListener->attach($eventManager);
         $enforceJsonResponseListener = new EnforceJsonResponseListener();
         $enforceJsonResponseListener->attach($eventManager);
         $stringListener = new StringListener();
         $stringListener->attach($eventManager);
         //
         $notificationlistener = $sm->get('Core/Listener/Notification');
         $notificationlistener->attachShared($sharedManager);
         $notificationAjaxHandler = new NotificationAjaxHandler();
         $eventManager->attach(MvcEvent::EVENT_DISPATCH, array($notificationAjaxHandler, 'injectView'), -20);
         $notificationlistener->attach(NotificationEvent::EVENT_NOTIFICATION_HTML, array($notificationAjaxHandler, 'render'), -20);
     }
     $persistenceListener = new PersistenceListener();
     $persistenceListener->attach($eventManager);
     $eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, function ($event) {
         $application = $event->getApplication();
         if ($application::ERROR_EXCEPTION == $event->getError()) {
             $ex = $event->getParam('exception');
             if (404 == $ex->getCode()) {
                 $event->setError($application::ERROR_CONTROLLER_NOT_FOUND);
             }
         }
     }, 500);
     $eventManager->attach(MvcEvent::EVENT_DISPATCH, function ($event) use($eventManager) {
         $eventManager->trigger('postDispatch', $event);
     }, -150);
 }
예제 #9
0
 /**
  * @param ClassMetadata $classMetadata
  */
 protected function checkCoordinateType(ClassMetadata $classMetadata)
 {
     foreach ($classMetadata->fieldMappings as $fieldName => $mapping) {
         if (isset($mapping['cubiche:coordinate'])) {
             $type = 'Coordinate';
             if (!Type::hasType($type)) {
                 Type::registerType($type, CoordinateType::class);
             }
             $classMetadata->fieldMappings[$fieldName]['type'] = $type;
         }
     }
 }
예제 #10
0
 public function convertToPHPValue($value)
 {
     if ($value === null) {
         return null;
     }
     if (!is_array($value)) {
         throw new CustomTypeException('Array expected.');
     }
     $converter = Type::getType('date');
     $value = array_map(function ($date) use($converter) {
         return $converter->convertToPHPValue($date);
     }, array_values($value));
     return $value;
 }
예제 #11
0
 /**
  * @param ClassMetadata $classMetadata
  *
  * @throws MappingException
  */
 protected function checkIdType(ClassMetadata $classMetadata)
 {
     foreach ($classMetadata->fieldMappings as $fieldName => $mapping) {
         if (isset($mapping['cubiche:id'])) {
             $idMapping = $mapping['cubiche:id'];
             $type = str_replace('\\', '.', $idMapping['type']);
             if (!Type::hasType($type)) {
                 Type::registerType($type, DynamicIdType::class);
                 Type::getType($type)->setTargetClass($idMapping['type']);
             }
             $classMetadata->fieldMappings[$fieldName]['type'] = $type;
         }
     }
 }
예제 #12
0
 /**
  * {@inheritdoc}
  */
 public function convertToPHPValue($value)
 {
     if ($value === null) {
         return new ArrayList();
     }
     if (is_array($value) || $value instanceof \Traversable) {
         $items = array();
         $type = Type::getType($this->innerType);
         foreach ($value as $item) {
             $items[] = $type->convertToPHPValue($item);
         }
         return new ArrayList($items);
     }
     return parent::convertToPHPValue($value);
 }
 public function testCreation()
 {
     $logger = $this->getMockForAbstractClass('DoctrineMongoODMModule\\Logging\\Logger');
     $metadataCache = $this->getMockForAbstractClass('Doctrine\\Common\\Cache\\Cache');
     $mappingDriver = $this->getMockForAbstractClass('Doctrine\\Common\\Persistence\\Mapping\\Driver\\MappingDriver');
     $serviceLocator = $this->getMockForAbstractClass('Zend\\ServiceManager\\ServiceLocatorInterface');
     $serviceLocator->expects($this->exactly(4))->method('get')->withConsecutive(array('Configuration'), array('stubbed_logger'), array('doctrine.cache.stubbed_metadatacache'), array('doctrine.driver.stubbed_driver'))->willReturnOnConsecutiveCalls(array('doctrine' => array('configuration' => array('odm_test' => array('logger' => 'stubbed_logger', 'metadata_cache' => 'stubbed_metadatacache', 'driver' => 'stubbed_driver', 'generate_proxies' => true, 'proxy_dir' => 'data/DoctrineMongoODMModule/Proxy', 'proxy_namespace' => 'DoctrineMongoODMModule\\Proxy', 'generate_hydrators' => true, 'hydrator_dir' => 'data/DoctrineMongoODMModule/Hydrator', 'hydrator_namespace' => 'DoctrineMongoODMModule\\Hydrator', 'default_db' => 'default_db', 'filters' => array(), 'types' => array('CustomType' => 'DoctrineMongoODMModuleTest\\Assets\\CustomType'), 'classMetadataFactoryName' => 'stdClass')))), $logger, $metadataCache, $mappingDriver);
     $factory = new ConfigurationFactory('odm_test');
     $config = $factory->createService($serviceLocator);
     $this->assertInstanceOf('Doctrine\\ODM\\MongoDB\\Configuration', $config);
     $this->assertNotNull($config->getLoggerCallable());
     $this->assertSame($metadataCache, $config->getMetadataCacheImpl());
     $this->assertSame($mappingDriver, $config->getMetadataDriverImpl());
     $this->assertInstanceOf('DoctrineMongoODMModuleTest\\Assets\\CustomType', \Doctrine\ODM\MongoDB\Types\Type::getType('CustomType'));
 }
예제 #14
0
 /**
  * @param ClassMetadata $classMetadata
  */
 protected function checkTypes(ClassMetadata $classMetadata)
 {
     $types = array_keys($this->typeMapping);
     foreach ($classMetadata->fieldMappings as $fieldName => $mapping) {
         foreach ($types as $type) {
             if (isset($mapping['cubiche:' . $type])) {
                 $typeName = substr($this->typeMapping[$type], strrpos($this->typeMapping[$type], '\\') + 1);
                 if (!Type::hasType($typeName)) {
                     Type::registerType($typeName, $this->typeMapping[$type]);
                 }
                 $classMetadata->fieldMappings[$fieldName]['type'] = $typeName;
                 break;
             }
         }
     }
 }
 /**
  * @return \Doctrine\ODM\MongoDB\DocumentManager
  */
 public function dm()
 {
     if ($this->dm === null) {
         $this->dm = $this->createTestDocumentManager();
         $this->uow = $this->dm->getUnitOfWork();
         Type::addType('Phonenumber', PhonenumberType::class);
         Type::addType('Role', RoleType::class);
         $this->dm->getEventManager()->addEventSubscriber(new MetadataEventSubscriber());
         $this->dm->getEventManager()->addEventSubscriber(new CollectionsEventSubscriber());
         $this->dm->getEventManager()->addEventSubscriber(new ModelEventSubscriber());
         $this->dm->getEventManager()->addEventSubscriber(new IdentityEventSubscriber());
         $this->dm->getEventManager()->addEventSubscriber(new GeolocationEventSubscriber());
         $this->dm->getEventManager()->addEventSubscriber(new SystemEventSubscriber());
     }
     return $this->dm;
 }
예제 #16
0
 public function setUp()
 {
     Type::hasType('object') ? Type::overrideType('object', 'Payum\\Core\\Bridge\\Doctrine\\Types\\ObjectType') : Type::addType('object', 'Payum\\Core\\Bridge\\Doctrine\\Types\\ObjectType');
     $config = new Configuration();
     $config->setProxyDir(\sys_get_temp_dir());
     $config->setProxyNamespace('PayumTestsProxies');
     $config->setHydratorDir(\sys_get_temp_dir());
     $config->setHydratorNamespace('PayumTestsHydrators');
     $config->setMetadataDriverImpl($this->getMetadataDriverImpl($config));
     $config->setMetadataCacheImpl(new ArrayCache());
     $config->setDefaultDB('payum_tests');
     $connection = new Connection(null, array(), $config);
     $this->dm = DocumentManager::create($connection, $config);
     foreach ($this->dm->getConnection()->selectDatabase('payum_tests')->listCollections() as $collection) {
         $collection->drop();
     }
 }
 /**
  * @param \Zend\ServiceManager\ServiceLocatorInterface $serviceLocator
  * @return \Doctrine\ODM\MongoDB\Configuration
  * @throws \Exception
  */
 public function createService(ServiceLocatorInterface $serviceLocator)
 {
     /** @var $options \DoctrineMongoODMModule\Options\Configuration */
     $options = $this->getOptions($serviceLocator, 'configuration');
     $config = new Configuration();
     // logger
     if ($options->getLogger()) {
         $logger = $serviceLocator->get($options->getLogger());
         $config->setLoggerCallable(array($logger, 'log'));
     }
     // proxies
     $config->setAutoGenerateProxyClasses($options->getGenerateProxies());
     $config->setProxyDir($options->getProxyDir());
     $config->setProxyNamespace($options->getProxyNamespace());
     // hydrators
     $config->setAutoGenerateHydratorClasses($options->getGenerateHydrators());
     $config->setHydratorDir($options->getHydratorDir());
     $config->setHydratorNamespace($options->getHydratorNamespace());
     // default db
     $config->setDefaultDB($options->getDefaultDb());
     // caching
     $config->setMetadataCacheImpl($serviceLocator->get($options->getMetadataCache()));
     // retries
     $config->setRetryConnect($options->getRetryConnect());
     $config->setRetryQuery($options->getRetryQuery());
     // Register filters
     foreach ($options->getFilters() as $alias => $class) {
         $config->addFilter($alias, $class);
     }
     // the driver
     $config->setMetadataDriverImpl($serviceLocator->get($options->getDriver()));
     // metadataFactory, if set
     if ($factoryName = $options->getClassMetadataFactoryName()) {
         $config->setClassMetadataFactoryName($factoryName);
     }
     // custom types
     foreach ($options->getTypes() as $name => $class) {
         if (Type::hasType($name)) {
             Type::overrideType($name, $class);
         } else {
             Type::addType($name, $class);
         }
     }
     return $config;
 }
예제 #18
0
 public function setUp()
 {
     $this->skipTestsIfPhp7();
     if (false == (class_exists(\MongoId::class) && class_exists(Connection::class))) {
         $this->markTestSkipped('Either mongo extension or\\and doctrine\\mongo-odm are not installed.');
     }
     Type::hasType('object') ? Type::overrideType('object', 'Payum\\Core\\Bridge\\Doctrine\\Types\\ObjectType') : Type::addType('object', 'Payum\\Core\\Bridge\\Doctrine\\Types\\ObjectType');
     $config = new Configuration();
     $config->setProxyDir(\sys_get_temp_dir());
     $config->setProxyNamespace('PayumTestsProxies');
     $config->setHydratorDir(\sys_get_temp_dir());
     $config->setHydratorNamespace('PayumTestsHydrators');
     $config->setMetadataDriverImpl($this->getMetadataDriverImpl($config));
     $config->setMetadataCacheImpl(new ArrayCache());
     $config->setDefaultDB('payum_tests');
     $connection = new Connection(null, array(), $config);
     $this->dm = DocumentManager::create($connection, $config);
     foreach ($this->dm->getConnection()->selectDatabase('payum_tests')->listCollections() as $collection) {
         $collection->drop();
     }
 }
예제 #19
0
 public function bootstrapDoctrine(MvcEvent $event)
 {
     $serviceManager = $event->getApplication()->getServiceManager();
     /** @var Options\ModuleOptions $moduleOptions */
     $moduleOptions = $serviceManager->get(__NAMESPACE__ . '\\Options\\ModuleOptions');
     if ($moduleOptions->getDoctrine()->registerUuidType()) {
         if (!class_exists('Rhumsaa\\Uuid\\Uuid')) {
             throw new Exception\RuntimeException('Failed to register "uuid" Doctrine mapping type: ' . 'Missing required class Rhumsaa\\Uuid\\Uuid');
         }
         if (class_exists(DoctrineOrmTypes\Type::CLASS)) {
             DoctrineOrmTypes\Type::addType(DoctrineUuidType::NAME, DoctrineUuidType::CLASS);
         }
         if (class_exists(DoctrineOdmTypes\Type::CLASS)) {
             DoctrineOdmTypes\Type::registerType(DoctrineOdmUuidType::NAME, DoctrineOdmUuidType::CLASS);
         }
     }
     if ($moduleOptions->getDoctrine()->registerDatetimeImmutableType()) {
         if (class_exists(DoctrineOdmTypes\Type::CLASS)) {
             DoctrineOdmTypes\Type::registerType(DoctrineOdmDateTimeImmutType::NAME, DoctrineOdmDateTimeImmutType::CLASS);
         }
     }
     if ($moduleOptions->getDoctrine()->registerDatetimeNoTzType()) {
         if (class_exists(DoctrineOdmTypes\Type::CLASS)) {
             DoctrineOdmTypes\Type::registerType(DoctrineOdmDateTimeNoTzType::NAME, DoctrineOdmDateTimeNoTzType::CLASS);
         }
     }
     if ($moduleOptions->getDoctrine()->registerDatetimeImmutableNoTzType()) {
         if (class_exists(DoctrineOdmTypes\Type::CLASS)) {
             DoctrineOdmTypes\Type::registerType(DoctrineOdmDateTimeImmutNoTzType::NAME, DoctrineOdmDateTimeImmutNoTzType::CLASS);
         }
     }
     //        /** @var \Zend\ServiceManager\ServiceManager $serviceManager */
     //        $serviceManager = $event->getApplication()->getServiceManager();
     //
     //        /** @var \Doctrine\ORM\EntityManager $entityManager */
     //        $entityManager = $serviceManager->get('Doctrine\ORM\EntityManager');
     //        $entityManager->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('db_mytype', 'mytype');
 }
예제 #20
0
 /**
  * {@inheritDoc}
  */
 public function createStorage($modelClass, $idProperty, array $options)
 {
     if (false == Type::hasType('object')) {
         Type::addType('object', 'Payum\\Core\\Bridge\\Doctrine\\Types\\ObjectType');
     }
     $driver = new MappingDriverChain();
     // payum's basic models
     $coreRootDir = dirname((new \ReflectionClass(GatewayInterface::class))->getFileName());
     $driver->addDriver(new XmlDriver(new SymfonyFileLocator(array($coreRootDir . '/Bridge/Doctrine/Resources/mapping' => 'Payum\\Core\\Model'), '.mongodb.xml'), '.mongodb.xml'), 'Payum\\Core\\Model');
     // your models
     $sererRootDir = dirname((new \ReflectionClass(Application::class))->getFileName());
     AnnotationDriver::registerAnnotationClasses();
     $driver->addDriver(new AnnotationDriver(new AnnotationReader(), array($sererRootDir . '/Model')), 'Payum\\Server\\Model');
     $config = new Configuration();
     $config->setProxyDir(\sys_get_temp_dir() . '/PayumServer');
     $config->setProxyNamespace('Proxies');
     $config->setHydratorDir(\sys_get_temp_dir() . '/PayumServer');
     $config->setHydratorNamespace('Hydrators');
     $config->setMetadataDriverImpl($driver);
     $config->setMetadataCacheImpl(new ArrayCache());
     $config->setDefaultDB($options['databaseName']);
     $connection = new Connection($options['host'], array(), $config);
     return new DoctrineStorage(DocumentManager::create($connection, $config), $modelClass);
 }
예제 #21
0
    /**
     * @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);
        }
    }
예제 #22
0
 public function testClosureToPHP()
 {
     $type = Type::getType('dough_money');
     $this->assertSame('$return = new \\Dough\\Money\\Money($value);', $type->closureToPHP());
 }
예제 #23
0
 /**
  * Used to do the common work of computeChangeSet and recomputeSingleDocumentChangeSet
  *
  * @param \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $class
  * @param object $document
  * @param boolean $recompute
  */
 private function computeOrRecomputeChangeSet(ClassMetadata $class, $document, $recompute = false)
 {
     $oid = spl_object_hash($document);
     $actualData = $this->getDocumentActualData($document);
     $isNewDocument = !isset($this->originalDocumentData[$oid]);
     if ($isNewDocument) {
         // Document is either NEW or MANAGED but not yet fully persisted (only has an id).
         // These result in an INSERT.
         $this->originalDocumentData[$oid] = $actualData;
         $changeSet = array();
         foreach ($actualData as $propName => $actualValue) {
             /* At this PersistentCollection shouldn't be here, probably it
              * was cloned and its ownership must be fixed
              */
             if ($actualValue instanceof PersistentCollection && $actualValue->getOwner() !== $document) {
                 $actualData[$propName] = $this->fixPersistentCollectionOwnership($actualValue, $document, $class, $propName);
                 $actualValue = $actualData[$propName];
             }
             $changeSet[$propName] = array(null, $actualValue);
         }
         $this->documentChangeSets[$oid] = $changeSet;
     } else {
         // Document is "fully" MANAGED: it was already fully persisted before
         // and we have a copy of the original data
         $originalData = $this->originalDocumentData[$oid];
         $isChangeTrackingNotify = $class->isChangeTrackingNotify();
         if ($isChangeTrackingNotify && !$recompute) {
             $changeSet = $this->documentChangeSets[$oid];
         } else {
             $changeSet = array();
         }
         foreach ($actualData as $propName => $actualValue) {
             // skip not saved fields
             if (isset($class->fieldMappings[$propName]['notSaved']) && $class->fieldMappings[$propName]['notSaved'] === true) {
                 continue;
             }
             $orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null;
             // skip if value has not changed
             if ($orgValue === $actualValue) {
                 // but consider dirty GridFSFile instances as changed
                 if (!(isset($class->fieldMappings[$propName]['file']) && $actualValue->isDirty())) {
                     continue;
                 }
             }
             // if relationship is a embed-one, schedule orphan removal to trigger cascade remove operations
             if (isset($class->fieldMappings[$propName]['embedded']) && $class->fieldMappings[$propName]['type'] === 'one') {
                 if ($orgValue !== null) {
                     $this->scheduleOrphanRemoval($orgValue);
                 }
                 $changeSet[$propName] = array($orgValue, $actualValue);
                 continue;
             }
             // if owning side of reference-one relationship
             if (isset($class->fieldMappings[$propName]['reference']) && $class->fieldMappings[$propName]['type'] === 'one' && $class->fieldMappings[$propName]['isOwningSide']) {
                 if ($orgValue !== null && $class->fieldMappings[$propName]['orphanRemoval']) {
                     $this->scheduleOrphanRemoval($orgValue);
                 }
                 $changeSet[$propName] = array($orgValue, $actualValue);
                 continue;
             }
             if ($isChangeTrackingNotify) {
                 continue;
             }
             // ignore inverse side of reference-many relationship
             if (isset($class->fieldMappings[$propName]['reference']) && $class->fieldMappings[$propName]['type'] === 'many' && $class->fieldMappings[$propName]['isInverseSide']) {
                 continue;
             }
             // Persistent collection was exchanged with the "originally"
             // created one. This can only mean it was cloned and replaced
             // on another document.
             if ($actualValue instanceof PersistentCollection && $actualValue->getOwner() !== $document) {
                 $this->fixPersistentCollectionOwnership($actualValue, $document, $class, $propName);
             }
             // if embed-many or reference-many relationship
             if (isset($class->fieldMappings[$propName]['type']) && $class->fieldMappings[$propName]['type'] === 'many') {
                 $changeSet[$propName] = array($orgValue, $actualValue);
                 /* If original collection was exchanged with a non-empty value
                  * and $set will be issued, there is no need to $unset it first
                  */
                 if ($actualValue && $actualValue->isDirty() && CollectionHelper::usesSet($class->fieldMappings[$propName]['strategy'])) {
                     continue;
                 }
                 if ($orgValue instanceof PersistentCollection) {
                     $this->scheduleCollectionDeletion($orgValue);
                 }
                 continue;
             }
             // skip equivalent date values
             if (isset($class->fieldMappings[$propName]['type']) && $class->fieldMappings[$propName]['type'] === 'date') {
                 $dateType = Type::getType('date');
                 $dbOrgValue = $dateType->convertToDatabaseValue($orgValue);
                 $dbActualValue = $dateType->convertToDatabaseValue($actualValue);
                 if ($dbOrgValue instanceof \MongoDate && $dbActualValue instanceof \MongoDate && $dbOrgValue == $dbActualValue) {
                     continue;
                 }
             }
             // regular field
             $changeSet[$propName] = array($orgValue, $actualValue);
         }
         if ($changeSet) {
             $this->documentChangeSets[$oid] = $recompute && isset($this->documentChangeSets[$oid]) ? $changeSet + $this->documentChangeSets[$oid] : $changeSet;
             $this->originalDocumentData[$oid] = $actualData;
             $this->scheduleForUpdate($document);
         }
     }
     // Look for changes in associations of the document
     $associationMappings = array_filter($class->associationMappings, function ($assoc) {
         return empty($assoc['notSaved']);
     });
     foreach ($associationMappings as $mapping) {
         $value = $class->reflFields[$mapping['fieldName']]->getValue($document);
         if ($value === null) {
             continue;
         }
         $this->computeAssociationChanges($document, $mapping, $value);
         if (isset($mapping['reference'])) {
             continue;
         }
         $values = $mapping['type'] === ClassMetadata::ONE ? array($value) : $value->unwrap();
         foreach ($values as $obj) {
             $oid2 = spl_object_hash($obj);
             if (isset($this->documentChangeSets[$oid2])) {
                 $this->documentChangeSets[$oid][$mapping['fieldName']] = array($value, $value);
                 if (!$isNewDocument) {
                     $this->scheduleForUpdate($document);
                 }
                 break;
             }
         }
     }
 }
예제 #24
0
 private function generateDocumentStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null, $defaultValue = null)
 {
     // Add/remove methods should use the singular form of the field name
     $formattedFieldName = in_array($type, array('add', 'remove')) ? Inflector::singularize($fieldName) : $fieldName;
     $methodName = $type . Inflector::classify($formattedFieldName);
     $variableName = Inflector::camelize($formattedFieldName);
     if ($this->hasMethod($methodName, $metadata)) {
         return;
     }
     $description = ucfirst($type) . ' ' . $variableName;
     $types = Type::getTypesMap();
     $methodTypeHint = $typeHint && !isset($types[$typeHint]) ? '\\' . $typeHint . ' ' : null;
     $variableType = $typeHint ? $typeHint . ' ' : null;
     $replacements = array('<description>' => $description, '<methodTypeHint>' => $methodTypeHint, '<variableType>' => $variableType, '<variableName>' => $variableName, '<methodName>' => $methodName, '<fieldName>' => $fieldName, '<variableDefault>' => $defaultValue !== null ? ' = ' . $defaultValue : '');
     $templateVar = sprintf('%sMethodTemplate', $type);
     $method = str_replace(array_keys($replacements), array_values($replacements), self::${$templateVar});
     return $this->prefixCodeWithSpaces($method);
 }
예제 #25
0
 public function test64bit1900Date()
 {
     if (PHP_INT_SIZE === 8) {
         $type = Type::getType(Type::DATE);
         $return = $type->convertToDatabaseValue('1900-01-01');
         $this->assertInstanceOf('MongoDate', $return);
         $this->assertEquals(new \MongoDate(strtotime('1900-01-01')), $return);
     } else {
         $this->markTestSkipped("Platform is not 64-bit");
     }
 }
예제 #26
0
 /**
  * setup type we want to test
  *
  * @return void
  */
 public function setUp()
 {
     Type::registerType('extref', ExtReferenceType::class);
     $this->type = Type::getType('extref');
 }
 /**
  * Casts the identifier to its database type.
  *
  * @param mixed $id
  * @return mixed $id
  */
 public function getDatabaseIdentifierValue($id)
 {
     $idType = $this->fieldMappings[$this->identifier]['type'];
     return Type::getType($idType)->convertToDatabaseValue($id);
 }
예제 #28
0
 /**
  * Returns the embedded document to be stored in MongoDB.
  *
  * The return value will usually be an associative array with string keys
  * corresponding to field names on the embedded document. An object may be
  * returned if the document is empty, to ensure that a BSON object will be
  * stored in lieu of an array.
  *
  * If $includeNestedCollections is true, nested collections will be included
  * in this prepared value and the option will cascade to all embedded
  * associations. If any nested PersistentCollections (embed or reference)
  * within this value were previously scheduled for deletion or update, they
  * will also be unscheduled.
  *
  * @param array $embeddedMapping
  * @param object $embeddedDocument
  * @param boolean $includeNestedCollections
  * @return array|object
  * @throws \UnexpectedValueException if an unsupported associating mapping is found
  */
 public function prepareEmbeddedDocumentValue(array $embeddedMapping, $embeddedDocument, $includeNestedCollections = false)
 {
     $embeddedDocumentValue = array();
     $class = $this->dm->getClassMetadata(get_class($embeddedDocument));
     foreach ($class->fieldMappings as $mapping) {
         // Skip notSaved fields
         if (!empty($mapping['notSaved'])) {
             continue;
         }
         // Inline ClassMetadataInfo::getFieldValue()
         $rawValue = $class->reflFields[$mapping['fieldName']]->getValue($embeddedDocument);
         $value = null;
         if ($rawValue !== null) {
             switch (isset($mapping['association']) ? $mapping['association'] : null) {
                 // @Field, @String, @Date, etc.
                 case null:
                     $value = Type::getType($mapping['type'])->convertToDatabaseValue($rawValue);
                     break;
                 case ClassMetadata::EMBED_ONE:
                 case ClassMetadata::REFERENCE_ONE:
                     // Nested collections should only be included for embedded relationships
                     $value = $this->prepareAssociatedDocumentValue($mapping, $rawValue, $includeNestedCollections && isset($mapping['embedded']));
                     break;
                 case ClassMetadata::EMBED_MANY:
                 case ClassMetadata::REFERENCE_MANY:
                     // Skip PersistentCollections already scheduled for deletion
                     if (!$includeNestedCollections && $rawValue instanceof PersistentCollection && $this->uow->isCollectionScheduledForDeletion($rawValue)) {
                         break;
                     }
                     // We're handling atomicSet or atomicSetArray collection
                     if ($includeNestedCollections && $rawValue instanceof PersistentCollection) {
                         $this->uow->unscheduleCollectionDeletion($rawValue);
                         $this->uow->unscheduleCollectionUpdate($rawValue);
                     }
                     $pb = $this;
                     $value = $rawValue->map(function ($v) use($pb, $mapping, $includeNestedCollections) {
                         // Nested collections should only be included for embedded relationships
                         return $pb->prepareAssociatedDocumentValue($mapping, $v, $includeNestedCollections && isset($mapping['embedded']));
                     })->toArray();
                     // Numerical reindexing may be necessary to ensure BSON array storage
                     if (in_array($mapping['strategy'], array('atomicSetArray', 'setArray', 'pushAll', 'addToSet'))) {
                         $value = array_values($value);
                     }
                     break;
                 default:
                     throw new \UnexpectedValueException('Unsupported mapping association: ' . $mapping['association']);
             }
         }
         // Omit non-nullable fields that would have a null value
         if ($value === null && $mapping['nullable'] === false) {
             continue;
         }
         $embeddedDocumentValue[$mapping['name']] = $value;
     }
     /* Add a discriminator value if the embedded document is not mapped
      * explicitly to a targetDocument class.
      */
     if (!isset($embeddedMapping['targetDocument'])) {
         $discriminatorField = $embeddedMapping['discriminatorField'];
         $discriminatorValue = isset($embeddedMapping['discriminatorMap']) ? array_search($class->name, $embeddedMapping['discriminatorMap']) : $class->name;
         /* If the discriminator value was not found in the map, use the full
          * class name. In the future, it may be preferable to throw an
          * exception here (perhaps based on some strictness option).
          *
          * @see DocumentManager::createDBRef()
          */
         if ($discriminatorValue === false) {
             $discriminatorValue = $class->name;
         }
         $embeddedDocumentValue[$discriminatorField] = $discriminatorValue;
     }
     /* If the class has a discriminator (field and value), use it. A child
      * class that is not defined in the discriminator map may only have a
      * discriminator field and no value, so default to the full class name.
      */
     if (isset($class->discriminatorField)) {
         $embeddedDocumentValue[$class->discriminatorField] = isset($class->discriminatorValue) ? $class->discriminatorValue : $class->name;
     }
     // Ensure empty embedded documents are stored as BSON objects
     if (empty($embeddedDocumentValue)) {
         return (object) $embeddedDocumentValue;
     }
     /* @todo Consider always casting the return value to an object, or
      * building $embeddedDocumentValue as an object instead of an array, to
      * handle the edge case where all database field names are sequential,
      * numeric keys.
      */
     return $embeddedDocumentValue;
 }
예제 #29
0
 /**
  * Prepares the query criteria or new document object.
  *
  * PHP field names and types will be converted to those used by MongoDB.
  *
  * @param array $query
  * @return array
  */
 public function prepareQueryOrNewObj(array $query)
 {
     $preparedQuery = array();
     foreach ($query as $key => $value) {
         // Recursively prepare logical query clauses
         if (in_array($key, array('$and', '$or', '$nor')) && is_array($value)) {
             foreach ($value as $k2 => $v2) {
                 $preparedQuery[$key][$k2] = $this->prepareQueryOrNewObj($v2);
             }
             continue;
         }
         if (isset($key[0]) && $key[0] === '$' && is_array($value)) {
             $preparedQuery[$key] = $this->prepareQueryOrNewObj($value);
             continue;
         }
         list($key, $value) = $this->prepareQueryElement($key, $value, null, true);
         $preparedQuery[$key] = is_array($value) ? array_map('\\Doctrine\\ODM\\MongoDB\\Types\\Type::convertPHPToDatabaseValue', $value) : Type::convertPHPToDatabaseValue($value);
     }
     return $preparedQuery;
 }
예제 #30
0
 /**
  * Used to do the common work of computeChangeSet and recomputeSingleDocumentChangeSet
  *
  * @param \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $class
  * @param object $document
  * @param boolean $recompute
  */
 private function computeOrRecomputeChangeSet(ClassMetadata $class, $document, $recompute = false)
 {
     $oid = spl_object_hash($document);
     $actualData = $this->getDocumentActualData($document);
     $isNewDocument = !isset($this->originalDocumentData[$oid]);
     if ($isNewDocument) {
         // Document is either NEW or MANAGED but not yet fully persisted (only has an id).
         // These result in an INSERT.
         $this->originalDocumentData[$oid] = $actualData;
         $changeSet = array();
         foreach ($actualData as $propName => $actualValue) {
             $changeSet[$propName] = array(null, $actualValue);
         }
         $this->documentChangeSets[$oid] = $changeSet;
     } else {
         // Document is "fully" MANAGED: it was already fully persisted before
         // and we have a copy of the original data
         $originalData = $this->originalDocumentData[$oid];
         $isChangeTrackingNotify = $class->isChangeTrackingNotify();
         if ($isChangeTrackingNotify && !$recompute) {
             $changeSet = $this->documentChangeSets[$oid];
         } else {
             $changeSet = array();
         }
         foreach ($actualData as $propName => $actualValue) {
             // skip not saved fields
             if (isset($class->fieldMappings[$propName]['notSaved']) && $class->fieldMappings[$propName]['notSaved'] === true) {
                 continue;
             }
             $orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null;
             // skip if value has not changed
             if ($orgValue === $actualValue) {
                 // but consider dirty GridFSFile instances as changed
                 if (!(isset($class->fieldMappings[$propName]['file']) && $actualValue->isDirty())) {
                     continue;
                 }
             }
             // if relationship is a embed-one, schedule orphan removal to trigger cascade remove operations
             if (isset($class->fieldMappings[$propName]['embedded']) && $class->fieldMappings[$propName]['type'] === 'one') {
                 if ($orgValue !== null) {
                     $this->scheduleOrphanRemoval($orgValue);
                 }
                 $changeSet[$propName] = array($orgValue, $actualValue);
                 continue;
             }
             // if owning side of reference-one relationship
             if (isset($class->fieldMappings[$propName]['reference']) && $class->fieldMappings[$propName]['type'] === 'one' && $class->fieldMappings[$propName]['isOwningSide']) {
                 if ($orgValue !== null && $class->fieldMappings[$propName]['orphanRemoval']) {
                     $this->scheduleOrphanRemoval($orgValue);
                 }
                 $changeSet[$propName] = array($orgValue, $actualValue);
                 continue;
             }
             if ($isChangeTrackingNotify) {
                 continue;
             }
             // ignore inverse side of reference-many relationship
             if (isset($class->fieldMappings[$propName]['reference']) && $class->fieldMappings[$propName]['type'] === 'many' && $class->fieldMappings[$propName]['isInverseSide']) {
                 continue;
             }
             // Persistent collection was exchanged with the "originally"
             // created one. This can only mean it was cloned and replaced
             // on another document.
             if ($actualValue instanceof PersistentCollection) {
                 $owner = $actualValue->getOwner();
                 if ($owner === null) {
                     // cloned
                     $actualValue->setOwner($document, $class->fieldMappings[$propName]);
                 } elseif ($owner !== $document) {
                     // no clone, we have to fix
                     if (!$actualValue->isInitialized()) {
                         $actualValue->initialize();
                         // we have to do this otherwise the cols share state
                     }
                     $newValue = clone $actualValue;
                     $newValue->setOwner($document, $class->fieldMappings[$propName]);
                     $class->reflFields[$propName]->setValue($document, $newValue);
                 }
             }
             // if embed-many or reference-many relationship
             if (isset($class->fieldMappings[$propName]['type']) && $class->fieldMappings[$propName]['type'] === 'many') {
                 $changeSet[$propName] = array($orgValue, $actualValue);
                 if ($orgValue instanceof PersistentCollection) {
                     $this->scheduleCollectionDeletion($orgValue);
                 }
                 continue;
             }
             // skip equivalent date values
             if (isset($class->fieldMappings[$propName]['type']) && $class->fieldMappings[$propName]['type'] === 'date') {
                 $dateType = Type::getType('date');
                 $dbOrgValue = $dateType->convertToDatabaseValue($orgValue);
                 $dbActualValue = $dateType->convertToDatabaseValue($actualValue);
                 if ($dbOrgValue instanceof \MongoDate && $dbActualValue instanceof \MongoDate && $dbOrgValue == $dbActualValue) {
                     continue;
                 }
             }
             // regular field
             $changeSet[$propName] = array($orgValue, $actualValue);
         }
         if ($changeSet) {
             $this->documentChangeSets[$oid] = $recompute && isset($this->documentChangeSets[$oid]) ? $changeSet + $this->documentChangeSets[$oid] : $changeSet;
             $this->originalDocumentData[$oid] = $actualData;
             $this->documentUpdates[$oid] = $document;
         }
     }
     // Look for changes in associations of the document
     foreach ($class->fieldMappings as $mapping) {
         // skip not saved fields
         if (isset($mapping['notSaved']) && $mapping['notSaved'] === true) {
             continue;
         }
         if (isset($mapping['reference']) || isset($mapping['embedded'])) {
             $value = $class->reflFields[$mapping['fieldName']]->getValue($document);
             if ($value !== null) {
                 $this->computeAssociationChanges($document, $mapping, $value);
                 if (isset($mapping['reference'])) {
                     continue;
                 }
                 $values = $value;
                 if (isset($mapping['type']) && $mapping['type'] === 'one') {
                     $values = array($values);
                 } elseif ($values instanceof PersistentCollection) {
                     $values = $values->unwrap();
                 }
                 foreach ($values as $obj) {
                     $oid2 = spl_object_hash($obj);
                     if (isset($this->documentChangeSets[$oid2])) {
                         $this->documentChangeSets[$oid][$mapping['fieldName']] = array($value, $value);
                         if (!$isNewDocument) {
                             $this->documentUpdates[$oid] = $document;
                         }
                         break;
                     }
                 }
             }
         }
     }
 }