Esempio n. 1
0
 /**
  * Get the subscribed event systems
  *
  * @param \Doctrine\ORM\Mapping\ClassMetadata $metadata The entity metadata.
  * @param string $eventName                             The entity lifecycle event.
  *
  * @return integer Bitmask of subscribed event systems.
  */
 public function getSubscribedSystems(ClassMetadata $metadata, $eventName)
 {
     $invoke = self::INVOKE_NONE;
     if (isset($metadata->lifecycleCallbacks[$eventName])) {
         $invoke |= self::INVOKE_CALLBACKS;
     }
     if (isset($metadata->entityListeners[$eventName])) {
         $invoke |= self::INVOKE_LISTENERS;
     }
     if ($this->eventManager->hasListeners($eventName)) {
         $invoke |= self::INVOKE_MANAGER;
     }
     return $invoke;
 }
 /**
  * Dispatches postHydrate event for specified entity or enqueues it for later dispatching
  *
  * @param object $entity
  */
 public function dispatchPostHydrate($entity)
 {
     $className = get_class($entity);
     if (!$this->eventManager->hasListeners(Events::postHydrate)) {
         return;
     }
     if (isset($this->hints[Query::HINT_INTERNAL_ITERATION])) {
         $this->eventManager->dispatchEvent(Events::postHydrate, new LifecycleEventArgs($entity, $this->entityManager));
     } else {
         if (!isset($this->entities[$className])) {
             $this->entities[$className] = array();
         }
         $this->entities[$className][] = $entity;
     }
 }
Esempio n. 3
0
 /**
  * Creates a new database.
  *
  * @param string $name The database name
  *
  * @return Database
  *
  * @throws Exception If the database could not be created.
  */
 public function createDatabase($name)
 {
     if (preg_match('@[^a-z0-9\\_\\$\\(\\)+\\-]@', $name)) {
         throw new InvalidDatabasenameException(sprintf('The database name %s is invalid. The database name must match the following pattern (a-z0-9_$()+-)', $name));
     }
     if ($this->eventManager->hasListeners(Events::PRE_CREATE_DATABASE)) {
         // @codeCoverageIgnoreStart
         $this->eventManager->dispatchEvent(Events::PRE_CREATE_DATABASE, new EventArgs($this, $name));
         // @codeCoverageIgnoreEnd
     }
     $response = $this->client->request('PUT', sprintf('/%s', $name));
     if (412 === $response->getStatusCode()) {
         throw new Exception(sprintf('The database "%s" already exist', $name));
     }
     $json = (string) $response->getBody();
     $value = JSONEncoder::decode($json);
     if (isset($value['error'])) {
         throw new Exception(sprintf('[%s] Failed to create database "%s". (%s)', $value['error'], $name, $value['reason']));
     }
     $database = $this->wrapDatabase($name);
     if ($this->eventManager->hasListeners(Events::POST_CREATE_DATABASE)) {
         // @codeCoverageIgnoreStart
         $this->eventManager->dispatchEvent(Events::POST_CREATE_DATABASE, new EventArgs($database));
         // @codeCoverageIgnoreEnd
     }
     return $database;
 }
