本文整理汇总了PHP中Doctrine\ORM\PersistentCollection::setOwner方法的典型用法代码示例。如果您正苦于以下问题:PHP PersistentCollection::setOwner方法的具体用法?PHP PersistentCollection::setOwner怎么用?PHP PersistentCollection::setOwner使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Doctrine\ORM\PersistentCollection
的用法示例。
在下文中一共展示了PersistentCollection::setOwner方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: setUpPersistentCollection
/**
* Set up the PersistentCollection used for collection initialization tests.
*/
public function setUpPersistentCollection()
{
$classMetaData = $this->_emMock->getClassMetadata('Doctrine\\Tests\\Models\\ECommerce\\ECommerceCart');
$this->collection = new PersistentCollection($this->_emMock, $classMetaData, new ArrayCollection());
$this->collection->setInitialized(false);
$this->collection->setOwner(new ECommerceCart(), $classMetaData->getAssociationMapping('products'));
}
示例2: testShouldNotScheduleDeletionOnClonedInstances
public function testShouldNotScheduleDeletionOnClonedInstances()
{
$class = $this->_em->getClassMetadata('Doctrine\\Tests\\Models\\ECommerce\\ECommerceProduct');
$product = new ECommerceProduct();
$category = new ECommerceCategory();
$collection = new PersistentCollection($this->_em, $class, new ArrayCollection(array($category)));
$collection->setOwner($product, $class->associationMappings['categories']);
$uow = $this->_em->getUnitOfWork();
$clonedCollection = clone $collection;
$clonedCollection->clear();
$this->assertEquals(0, count($uow->getScheduledCollectionDeletions()));
}
示例3: setProductPersistentCollection
/**
* Prepare a lazy loadable PersistentCollection
* on the entity to get Products.
* The entity must have a "products" property defined
*
* @param object $entity The entity related to the products
* @param array $assoc Association properties
* @param EntityManager $entityManager Entity manager
*/
protected function setProductPersistentCollection($entity, $assoc, EntityManager $entityManager)
{
$targetEntity = $this->productClass;
$productsCollection = new PersistentCollection($entityManager, $targetEntity, new ArrayCollection());
$assoc['fieldName'] = 'products';
$assoc['targetEntity'] = $targetEntity;
$assoc['type'] = ClassMetadata::MANY_TO_MANY;
$assoc['inversedBy'] = '';
$assoc['isOwningSide'] = false;
$assoc['sourceEntity'] = get_class($entity);
$assoc['orphanRemoval'] = false;
$productsCollection->setOwner($entity, $assoc);
$productsCollection->setInitialized(false);
$entityMetadata = $entityManager->getClassMetadata(get_class($entity));
$productsReflProp = $entityMetadata->reflClass->getProperty('products');
$productsReflProp->setAccessible(true);
$productsReflProp->setValue($entity, $productsCollection);
}
示例4: initRelatedCollection
/**
* Initializes a related collection.
*
* @param object $entity The entity to which the collection belongs.
* @param ClassMetadata $class
* @param string $fieldName The name of the field on the entity that holds the collection.
* @param string $parentDqlAlias Alias of the parent fetch joining this collection.
*
* @return \Doctrine\ORM\PersistentCollection
*/
private function initRelatedCollection($entity, $class, $fieldName, $parentDqlAlias)
{
$oid = spl_object_hash($entity);
$relation = $class->associationMappings[$fieldName];
$value = $class->reflFields[$fieldName]->getValue($entity);
if ($value === null || is_array($value)) {
$value = new ArrayCollection((array) $value);
}
if (!$value instanceof PersistentCollection) {
$value = new PersistentCollection($this->_em, $this->_metadataCache[$relation['targetEntity']], $value);
$value->setOwner($entity, $relation);
$class->reflFields[$fieldName]->setValue($entity, $value);
$this->_uow->setOriginalEntityProperty($oid, $fieldName, $value);
$this->initializedCollections[$oid . $fieldName] = $value;
} else {
if (isset($this->_hints[Query::HINT_REFRESH]) || isset($this->_hints['fetched'][$parentDqlAlias][$fieldName]) && !$value->isInitialized()) {
// Is already PersistentCollection, but either REFRESH or FETCH-JOIN and UNINITIALIZED!
$value->setDirty(false);
$value->setInitialized(true);
$value->unwrap()->clear();
$this->initializedCollections[$oid . $fieldName] = $value;
} else {
// Is already PersistentCollection, and DON'T REFRESH or FETCH-JOIN!
$this->existingCollections[$oid . $fieldName] = $value;
}
}
return $value;
}
示例5: getPersistentCollection
/**
* @param object $owner
* @param array $mapping
* @param array $items
*
* @return PersistentCollection
*/
protected function getPersistentCollection($owner, array $mapping, array $items = [])
{
$metadata = $this->getMockBuilder('Doctrine\\ORM\\Mapping\\ClassMetadata')->disableOriginalConstructor()->getMock();
$coll = new PersistentCollection($this->em, $metadata, new ArrayCollection($items));
$mapping['inversedBy'] = 'test';
$coll->setOwner($owner, $mapping);
return $coll;
}
示例6: createEntity
//.........这里部分代码省略.........
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[self::HINT_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[self::HINT_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;
if ($newValue instanceof NotifyPropertyChanged && (!$newValue instanceof Proxy || $newValue->__isInitialized())) {
$newValue->addPropertyChangedListener($this);
}
$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:
// Ignore if its a cached collection
if (isset($hints[Query::HINT_CACHE_ENABLED]) && $class->getFieldValue($entity, $field) instanceof PersistentCollection) {
break;
}
// use the given collection
if (isset($data[$field]) && $data[$field] instanceof PersistentCollection) {
$data[$field]->setOwner($entity, $assoc);
$class->reflFields[$field]->setValue($entity, $data[$field]);
$this->originalEntityData[$oid][$field] = $data[$field];
break;
}
// 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) {
$invoke = $this->listenersInvoker->getSubscribedSystems($class, Events::postLoad);
if ($invoke !== ListenersInvoker::INVOKE_NONE) {
$this->listenersInvoker->invoke($class, Events::postLoad, $entity, new LifecycleEventArgs($entity, $this->em), $invoke);
}
}
return $entity;
}
示例7: createEntity
//.........这里部分代码省略.........
} else {
$entity = $class->newInstance();
$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) {
foreach ($data as $field => $value) {
if (isset($class->fieldMappings[$field])) {
$class->reflFields[$field]->setValue($entity, $value);
}
}
// Properly initialize any unfetched associations, if partial objects are not allowed.
if (!isset($hints[Query::HINT_FORCE_PARTIAL_LOAD])) {
foreach ($class->associationMappings as $field => $assoc) {
// Check if the association is not among the fetch-joined associations already.
if (isset($hints['fetched'][$className][$field])) {
continue;
}
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
if ($assoc['type'] & ClassMetadata::TO_ONE) {
if ($assoc['isOwningSide']) {
$associatedId = array();
foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) {
$joinColumnValue = isset($data[$srcColumn]) ? $data[$srcColumn] : null;
if ($joinColumnValue !== null) {
$associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue;
}
}
if (!$associatedId) {
// Foreign key is NULL
$class->reflFields[$field]->setValue($entity, null);
$this->originalEntityData[$oid][$field] = null;
} else {
// 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);
if (isset($this->identityMap[$targetClass->rootEntityName][$relatedIdHash])) {
$newValue = $this->identityMap[$targetClass->rootEntityName][$relatedIdHash];
} else {
if ($targetClass->subClasses) {
// If it might be a subtype, it can not be lazy
$newValue = $this->getEntityPersister($assoc['targetEntity'])->loadOneToOneEntity($assoc, $entity, null, $associatedId);
} else {
if ($assoc['fetch'] == ClassMetadata::FETCH_EAGER) {
// TODO: Maybe it could be optimized to do an eager fetch with a JOIN inside
// the persister instead of this rather unperformant approach.
$newValue = $this->em->find($assoc['targetEntity'], $associatedId);
} else {
$newValue = $this->em->getProxyFactory()->getProxy($assoc['targetEntity'], $associatedId);
}
// 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!
}
}
$this->originalEntityData[$oid][$field] = $newValue;
$class->reflFields[$field]->setValue($entity, $newValue);
}
} else {
// Inverse side of x-to-one can never be lazy
$class->reflFields[$field]->setValue($entity, $this->getEntityPersister($assoc['targetEntity'])->loadOneToOneEntity($assoc, $entity, null));
}
} else {
// Inject collection
$pColl = new PersistentCollection($this->em, $targetClass, new ArrayCollection());
$pColl->setOwner($entity, $assoc);
$reflField = $class->reflFields[$field];
$reflField->setValue($entity, $pColl);
if ($assoc['fetch'] == ClassMetadata::FETCH_LAZY) {
$pColl->setInitialized(false);
} else {
$this->loadCollection($pColl);
$pColl->takeSnapshot();
}
$this->originalEntityData[$oid][$field] = $pColl;
}
}
}
}
//TODO: These should be invoked later, after hydration, because associations may not yet be loaded here.
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;
}
示例8: mergeEntityStateIntoManagedCopy
/**
* @param object $entity
* @param object $managedCopy
*
* @throws ORMException
* @throws OptimisticLockException
* @throws TransactionRequiredException
*/
private function mergeEntityStateIntoManagedCopy($entity, $managedCopy)
{
$class = $this->em->getClassMetadata(get_class($entity));
foreach ($this->reflectionPropertiesGetter->getProperties($class->name) as $prop) {
$name = $prop->name;
$prop->setAccessible(true);
if (!isset($class->associationMappings[$name])) {
if (!$class->isIdentifier($name)) {
$prop->setValue($managedCopy, $prop->getValue($entity));
}
} else {
$assoc2 = $class->associationMappings[$name];
if ($assoc2['type'] & ClassMetadata::TO_ONE) {
$other = $prop->getValue($entity);
if ($other === null) {
$prop->setValue($managedCopy, null);
} else {
if ($other instanceof Proxy && !$other->__isInitialized()) {
// do not merge fields marked lazy that have not been fetched.
return;
}
if (!$assoc2['isCascadeMerge']) {
if ($this->getEntityState($other) === self::STATE_DETACHED) {
$targetClass = $this->em->getClassMetadata($assoc2['targetEntity']);
$relatedId = $targetClass->getIdentifierValues($other);
if ($targetClass->subClasses) {
$other = $this->em->find($targetClass->name, $relatedId);
} else {
$other = $this->em->getProxyFactory()->getProxy($assoc2['targetEntity'], $relatedId);
$this->registerManaged($other, $relatedId, array());
}
}
$prop->setValue($managedCopy, $other);
}
}
} else {
$mergeCol = $prop->getValue($entity);
if ($mergeCol instanceof PersistentCollection && !$mergeCol->isInitialized()) {
// do not merge fields marked lazy that have not been fetched.
// keep the lazy persistent collection of the managed copy.
return;
}
$managedCol = $prop->getValue($managedCopy);
if (!$managedCol) {
$managedCol = new PersistentCollection($this->em, $this->em->getClassMetadata($assoc2['targetEntity']), new ArrayCollection());
$managedCol->setOwner($managedCopy, $assoc2);
$prop->setValue($managedCopy, $managedCol);
$this->originalEntityData[spl_object_hash($entity)][$name] = $managedCol;
}
if ($assoc2['isCascadeMerge']) {
$managedCol->initialize();
// clear and set dirty a managed collection if its not also the same collection to merge from.
if (!$managedCol->isEmpty() && $managedCol !== $mergeCol) {
$managedCol->unwrap()->clear();
$managedCol->setDirty(true);
if ($assoc2['isOwningSide'] && $assoc2['type'] == ClassMetadata::MANY_TO_MANY && $class->isChangeTrackingNotify()) {
$this->scheduleForDirtyCheck($managedCopy);
}
}
}
}
}
if ($class->isChangeTrackingNotify()) {
// Just treat all properties as changed, there is no other choice.
$this->propertyChanged($managedCopy, $name, null, $prop->getValue($managedCopy));
}
}
}
示例9: createEntity
//.........这里部分代码省略.........
if ($assoc['type'] & ClassMetadata::TO_ONE) {
if ($assoc['isOwningSide']) {
$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;
} else {
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);
if (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 cann 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);
}
} else {
if ($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);
} else {
// Deferred eager load only works for single identifier classes
if ($hints['fetchMode'][$class->name][$field] == ClassMetadata::FETCH_EAGER) {
if (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);
} else {
// TODO: This is very imperformant, ignore it?
$newValue = $this->em->find($assoc['targetEntity'], $associatedId);
}
} else {
$newValue = $this->em->getProxyFactory()->getProxy($assoc['targetEntity'], $associatedId);
}
// 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!
}
}
$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);
}
}
} else {
// Inverse side of x-to-one can never be lazy
$class->reflFields[$field]->setValue($entity, $this->getEntityPersister($assoc['targetEntity'])->loadOneToOneEntity($assoc, $entity));
}
} else {
// Inject collection
$pColl = new PersistentCollection($this->em, $targetClass, new ArrayCollection());
$pColl->setOwner($entity, $assoc);
$reflField = $class->reflFields[$field];
$reflField->setValue($entity, $pColl);
if ($assoc['fetch'] == ClassMetadata::FETCH_EAGER) {
$this->loadCollection($pColl);
$pColl->takeSnapshot();
} else {
$pColl->setInitialized(false);
}
$this->originalEntityData[$oid][$field] = $pColl;
}
}
}
}
//TODO: These should be invoked later, after hydration, because associations may not yet be loaded here.
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;
}
示例10: _initRelatedCollection
/**
* Initializes a related collection.
*
* @param object $entity The entity to which the collection belongs.
* @param string $name The name of the field on the entity that holds the collection.
*/
private function _initRelatedCollection($entity, $class, $fieldName)
{
$oid = spl_object_hash($entity);
$relation = $class->associationMappings[$fieldName];
$value = $class->reflFields[$fieldName]->getValue($entity);
if ($value === null) {
$value = new ArrayCollection();
}
if (!$value instanceof PersistentCollection) {
$value = new PersistentCollection($this->_em, $this->_ce[$relation->targetEntityName], $value);
$value->setOwner($entity, $relation);
$class->reflFields[$fieldName]->setValue($entity, $value);
$this->_uow->setOriginalEntityProperty($oid, $fieldName, $value);
$this->_initializedCollections[$oid . $fieldName] = $value;
} else {
if (isset($this->_hints[Query::HINT_REFRESH])) {
// Is already PersistentCollection, but REFRESH
$value->setDirty(false);
$value->setInitialized(true);
$value->unwrap()->clear();
$this->_initializedCollections[$oid . $fieldName] = $value;
} else {
// Is already PersistentCollection, and DONT REFRESH
$this->_existingCollections[$oid . $fieldName] = $value;
}
}
return $value;
}
示例11: _computeEntityChanges
/**
* Computes the changes done to a single entity.
*
* Modifies/populates the following properties:
*
* {@link _originalEntityData}
* If the entity is NEW or MANAGED but not yet fully persisted (only has an id)
* then it was not fetched from the database and therefore we have no original
* entity data yet. All of the current entity data is stored as the original entity data.
*
* {@link _entityChangeSets}
* The changes detected on all properties of the entity are stored there.
* A change is a tuple array where the first entry is the old value and the second
* entry is the new value of the property. Changesets are used by persisters
* to INSERT/UPDATE the persistent entity state.
*
* {@link _entityUpdates}
* If the entity is already fully MANAGED (has been fetched from the database before)
* and any changes to its properties are detected, then a reference to the entity is stored
* there to mark it for an update.
*
* {@link _collectionDeletions}
* If a PersistentCollection has been de-referenced in a fully MANAGED entity,
* then this collection is marked for deletion.
*
* @param ClassMetadata $class The class descriptor of the entity.
* @param object $entity The entity for which to compute the changes.
*/
private function _computeEntityChanges($class, $entity)
{
$oid = spl_object_hash($entity);
if (!$class->isInheritanceTypeNone()) {
$class = $this->_em->getClassMetadata(get_class($entity));
}
$actualData = array();
foreach ($class->reflFields as $name => $refProp) {
if (!$class->isIdentifier($name) || !$class->isIdGeneratorIdentity()) {
$actualData[$name] = $refProp->getValue($entity);
}
if ($class->isCollectionValuedAssociation($name) && $actualData[$name] !== null && !$actualData[$name] instanceof PersistentCollection) {
//TODO: If $actualData[$name] is Collection then unwrap the array
$assoc = $class->associationMappings[$name];
//echo PHP_EOL . "INJECTING PCOLL into $name" . PHP_EOL;
// Inject PersistentCollection
$coll = new PersistentCollection($this->_em, $this->_em->getClassMetadata($assoc->targetEntityName), $actualData[$name] ? $actualData[$name] : array());
$coll->setOwner($entity, $assoc);
if (!$coll->isEmpty()) {
$coll->setDirty(true);
}
$class->reflFields[$name]->setValue($entity, $coll);
$actualData[$name] = $coll;
}
}
if (!isset($this->_originalEntityData[$oid])) {
// Entity is either NEW or MANAGED but not yet fully persisted
// (only has an id). These result in an INSERT.
$this->_originalEntityData[$oid] = $actualData;
$this->_entityChangeSets[$oid] = array_map(function ($e) {
return array(null, $e);
}, $actualData);
} else {
// Entity is "fully" MANAGED: it was already fully persisted before
// and we have a copy of the original data
$originalData = $this->_originalEntityData[$oid];
$changeSet = array();
$entityIsDirty = false;
foreach ($actualData as $propName => $actualValue) {
$orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null;
if (is_object($orgValue) && $orgValue !== $actualValue) {
$changeSet[$propName] = array($orgValue, $actualValue);
} else {
if ($orgValue != $actualValue || $orgValue === null ^ $actualValue === null) {
$changeSet[$propName] = array($orgValue, $actualValue);
}
}
if (isset($changeSet[$propName])) {
if (isset($class->associationMappings[$propName])) {
$assoc = $class->associationMappings[$propName];
if ($assoc->isOneToOne() && $assoc->isOwningSide) {
$entityIsDirty = true;
} else {
if ($orgValue instanceof PersistentCollection) {
// A PersistentCollection was de-referenced, so delete it.
if (!in_array($orgValue, $this->_collectionDeletions, true)) {
$this->_collectionDeletions[] = $orgValue;
}
}
}
} else {
$entityIsDirty = true;
}
}
}
if ($changeSet) {
if ($entityIsDirty) {
$this->_entityUpdates[$oid] = $entity;
}
$this->_entityChangeSets[$oid] = $changeSet;
$this->_originalEntityData[$oid] = $actualData;
}
//.........这里部分代码省略.........
示例12: _hydrateRow
//.........这里部分代码省略.........
$indexExists = isset($this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]]);
$index = $indexExists ? $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] : false;
$indexIsValid = $index !== false ? isset($reflFieldValue[$index]) : false;
if (!$indexExists || !$indexIsValid) {
if (isset($this->_existingCollections[$collKey])) {
// Collection exists, only look for the element in the identity map.
if ($element = $this->_getEntityFromIdentityMap($entityName, $data)) {
$this->_resultPointers[$dqlAlias] = $element;
} else {
unset($this->_resultPointers[$dqlAlias]);
}
} else {
$element = $this->_getEntity($data, $dqlAlias);
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
$field = $this->_rsm->indexByMap[$dqlAlias];
$indexValue = $this->_ce[$entityName]->reflFields[$field]->getValue($element);
$reflFieldValue->hydrateSet($indexValue, $element);
$this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $indexValue;
} else {
$reflFieldValue->hydrateAdd($element);
$reflFieldValue->last();
$this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $reflFieldValue->key();
}
// Update result pointer
$this->_resultPointers[$dqlAlias] = $element;
}
} else {
// Update result pointer
$this->_resultPointers[$dqlAlias] = $reflFieldValue[$index];
}
} else {
if (!$reflField->getValue($parentObject)) {
$coll = new PersistentCollection($this->_em, $this->_ce[$entityName], new ArrayCollection());
$coll->setOwner($parentObject, $relation);
$reflField->setValue($parentObject, $coll);
$this->_uow->setOriginalEntityProperty($oid, $relationField, $coll);
}
}
} else {
// PATH B: Single-valued association
$reflFieldValue = $reflField->getValue($parentObject);
if (!$reflFieldValue || isset($this->_hints[Query::HINT_REFRESH])) {
if (isset($nonemptyComponents[$dqlAlias])) {
$element = $this->_getEntity($data, $dqlAlias);
$reflField->setValue($parentObject, $element);
$this->_uow->setOriginalEntityProperty($oid, $relationField, $element);
$targetClass = $this->_ce[$relation['targetEntity']];
if ($relation['isOwningSide']) {
//TODO: Just check hints['fetched'] here?
// If there is an inverse mapping on the target class its bidirectional
if ($relation['inversedBy']) {
$inverseAssoc = $targetClass->associationMappings[$relation['inversedBy']];
if ($inverseAssoc['type'] & ClassMetadata::TO_ONE) {
$targetClass->reflFields[$inverseAssoc['fieldName']]->setValue($element, $parentObject);
$this->_uow->setOriginalEntityProperty(spl_object_hash($element), $inverseAssoc['fieldName'], $parentObject);
}
} else {
if ($parentClass === $targetClass && $relation['mappedBy']) {
// Special case: bi-directional self-referencing one-one on the same class
$targetClass->reflFields[$relationField]->setValue($element, $parentObject);
}
}
} else {
// For sure bidirectional, as there is no inverse side in unidirectional mappings
$targetClass->reflFields[$relation['mappedBy']]->setValue($element, $parentObject);
$this->_uow->setOriginalEntityProperty(spl_object_hash($element), $relation['mappedBy'], $parentObject);
开发者ID:MarS2806,项目名称:Zend-Framework--Doctrine-ORM--PHPUnit--Ant--Jenkins-CI--TDD-,代码行数:67,代码来源:ObjectHydrator.php
示例13: createEntity
//.........这里部分代码省略.........
$oid = spl_object_hash($entity);
if ($entity instanceof Proxy && !$entity->__isInitialized__) {
$entity->__isInitialized__ = true;
$overrideLocalValues = true;
} else {
$overrideLocalValues = isset($hints[Query::HINT_REFRESH]);
}
} else {
$entity = $class->newInstance();
$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) {
if ($this->_useCExtension) {
doctrine_populate_data($entity, $data);
} else {
foreach ($data as $field => $value) {
if (isset($class->reflFields[$field])) {
$class->reflFields[$field]->setValue($entity, $value);
}
}
}
// Properly initialize any unfetched associations, if partial objects are not allowed.
if (!isset($hints[Query::HINT_FORCE_PARTIAL_LOAD])) {
foreach ($class->associationMappings as $field => $assoc) {
// Check if the association is not among the fetch-joined associations already.
if (isset($hints['fetched'][$className][$field])) {
continue;
}
$targetClass = $this->_em->getClassMetadata($assoc->targetEntityName);
if ($assoc->isOneToOne()) {
if ($assoc->isOwningSide) {
$associatedId = array();
foreach ($assoc->targetToSourceKeyColumns as $targetColumn => $srcColumn) {
$joinColumnValue = $data[$srcColumn];
if ($joinColumnValue !== null) {
$associatedId[$targetClass->fieldNames[$targetColumn]] = $joinColumnValue;
}
}
if (!$associatedId) {
// Foreign key is NULL
$class->reflFields[$field]->setValue($entity, null);
$this->_originalEntityData[$oid][$field] = null;
} else {
// 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);
if (isset($this->_identityMap[$targetClass->rootEntityName][$relatedIdHash])) {
$newValue = $this->_identityMap[$targetClass->rootEntityName][$relatedIdHash];
} else {
if ($targetClass->subClasses) {
// If it might be a subtype, it can not be lazy
$newValue = $assoc->load($entity, null, $this->_em, $associatedId);
} else {
$newValue = $this->_em->getProxyFactory()->getProxy($assoc->targetEntityName, $associatedId);
$this->_entityIdentifiers[spl_object_hash($newValue)] = $associatedId;
$this->_identityMap[$targetClass->rootEntityName][$relatedIdHash] = $newValue;
}
}
$this->_originalEntityData[$oid][$field] = $newValue;
$class->reflFields[$field]->setValue($entity, $newValue);
}
} else {
// Inverse side of x-to-one can never be lazy
$class->reflFields[$field]->setValue($entity, $assoc->load($entity, null, $this->_em));
}
} else {
// Inject collection
$reflField = $class->reflFields[$field];
$pColl = new PersistentCollection($this->_em, $targetClass, $reflField->getValue($entity) ?: new ArrayCollection());
$pColl->setOwner($entity, $assoc);
$reflField->setValue($entity, $pColl);
if ($assoc->isLazilyFetched()) {
$pColl->setInitialized(false);
} else {
$assoc->load($entity, $pColl, $this->_em);
}
$this->_originalEntityData[$oid][$field] = $pColl;
}
}
}
}
//TODO: These should be invoked later, after hydration, because associations may not yet be loaded here.
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));
}
return $entity;
}
示例14: initRelatedCollection
/**
*
* @param object $entity
* @param string $name
* @todo Consider inlining this method.
*/
private function initRelatedCollection($entity, $name)
{
$oid = spl_object_hash($entity);
$classMetadata = $this->_ce[get_class($entity)];
$relation = $classMetadata->associationMappings[$name];
$relatedClass = $this->_em->getClassMetadata($relation->targetEntityName);
$coll = new PersistentCollection($this->_em, $relatedClass);
$this->_collections[] = $coll;
$coll->setOwner($entity, $relation);
$classMetadata->reflFields[$name]->setValue($entity, $coll);
$this->_uow->setOriginalEntityProperty($oid, $name, $coll);
$this->_initializedRelations[$oid][$name] = true;
return $coll;
}