Esempio n. 4
0
 /**
  * Construct an entity object
  *
  * @param ClassMetadata $class
  * @param object $document
  */
 public function hydrateEntity(ClassMetadata $class, $document)
 {
     // TODO: add support for different result set types from different clients
     // perhaps by wrapping documents in a layer of abstraction
     $data = $document->getData();
     $fields = array_merge($document->hasFields() ? $document->getFields() : array(), array('_version' => $document->getVersion()));
     foreach ($fields as $name => $value) {
         if (isset($class->parameters[$name])) {
             $data[$name] = $value;
         } else {
             foreach ($class->parameters as $param => $mapping) {
                 if ($mapping->name == $name) {
                     $data[$param] = $value;
                     break;
                 }
             }
         }
     }
     $data[$class->getIdentifier()] = $document->getId();
     if (method_exists($document, 'getScore')) {
         $data['score'] = $document->getScore();
     }
     $entity = $this->sm->getSerializer()->deserialize($class->className, json_encode($data));
     if ($this->evm->hasListeners(Events::postLoad)) {
         $this->evm->dispatchEvent(Events::postLoad, new Event\LifecycleEventArgs($entity, $this->sm));
     }
     return $entity;
 }
 /**
  * Executes the queued restorations.
  */
 private function executeRestores()
 {
     $deletedFieldName = $this->configuration->getDeletedFieldName();
     $persisters = array();
     foreach ($this->restoreBy as $className => $criterias) {
         $persister = $this->getDocumentPersister($className);
         $persisters[$className] = $persister;
         foreach ($criterias as $criteria) {
             $persister->addRestoreBy($criteria);
         }
     }
     $documentRestores = array();
     foreach ($this->documentRestores as $document) {
         $className = get_class($document);
         $documentRestores[$className][] = $document;
         $persister = $this->getDocumentPersister($className);
         $persisters[$className] = $persister;
         $persister->addRestore($document);
     }
     foreach ($persisters as $className => $persister) {
         $persister->executeRestores();
         $class = $this->dm->getClassMetadata($className);
         if (isset($documentRestores[$className])) {
             $documents = $documentRestores[$className];
             foreach ($documents as $document) {
                 $class->setFieldValue($document, $deletedFieldName, null);
                 if ($this->eventManager->hasListeners(Events::postRestore)) {
                     $this->eventManager->dispatchEvent(Events::postRestore, new Event\LifecycleEventArgs($document, $this));
                 }
             }
         }
     }
 }
 /**
  * {@inheritDoc}
  */
 protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
 {
     /* @var $class \Doctrine\OXM\Mapping\ClassMetadata */
     /* @var $parent \Doctrine\OXM\Mapping\ClassMetadata */
     if ($parent) {
         $class->setIdGeneratorType($parent->generatorType);
         $this->addInheritedFields($class, $parent);
         $class->setXmlNamespaces($parent->xmlNamespaces);
         $class->setIdentifier($parent->identifier);
         $class->setLifecycleCallbacks($parent->lifecycleCallbacks);
         $class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
         $class->parent = $parent->getName();
     }
     // Invoke driver
     try {
         $this->driver->loadMetadataForClass($class->getName(), $class);
     } catch (ReflectionException $e) {
         throw MappingException::reflectionFailure($class->getName(), $e);
     }
     $xmlNamespace = empty($class->xmlNamespaces) ? '' : $class->xmlNamespaces[0]['url'];
     foreach ($class->xmlNamespaces as $namespaceData) {
         if (empty($namespaceData['prefix'])) {
             $xmlNamespace = $namespaceData['url'];
         }
     }
     $xmlName = $class->getXmlName();
     // Ignore duplicate binding issues -- at least for now
     /*
     if ( $this->isEntity($class) && array_key_exists($xmlName, $this->xmlToClassMap) && array_key_exists($xmlNamespace, $this->xmlToClassMap[$xmlName])) {
     			if ($this->xmlToClassMap[$xmlName][$xmlNamespace] == $class->getName() || $this->xmlToClassMap[$xmlName][$xmlNamespace] == '\\' . $class->getName()) {
     				// Ignore
     	        } else {
     		throw MappingException::duplicateXmlNameBinding($class->getName(), $class->getXmlName());
     	        }
     }
     */
     // The previous test should be sufficent for us to just assume that the namespace/alternative is fine
     if (!empty($parent)) {
         $this->alternativeClassMap[$parent->getName()][$xmlNamespace] = $class->getName();
     }
     if (!$class->isMappedSuperclass) {
         $this->xmlToClassMap[$xmlName][$xmlNamespace] = $class->getName();
     }
     if ($parent && !$parent->isMappedSuperclass) {
         if ($parent->generatorType) {
             $class->setIdGeneratorType($parent->generatorType);
         }
         if ($parent->idGenerator) {
             $class->setIdGenerator($parent->idGenerator);
         }
     } else {
         $this->completeIdGeneratorMapping($class);
     }
     $class->setParentClasses($nonSuperclassParents);
     // Todo - ensure that root elements have an ID mapped
     if ($this->evm->hasListeners(Events::loadClassMetadata)) {
         $eventArgs = new LoadClassMetadataEventArgs($class, $this);
         $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
     }
 }
Esempio n. 7
0
 /**
  * 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));
     // Invoke preLoad lifecycle events and listeners
     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));
     }
     // Use the alsoLoadMethods on the document object to transform the data before hydration
     if (isset($metadata->alsoLoadMethods)) {
         foreach ($metadata->alsoLoadMethods as $fieldName => $method) {
             if (isset($data[$fieldName])) {
                 $document->{$method}($data[$fieldName]);
             }
         }
     }
     if ($this->hydratorFactory !== null) {
         $data = $this->hydratorFactory->getHydratorFor($metadata->name)->hydrate($document, $data);
     } else {
         $data = $this->doGenericHydration($metadata, $document, $data);
     }
     // Invoke the postLoad lifecycle callbacks and listeners
     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 $data;
 }
Esempio n. 8
0
 /**
  * Get the subscribed event systems
  *
  * @param ClassMetadata $metadata
  * @param string        $eventName The entity lifecycle event.
  *
  * @return integer                 Bitmask of subscribed event systems.
  */
 public function getSubscribedSystems(ClassMetadata $metadata, $eventName)
 {
     $invoke = self::INVOKE_NONE;
     if ($metadata && isset($metadata->lifecycleCallbacks[$eventName])) {
         $invoke |= self::INVOKE_CALLBACKS;
     }
     /*
      * Not implemented for phpcr-odm at the moment.
      *
     if (isset($metadata->documentListeners[$eventName])) {
         $invoke |= self::INVOKE_LISTENERS;
     }
     */
     if ($this->eventManager->hasListeners($eventName)) {
         $invoke |= self::INVOKE_MANAGER;
     }
     return $invoke;
 }
Esempio n. 9
0
 /**
  * Actually load the metadata from the underlying metadata
  *
  * @param ClassMetadataInterface|ClassMetadata $class
  * @param ClassMetadataInterface|ClassMetadata $parent
  * @param bool $rootEntityFound
  * @param array $nonSuperclassParents
  */
 protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
 {
     //Manipulates $classMetadata;
     $this->driver->loadMetadataForClass($class->getName(), $class);
     if ($this->evm->hasListeners(Events::loadClassMetadata)) {
         $eventArgs = new LoadClassMetadataEventArgs($class, $this->sm);
         $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
     }
 }
Esempio n. 10
0
 public function save(array &$a, array $options = array())
 {
     if ($this->eventManager->hasListeners(Events::preSave)) {
         $this->eventManager->dispatchEvent(Events::preSave, new EventArgs($this, $a));
     }
     $result = $this->doSave($a, $options);
     if ($this->eventManager->hasListeners(Events::postSave)) {
         $this->eventManager->dispatchEvent(Events::postSave, new EventArgs($this, $result));
     }
     return $result;
 }
 /**
  * {@inheritdoc}
  */
 protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
 {
     if ($this->getDriver()) {
         $this->getDriver()->loadMetadataForClass($class->getName(), $class);
     }
     if ($this->evm->hasListeners(Event::loadClassMetadata)) {
         $eventArgs = new Event\LoadClassMetadataEventArgs($class, $this->objectAdapterManager);
         $this->evm->dispatchEvent(Event::loadClassMetadata, $eventArgs);
     }
     $this->validateRuntimeMetadata($class, $parent);
 }
Esempio n. 12
0
 /** @proxy */
 public function selectCollection($name)
 {
     if ($this->eventManager->hasListeners(Events::preSelectCollection)) {
         $this->eventManager->dispatchEvent(Events::preSelectCollection, new EventArgs($this, $name));
     }
     $collection = $this->doSelectCollection($name);
     if ($this->eventManager->hasListeners(Events::postSelectCollection)) {
         $this->eventManager->dispatchEvent(Events::postSelectCollection, new EventArgs($this, $collection));
     }
     return $collection;
 }
Esempio n. 13
0
 /**
  * @param ObjectManager $om
  *
  * @return MetadataFactory
  */
 protected function getMetadataFactory(ObjectManager $om, EventManager $evm)
 {
     if ($this->metadataFactory === null) {
         $driverFactory = DriverFactory::instance();
         if ($evm->hasListeners(Events::REGISTER_DRIVER_METADATA)) {
             $eventArgs = new RegisterDriverMetadataEventArgs($driverFactory, $om);
             $evm->dispatchEvent(Events::REGISTER_DRIVER_METADATA, $eventArgs);
         }
         $this->metadataFactory = new MetadataFactory($driverFactory->driversFromManager($om));
     }
     return $this->metadataFactory;
 }
Esempio n. 14
0
 /** @proxy */
 public function selectDatabase($name)
 {
     if ($this->eventManager->hasListeners(Events::preSelectDatabase)) {
         $this->eventManager->dispatchEvent(Events::preSelectDatabase, new EventArgs($this, $name));
     }
     $this->initialize();
     $database = $this->wrapDatabase($name);
     if ($this->eventManager->hasListeners(Events::postSelectDatabase)) {
         $this->eventManager->dispatchEvent(Events::postSelectDatabase, new EventArgs($this, $database));
     }
     return $database;
 }
Esempio n. 15
0
 /**
  * @param TableDiff $diff
  * @param array $columnSql
  */
 protected function onSchemaAlterTable(TableDiff $diff, &$sql)
 {
     if (null === $this->_eventManager) {
         return false;
     }
     if (!$this->_eventManager->hasListeners(Events::onSchemaAlterTable)) {
         return false;
     }
     $eventArgs = new SchemaAlterTableEventArgs($diff, $this);
     $this->_eventManager->dispatchEvent(Events::onSchemaAlterTable, $eventArgs);
     $sql = array_merge($sql, $eventArgs->getSql());
     return $eventArgs->isDefaultPrevented();
 }
Esempio n. 16
0
 /**
  * Wrapper method for RiakCollection::update().
  *
  * This method will dispatch preUpdate and postUpdate events.
  *
  * @see http://php.net/manual/en/mongocollection.update.php
  * @param array $query
  * @param array $newObj
  * @param array $options
  * @return array|boolean
  */
 public function update($query, array $newObj, array $options = array())
 {
     if (is_scalar($query)) {
         trigger_error('Scalar $query argument for update() is deprecated', E_USER_DEPRECATED);
         $query = array('_id' => $query);
     }
     if ($this->eventManager->hasListeners(Events::preUpdate)) {
         $this->eventManager->dispatchEvent(Events::preUpdate, new UpdateEventArgs($this, $query, $newObj, $options));
     }
     $result = $this->doUpdate($query, $newObj, $options);
     if ($this->eventManager->hasListeners(Events::postUpdate)) {
         $this->eventManager->dispatchEvent(Events::postUpdate, new EventArgs($this, $result));
     }
     return $result;
 }
Esempio n. 17
0
 /**
  * {@inheritdoc}
  */
 protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
 {
     if ($parent) {
         $this->addInheritedDocumentOptions($class, $parent);
         $this->addInheritedFields($class, $parent);
     }
     if ($this->getDriver()) {
         $this->getDriver()->loadMetadataForClass($class->getName(), $class);
     }
     if ($this->evm->hasListeners(Event::loadClassMetadata)) {
         $eventArgs = new LoadClassMetadataEventArgs($class, $this->dm);
         $this->evm->dispatchEvent(Event::loadClassMetadata, $eventArgs);
     }
     $this->validateRuntimeMetadata($class, $parent);
     $class->setParentClasses($this->getParentClasses($class->name));
 }
Esempio n. 18
0
 /**
  * Establishes the connection with the database.
  *
  * @return boolean TRUE if the connection was successfully established, FALSE if
  *                 the connection is already open.
  */
 public function connect()
 {
     if ($this->_isConnected) {
         return false;
     }
     $driverOptions = isset($this->_params['driverOptions']) ? $this->_params['driverOptions'] : array();
     $user = isset($this->_params['user']) ? $this->_params['user'] : null;
     $password = isset($this->_params['password']) ? $this->_params['password'] : null;
     $this->_conn = $this->_driver->connect($this->_params, $user, $password, $driverOptions);
     $this->_isConnected = true;
     if ($this->_eventManager->hasListeners(Events::postConnect)) {
         $eventArgs = new Event\ConnectionEventArgs($this);
         $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
     }
     return true;
 }
Esempio n. 19
0
 /**
  * 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.
  * @param array $hints Any hints to account for during reconstitution/lookup of the document.
  * @return array $values The array of hydrated values.
  */
 public function hydrate($document, $data, array $hints = array())
 {
     $metadata = $this->dm->getClassMetadata(get_class($document));
     // Invoke preLoad lifecycle events and listeners
     if (!empty($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));
     }
     // alsoLoadMethods may transform the document before hydration
     if (!empty($metadata->alsoLoadMethods)) {
         foreach ($metadata->alsoLoadMethods as $method => $fieldNames) {
             foreach ($fieldNames as $fieldName) {
                 // Invoke the method only once for the first field we find
                 if (array_key_exists($fieldName, $data)) {
                     $document->{$method}($data[$fieldName]);
                     continue 2;
                 }
             }
         }
     }
     $data = $this->getHydratorFor($metadata->name)->hydrate($document, $data, $hints);
     if ($document instanceof Proxy) {
         $document->__isInitialized__ = true;
         $document->__setInitializer(null);
         $document->__setCloner(null);
         // lazy properties may be left uninitialized
         $properties = $document->__getLazyProperties();
         foreach ($properties as $propertyName => $property) {
             if (!isset($document->{$propertyName})) {
                 $document->{$propertyName} = $properties[$propertyName];
             }
         }
     }
     // Invoke the postLoad lifecycle callbacks and listeners
     if (!empty($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 $data;
 }
Esempio n. 20
0
 /**
  * Clears the UnitOfWork.
  *
  * @param string|null $class if given, only documents of this type will be detached.
  *
  * @throws \Exception if $class is not null (not implemented)
  */
 public function clear($class = null)
 {
     if ($class === null) {
         $this->identityMap = $this->documentIdentifiers = $this->originalDocumentData = $this->documentChangeSets = $this->documentStates = $this->scheduledForDirtyCheck = $this->documentInsertions = $this->documentUpdates = $this->documentDeletions = $this->collectionUpdates = $this->collectionDeletions = $this->orphanRemovals = [];
     } else {
         $visited = [];
         foreach ($this->identityMap as $className => $documents) {
             if ($className === $class) {
                 foreach ($documents as $document) {
                     $this->doDetach($document, $visited);
                 }
             }
         }
     }
     if ($this->evm->hasListeners(Events::onClear)) {
         $this->evm->dispatchEvent(Events::onClear, new Event\OnClearEventArgs($this->dm, $class));
     }
 }
 /**
  * Will remove all scheduled stuff. This method can only be calles once.
  */
 public function clear()
 {
     if ($this->hasCleared()) {
         return;
     }
     $this->hasCleared = true;
     // trigger clear on all managers of the referenced objects
     $managedObjects = $this->getScheduledReferencesByManager();
     foreach ($managedObjects as $value) {
         $value['manager']->clear();
     }
     // clear all object stores
     $this->objects = $this->objectState = $this->referencedObjects = $this->referencedObjectState = $this->removeReferences = $this->insertReferences = $this->updateReferences = array();
     $this->hasCleared = false;
     $this->hasFlushed = false;
     if ($this->eventManager->hasListeners(Event::onClear)) {
         $this->eventManager->dispatchEvent(Event::onClear, new ManagerEventArgs($this->objectAdapterManager));
     }
 }
Esempio n. 22
0
 /**
  * Actually loads PHPCR-ODM metadata from the underlying metadata.
  *
  * @param ClassMetadata      $class
  * @param ClassMetadata|null $parent
  * @param bool               $rootEntityFound
  * @param array              $nonSuperclassParents All parent class names
  *                                                 that are not marked as mapped superclasses.
  */
 protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
 {
     if ($parent) {
         $this->addInheritedDocumentOptions($class, $parent);
         $this->addInheritedFields($class, $parent);
     }
     if ($this->getDriver()) {
         $this->getDriver()->loadMetadataForClass($class->getName(), $class);
     }
     // once we loaded the metadata of this class, we might have to merge in the mixins of the parent.
     if ($parent && $class->getInheritMixins()) {
         $class->setMixins(array_merge($parent->getMixins(), $class->getMixins()));
     }
     if ($this->evm->hasListeners(Event::loadClassMetadata)) {
         $eventArgs = new LoadClassMetadataEventArgs($class, $this->dm);
         $this->evm->dispatchEvent(Event::loadClassMetadata, $eventArgs);
     }
     $this->validateRuntimeMetadata($class, $parent);
     $class->setParentClasses($this->getParentClasses($class->name));
 }
Esempio n. 23
0
 /**
  * Wrapper method for MongoCollection::update().
  *
  * This method will dispatch preUpdate and postUpdate events.
  *
  * @see http://php.net/manual/en/mongocollection.update.php
  * @param array $query
  * @param array $newObj
  * @param array $options
  * @return array|boolean
  */
 public function update($query, array $newObj, array $options = [])
 {
     if (is_scalar($query)) {
         trigger_error('Scalar $query argument for update() is deprecated', E_USER_DEPRECATED);
         $query = ['_id' => $query];
     }
     if ($this->eventManager->hasListeners(Events::preUpdate)) {
         $updateEventArgs = new UpdateEventArgs($this, $query, $newObj, $options);
         $this->eventManager->dispatchEvent(Events::preUpdate, $updateEventArgs);
         $query = $updateEventArgs->getQuery();
         $newObj = $updateEventArgs->getNewObj();
         $options = $updateEventArgs->getOptions();
     }
     $result = $this->doUpdate($query, $newObj, $options);
     if ($this->eventManager->hasListeners(Events::postUpdate)) {
         $eventArgs = new MutableEventArgs($this, $result);
         $this->eventManager->dispatchEvent(Events::postUpdate, $eventArgs);
         $result = $eventArgs->getData();
     }
     return $result;
 }
 /**
  * {@inheritDoc}
  */
 protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonSuperclassParents)
 {
     /* @var $class ClassMetadata */
     /* @var $parent ClassMetadata */
     if ($parent) {
         $class->setInheritanceType($parent->inheritanceType);
         $class->setDiscriminatorColumn($parent->discriminatorColumn);
         $class->setIdGeneratorType($parent->generatorType);
         $this->addInheritedFields($class, $parent);
         $this->addInheritedRelations($class, $parent);
         $this->addInheritedEmbeddedClasses($class, $parent);
         $class->setIdentifier($parent->identifier);
         $class->setVersioned($parent->isVersioned);
         $class->setVersionField($parent->versionField);
         $class->setDiscriminatorMap($parent->discriminatorMap);
         $class->setLifecycleCallbacks($parent->lifecycleCallbacks);
         $class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
         if (!empty($parent->customGeneratorDefinition)) {
             $class->setCustomGeneratorDefinition($parent->customGeneratorDefinition);
         }
         if ($parent->isMappedSuperclass) {
             $class->setCustomRepositoryClass($parent->customRepositoryClassName);
         }
     }
     // Invoke driver
     try {
         $this->driver->loadMetadataForClass($class->getName(), $class);
     } catch (ReflectionException $e) {
         throw MappingException::reflectionFailure($class->getName(), $e);
     }
     // If this class has a parent the id generator strategy is inherited.
     // However this is only true if the hierarchy of parents contains the root entity,
     // if it consists of mapped superclasses these don't necessarily include the id field.
     if ($parent && $rootEntityFound) {
         if ($parent->isIdGeneratorSequence()) {
             $class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
         } else {
             if ($parent->isIdGeneratorTable()) {
                 $class->tableGeneratorDefinition = $parent->tableGeneratorDefinition;
             }
         }
         if ($parent->generatorType) {
             $class->setIdGeneratorType($parent->generatorType);
         }
         if ($parent->idGenerator) {
             $class->setIdGenerator($parent->idGenerator);
         }
     } else {
         $this->completeIdGeneratorMapping($class);
     }
     if (!$class->isMappedSuperclass) {
         foreach ($class->embeddedClasses as $property => $embeddableClass) {
             if (isset($embeddableClass['inherited'])) {
                 continue;
             }
             if (isset($this->embeddablesActiveNesting[$embeddableClass['class']])) {
                 throw MappingException::infiniteEmbeddableNesting($class->name, $property);
             }
             $this->embeddablesActiveNesting[$class->name] = true;
             $embeddableMetadata = $this->getMetadataFor($embeddableClass['class']);
             if ($embeddableMetadata->isEmbeddedClass) {
                 $this->addNestedEmbeddedClasses($embeddableMetadata, $class, $property);
             }
             $class->inlineEmbeddable($property, $embeddableMetadata);
             unset($this->embeddablesActiveNesting[$class->name]);
         }
     }
     if ($parent && $parent->isInheritanceTypeSingleTable()) {
         $class->setPrimaryTable($parent->table);
     }
     if ($parent && $parent->cache) {
         $class->cache = $parent->cache;
     }
     if ($parent && $parent->containsForeignIdentifier) {
         $class->containsForeignIdentifier = true;
     }
     if ($parent && !empty($parent->namedQueries)) {
         $this->addInheritedNamedQueries($class, $parent);
     }
     if ($parent && !empty($parent->namedNativeQueries)) {
         $this->addInheritedNamedNativeQueries($class, $parent);
     }
     if ($parent && !empty($parent->sqlResultSetMappings)) {
         $this->addInheritedSqlResultSetMappings($class, $parent);
     }
     if ($parent && !empty($parent->entityListeners) && empty($class->entityListeners)) {
         $class->entityListeners = $parent->entityListeners;
     }
     $class->setParentClasses($nonSuperclassParents);
     if ($class->isRootEntity() && !$class->isInheritanceTypeNone() && !$class->discriminatorMap) {
         $this->addDefaultDiscriminatorMap($class);
     }
     if ($this->evm->hasListeners(Events::loadClassMetadata)) {
         $eventArgs = new LoadClassMetadataEventArgs($class, $this->em);
         $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
     }
     $this->validateRuntimeMetadata($class, $parent);
 }
Esempio n. 25
0
 /**
  * To invoke a global invent without using the ListenersInvoker.
  *
  * @param $eventName
  * @param EventArgs $event
  */
 public function invokeGlobalEvent($eventName, EventArgs $event)
 {
     if ($this->eventManager->hasListeners($eventName)) {
         $this->eventManager->dispatchEvent($eventName, $event);
     }
 }
Esempio n. 26
0
 /**
  * Loads the metadata of the class in question and all it's ancestors whose metadata
  * is still not loaded.
  *
  * @param string $name The name of the class for which the metadata should get loaded.
  * @param array  $tables The metadata collection to which the loaded metadata is added.
  */
 protected function loadMetadata($name)
 {
     if (!$this->initialized) {
         $this->initialize();
     }
     $loaded = array();
     $parentClasses = $this->getParentClasses($name);
     $parentClasses[] = $name;
     // Move down the hierarchy of parent classes, starting from the topmost class
     $parent = null;
     $visited = array();
     foreach ($parentClasses as $className) {
         if (isset($this->loadedMetadata[$className])) {
             $parent = $this->loadedMetadata[$className];
             if ($parent->isMappedSuperclass) {
                 array_unshift($visited, $className);
             }
             continue;
         }
         $class = $this->newClassMetadataInstance($className);
         if ($parent) {
             $class->setIdGeneratorType($parent->generatorType);
             $this->addInheritedFields($class, $parent);
             $class->setXmlNamespaces($parent->xmlNamespaces);
             $class->setIdentifier($parent->identifier);
             $class->setLifecycleCallbacks($parent->lifecycleCallbacks);
             $class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
         }
         // Invoke driver
         try {
             $this->driver->loadMetadataForClass($className, $class);
         } catch (ReflectionException $e) {
             throw MappingException::reflectionFailure($className, $e);
         }
         if (!$class->isMappedSuperclass && in_array($class->getXmlName(), array_keys($this->xmlToClassMap))) {
             throw MappingException::duplicateXmlNameBinding($className, $class->getXmlName());
         }
         if ($parent && !$parent->isMappedSuperclass) {
             if ($parent->generatorType) {
                 $class->setIdGeneratorType($parent->generatorType);
             }
             if ($parent->idGenerator) {
                 $class->setIdGenerator($parent->idGenerator);
             }
         } else {
             $this->completeIdGeneratorMapping($class);
         }
         $class->setParentClasses($visited);
         // Todo - ensure that root elements have an ID mapped
         if ($this->evm->hasListeners(Events::loadClassMetadata)) {
             $eventArgs = new \Doctrine\OXM\Event\LoadClassMetadataEventArgs($class, $this);
             $this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
         }
         $this->loadedMetadata[$className] = $class;
         $this->completeMappingTypeValidation($className, $class);
         if (!$class->isMappedSuperclass) {
             $this->xmlToClassMap[$class->getXmlName()] = $className;
         }
         $parent = $class;
         if ($class->isMappedSuperclass) {
             array_unshift($visited, $className);
         }
         $loaded[] = $className;
     }
     return $loaded;
 }
Esempio n. 27
0
 /**
  * Cascades the preLoad event to embedded documents.
  *
  * @param ClassMetadata $class
  * @param object $document
  * @param array $data
  */
 private function cascadePreLoad(ClassMetadata $class, $document, $data)
 {
     foreach ($class->fieldMappings as $mapping) {
         if (isset($mapping['embedded'])) {
             $value = $class->reflFields[$mapping['fieldName']]->getValue($document);
             if ($value === null) {
                 continue;
             }
             if ($mapping['type'] === 'one') {
                 $value = array($value);
             }
             foreach ($value as $entry) {
                 $entryClass = $this->dm->getClassMetadata(get_class($entry));
                 if (isset($entryClass->lifecycleCallbacks[Events::preLoad])) {
                     $args = array(&$data);
                     $entryClass->invokeLifecycleCallbacks(Events::preLoad, $entry, $args);
                 }
                 if ($this->evm->hasListeners(Events::preLoad)) {
                     $this->evm->dispatchEvent(Events::preLoad, new PreLoadEventArgs($entry, $this->dm, $data[$mapping['name']]));
                 }
                 $this->cascadePreLoad($entryClass, $entry, $data[$mapping['name']]);
             }
         }
     }
 }
Esempio n. 28
0
 private function dispatchPostFlushEvent()
 {
     if ($this->evm->hasListeners(Events::postFlush)) {
         $this->evm->dispatchEvent(Events::postFlush, new PostFlushEventArgs($this->em));
     }
 }
Esempio n. 29
0
 /**
  * INTERNAL:
  * Creates an entity. Used for reconstitution of persistent entities.
  *
  * @ignore
  * @param string $className The name of the entity class.
  * @param array $data The data for the entity.
  * @param array $hints Any hints to account for during reconstitution/lookup of the entity.
  *
  * @return object The managed entity instance.
  * @internal Highly performance-sensitive method.
  *
  * @todo Rename: getOrCreateEntity
  */
 public function createEntity($className, array $data, &$hints = array())
 {
     $class = $this->em->getClassMetadata($className);
     //$isReadOnly = isset($hints[Query::HINT_READ_ONLY]);
     if ($class->isIdentifierComposite) {
         $id = array();
         foreach ($class->identifier as $fieldName) {
             $id[$fieldName] = isset($class->associationMappings[$fieldName]) ? $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']] : $data[$fieldName];
         }
         $idHash = implode(' ', $id);
     } else {
         $idHash = isset($class->associationMappings[$class->identifier[0]]) ? $data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']] : $data[$class->identifier[0]];
         $id = array($class->identifier[0] => $idHash);
     }
     if (isset($this->identityMap[$class->rootEntityName][$idHash])) {
         $entity = $this->identityMap[$class->rootEntityName][$idHash];
         $oid = spl_object_hash($entity);
         if ($entity instanceof Proxy && !$entity->__isInitialized__) {
             $entity->__isInitialized__ = true;
             $overrideLocalValues = true;
             if ($entity instanceof NotifyPropertyChanged) {
                 $entity->addPropertyChangedListener($this);
             }
         } else {
             $overrideLocalValues = isset($hints[Query::HINT_REFRESH]);
             // If only a specific entity is set to refresh, check that it's the one
             if (isset($hints[Query::HINT_REFRESH_ENTITY])) {
                 $overrideLocalValues = $hints[Query::HINT_REFRESH_ENTITY] === $entity;
                 // inject ObjectManager into just loaded proxies.
                 if ($overrideLocalValues && $entity instanceof ObjectManagerAware) {
                     $entity->injectObjectManager($this->em, $class);
                 }
             }
         }
         if ($overrideLocalValues) {
             $this->originalEntityData[$oid] = $data;
         }
     } else {
         $entity = $this->newInstance($class);
         $oid = spl_object_hash($entity);
         $this->entityIdentifiers[$oid] = $id;
         $this->entityStates[$oid] = self::STATE_MANAGED;
         $this->originalEntityData[$oid] = $data;
         $this->identityMap[$class->rootEntityName][$idHash] = $entity;
         if ($entity instanceof NotifyPropertyChanged) {
             $entity->addPropertyChangedListener($this);
         }
         $overrideLocalValues = true;
     }
     if (!$overrideLocalValues) {
         return $entity;
     }
     foreach ($data as $field => $value) {
         if (isset($class->fieldMappings[$field])) {
             $class->reflFields[$field]->setValue($entity, $value);
         }
     }
     // Loading the entity right here, if its in the eager loading map get rid of it there.
     unset($this->eagerLoadingEntities[$class->rootEntityName][$idHash]);
     if (isset($this->eagerLoadingEntities[$class->rootEntityName]) && !$this->eagerLoadingEntities[$class->rootEntityName]) {
         unset($this->eagerLoadingEntities[$class->rootEntityName]);
     }
     // Properly initialize any unfetched associations, if partial objects are not allowed.
     if (isset($hints[Query::HINT_FORCE_PARTIAL_LOAD])) {
         return $entity;
     }
     foreach ($class->associationMappings as $field => $assoc) {
         // Check if the association is not among the fetch-joined associations already.
         if (isset($hints['fetchAlias']) && isset($hints['fetched'][$hints['fetchAlias']][$field])) {
             continue;
         }
         $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
         switch (true) {
             case $assoc['type'] & ClassMetadata::TO_ONE:
                 if (!$assoc['isOwningSide']) {
                     // Inverse side of x-to-one can never be lazy
                     $class->reflFields[$field]->setValue($entity, $this->getEntityPersister($assoc['targetEntity'])->loadOneToOneEntity($assoc, $entity));
                     continue 2;
                 }
                 $associatedId = array();
                 // TODO: Is this even computed right in all cases of composite keys?
                 foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) {
                     $joinColumnValue = isset($data[$srcColumn]) ? $data[$srcColumn] : null;
                     if ($joinColumnValue !== null) {
                         if ($targetClass->containsForeignIdentifier) {
                             $associatedId[$targetClass->getFieldForColumn($targetColumn)] = $joinColumnValue;
                         } else {
                             $associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue;
                         }
                     }
                 }
                 if (!$associatedId) {
                     // Foreign key is NULL
                     $class->reflFields[$field]->setValue($entity, null);
                     $this->originalEntityData[$oid][$field] = null;
                     continue;
                 }
                 if (!isset($hints['fetchMode'][$class->name][$field])) {
                     $hints['fetchMode'][$class->name][$field] = $assoc['fetch'];
                 }
                 // Foreign key is set
                 // Check identity map first
                 // FIXME: Can break easily with composite keys if join column values are in
                 //        wrong order. The correct order is the one in ClassMetadata#identifier.
                 $relatedIdHash = implode(' ', $associatedId);
                 switch (true) {
                     case isset($this->identityMap[$targetClass->rootEntityName][$relatedIdHash]):
                         $newValue = $this->identityMap[$targetClass->rootEntityName][$relatedIdHash];
                         // If this is an uninitialized proxy, we are deferring eager loads,
                         // this association is marked as eager fetch, and its an uninitialized proxy (wtf!)
                         // then we can append this entity for eager loading!
                         if ($hints['fetchMode'][$class->name][$field] == ClassMetadata::FETCH_EAGER && isset($hints['deferEagerLoad']) && !$targetClass->isIdentifierComposite && $newValue instanceof Proxy && $newValue->__isInitialized__ === false) {
                             $this->eagerLoadingEntities[$targetClass->rootEntityName][$relatedIdHash] = current($associatedId);
                         }
                         break;
                     case $targetClass->subClasses:
                         // If it might be a subtype, it can not be lazy. There isn't even
                         // a way to solve this with deferred eager loading, which means putting
                         // an entity with subclasses at a *-to-one location is really bad! (performance-wise)
                         $newValue = $this->getEntityPersister($assoc['targetEntity'])->loadOneToOneEntity($assoc, $entity, $associatedId);
                         break;
                     default:
                         switch (true) {
                             // We are negating the condition here. Other cases will assume it is valid!
                             case $hints['fetchMode'][$class->name][$field] !== ClassMetadata::FETCH_EAGER:
                                 $newValue = $this->em->getProxyFactory()->getProxy($assoc['targetEntity'], $associatedId);
                                 break;
                                 // Deferred eager load only works for single identifier classes
                             // Deferred eager load only works for single identifier classes
                             case isset($hints['deferEagerLoad']) && !$targetClass->isIdentifierComposite:
                                 // TODO: Is there a faster approach?
                                 $this->eagerLoadingEntities[$targetClass->rootEntityName][$relatedIdHash] = current($associatedId);
                                 $newValue = $this->em->getProxyFactory()->getProxy($assoc['targetEntity'], $associatedId);
                                 break;
                             default:
                                 // TODO: This is very imperformant, ignore it?
                                 $newValue = $this->em->find($assoc['targetEntity'], $associatedId);
                                 break;
                         }
                         // PERF: Inlined & optimized code from UnitOfWork#registerManaged()
                         $newValueOid = spl_object_hash($newValue);
                         $this->entityIdentifiers[$newValueOid] = $associatedId;
                         $this->identityMap[$targetClass->rootEntityName][$relatedIdHash] = $newValue;
                         $this->entityStates[$newValueOid] = self::STATE_MANAGED;
                         // make sure that when an proxy is then finally loaded, $this->originalEntityData is set also!
                         break;
                 }
                 $this->originalEntityData[$oid][$field] = $newValue;
                 $class->reflFields[$field]->setValue($entity, $newValue);
                 if ($assoc['inversedBy'] && $assoc['type'] & ClassMetadata::ONE_TO_ONE) {
                     $inverseAssoc = $targetClass->associationMappings[$assoc['inversedBy']];
                     $targetClass->reflFields[$inverseAssoc['fieldName']]->setValue($newValue, $entity);
                 }
                 break;
             default:
                 // Inject collection
                 $pColl = new PersistentCollection($this->em, $targetClass, new ArrayCollection());
                 $pColl->setOwner($entity, $assoc);
                 $pColl->setInitialized(false);
                 $reflField = $class->reflFields[$field];
                 $reflField->setValue($entity, $pColl);
                 if ($assoc['fetch'] == ClassMetadata::FETCH_EAGER) {
                     $this->loadCollection($pColl);
                     $pColl->takeSnapshot();
                 }
                 $this->originalEntityData[$oid][$field] = $pColl;
                 break;
         }
     }
     if ($overrideLocalValues) {
         if (isset($class->lifecycleCallbacks[Events::postLoad])) {
             $class->invokeLifecycleCallbacks(Events::postLoad, $entity);
         }
         if ($this->evm->hasListeners(Events::postLoad)) {
             $this->evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($entity, $this->em));
         }
     }
     return $entity;
 }
 /**
  * Establishes the connection with the database.
  *
  * @return boolean TRUE if the connection was successfully established, FALSE if
  *                 the connection is already open.
  */
 public function connect()
 {
     if ($this->_isConnected) {
         return false;
     }
     $driverOptions = isset($this->_params['driverOptions']) ? $this->_params['driverOptions'] : array();
     $user = isset($this->_params['user']) ? $this->_params['user'] : null;
     $password = isset($this->_params['password']) ? $this->_params['password'] : null;
     $this->_conn = $this->_driver->connect($this->_params, $user, $password, $driverOptions);
     $this->_isConnected = true;
     if (null === $this->platform) {
         $this->detectDatabasePlatform();
     }
     if (false === $this->autoCommit) {
         $this->beginTransaction();
     }
     if ($this->_eventManager->hasListeners(Events::postConnect)) {
         $eventArgs = new Event\ConnectionEventArgs($this);
         $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
     }
     return true;
 }