diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index a3606d0b0..17e122ea9 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -443,9 +443,9 @@ class Doctrine_ORM_EntityManager /** * Deletes the persistent state of the given entity. * - * @param Doctrine\ORM\Entity $entity + * @param object $entity */ - public function delete(Doctrine_ORM_Entity $entity) + public function delete($entity) { $this->_errorIfNotActiveOrClosed(); $this->_unitOfWork->delete($entity); diff --git a/lib/Doctrine/ORM/Export/ClassExporter.php b/lib/Doctrine/ORM/Export/ClassExporter.php index 32d87286f..ed94b98a1 100644 --- a/lib/Doctrine/ORM/Export/ClassExporter.php +++ b/lib/Doctrine/ORM/Export/ClassExporter.php @@ -80,6 +80,23 @@ class Doctrine_ORM_Export_ClassExporter $columns[$mapping['columnName']] = $column; } + foreach ($class->getAssociationMappings() as $mapping) { + if ($mapping->isOneToOne() && $mapping->isOwningSide()) { + foreach ($mapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) { + $column = array(); + $column['name'] = $sourceColumn; + $column['type'] = $this->_em->getClassMetadata($mapping->getTargetEntityName()) + ->getTypeOfColumn($targetColumn); + $columns[$sourceColumn] = $column; + } + } else if ($mapping->isOneToMany() && $mapping->usesJoinTable()) { + //... create join table, one-many through join table supported later + throw new Doctrine_Exception("Not yet implemented."); + } else if ($mapping->isManyToMany() && $mapping->isOwningSide()) { + //... create join table + } + } + $this->_sm->createTable($class->getTableName(), $columns, $options); } } diff --git a/lib/Doctrine/ORM/Mapping/AssociationMapping.php b/lib/Doctrine/ORM/Mapping/AssociationMapping.php index 100c0e817..eb1488c28 100644 --- a/lib/Doctrine/ORM/Mapping/AssociationMapping.php +++ b/lib/Doctrine/ORM/Mapping/AssociationMapping.php @@ -26,7 +26,6 @@ * * @author Roman Borschel * @since 2.0 - * @todo Rename to AssociationMapping. */ abstract class Doctrine_ORM_Mapping_AssociationMapping { @@ -362,6 +361,11 @@ abstract class Doctrine_ORM_Mapping_AssociationMapping return false; } + public function usesJoinTable() + { + return (bool)$this->_joinTable; + } + abstract public function lazyLoadFor($entity, $entityManager); } diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index 86c289522..7888bebf6 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -77,6 +77,7 @@ class Doctrine_ORM_Mapping_Driver_AnnotationDriver { } else if ($oneToManyAnnot = $property->getAnnotation('DoctrineOneToMany')) { $mapping['mappedBy'] = $oneToManyAnnot->mappedBy; $mapping['targetEntity'] = $oneToManyAnnot->targetEntity; + $mapping['cascade'] = $oneToManyAnnot->cascade; $metadata->mapOneToMany($mapping); } else if ($manyToOneAnnot = $property->getAnnotation('DoctrineManyToOne')) { $mapping['joinColumns'] = $manyToOneAnnot->joinColumns; diff --git a/lib/Doctrine/ORM/Persisters/AbstractEntityPersister.php b/lib/Doctrine/ORM/Persisters/AbstractEntityPersister.php index 0a9ae2fdc..385f7482b 100644 --- a/lib/Doctrine/ORM/Persisters/AbstractEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/AbstractEntityPersister.php @@ -100,11 +100,17 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister /** * Updates an entity. * - * @param Doctrine\ORM\Entity $entity The entity to update. + * @param object $entity The entity to update. * @return void */ - public function update(Doctrine_ORM_Entity $entity) + public function update($entity) { + $updateData = array(); + $this->_prepareData($entity, $updateData); + $id = array_combine($this->_classMetadata->getIdentifierFieldNames(), + $this->_em->getUnitOfWork()->getEntityIdentifier($entity)); + $this->_conn->update($this->_classMetadata->getTableName(), $updateData, $id); + /*$dataChangeSet = $entity->_getDataChangeSet(); $referenceChangeSet = $entity->_getReferenceChangeSet(); @@ -126,12 +132,14 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister /** * Deletes an entity. * - * @param Doctrine\ORM\Entity $entity The entity to delete. + * @param object $entity The entity to delete. * @return void */ - public function delete(Doctrine_ORM_Entity $entity) + public function delete($entity) { - //TODO: perform delete + $id = array_combine($this->_classMetadata->getIdentifierFieldNames(), + $this->_em->getUnitOfWork()->getEntityIdentifier($entity)); + $this->_conn->delete($this->_classMetadata->getTableName(), $id); } /** @@ -232,7 +240,7 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister */ protected function _prepareData($entity, array &$result, $isInsert = false) { - foreach ($this->_em->getUnitOfWork()->getDataChangeSet($entity) as $field => $change) { + foreach ($this->_em->getUnitOfWork()->getEntityChangeSet($entity) as $field => $change) { if (is_array($change)) { list ($oldVal, $newVal) = each($change); } else { @@ -244,16 +252,21 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister $columnName = $this->_classMetadata->getColumnName($field); if ($this->_classMetadata->hasAssociation($field)) { - $assocMapping = $this->_classMetadata->getAssociationMapping($field); - if ( ! $assocMapping->isOneToOne() || $assocMapping->isInverseSide()) { - //echo "NOT TO-ONE OR INVERSE!"; - continue; - } - foreach ($assocMapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) { - //TODO: throw exc if field not set - $otherClass = $this->_em->getClassMetadata($assocMapping->getTargetEntityName()); - $result[$sourceColumn] = $otherClass->getReflectionProperty( - $otherClass->getFieldName($targetColumn))->getValue($newVal); + if ($newVal !== null) { + $assocMapping = $this->_classMetadata->getAssociationMapping($field); + if ( ! $assocMapping->isOneToOne() || $assocMapping->isInverseSide()) { + //echo "NOT TO-ONE OR INVERSE!"; + continue; + } + //echo "HERE!!!"; + foreach ($assocMapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) { + //TODO: throw exc if field not set + $otherClass = $this->_em->getClassMetadata($assocMapping->getTargetEntityName()); + $result[$sourceColumn] = $otherClass->getReflectionProperty( + $otherClass->getFieldName($targetColumn))->getValue($newVal); + } + } else if ( ! $isInsert) { + echo "NO INSERT AND NEWVAL NULL ON 1-1 ASSOC, OWNING SIDE"; } } else if (is_null($newVal)) { $result[$columnName] = null; diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 7e81d2d10..3b239b1d1 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -60,7 +60,7 @@ class Doctrine_ORM_UnitOfWork * @todo Not sure this is a good idea. It is a problematic solution because * it hides the original state while the locked state is active. */ - const STATE_LOCKED = 6; + //const STATE_LOCKED = 6; /** * A detached Entity is an instance with a persistent identity that is not @@ -109,7 +109,7 @@ class Doctrine_ORM_UnitOfWork * * @var array */ - protected $_dataChangeSets = array(); + protected $_entityChangeSets = array(); /** * The states of entities in this UnitOfWork. @@ -167,7 +167,7 @@ class Doctrine_ORM_UnitOfWork protected $_collectionUpdates = array(); /** - * The EntityManager the UnitOfWork belongs to. + * The EntityManager that "owns" this UnitOfWork instance. * * @var Doctrine\ORM\EntityManager */ @@ -182,8 +182,7 @@ class Doctrine_ORM_UnitOfWork protected $_commitOrderCalculator; /** - * Constructor. - * Creates a new UnitOfWork. + * Initializes a new UnitOfWork instance, bound to the given EntityManager. * * @param Doctrine\ORM\EntityManager $em */ @@ -203,7 +202,7 @@ class Doctrine_ORM_UnitOfWork public function commit() { // Compute changes in managed entities - $this->computeDataChangeSet(); + $this->computeEntityChangeSets(); if (empty($this->_newEntities) && empty($this->_deletedEntities) && @@ -238,42 +237,38 @@ class Doctrine_ORM_UnitOfWork $this->_newEntities = array(); $this->_dirtyEntities = array(); $this->_deletedEntities = array(); - $this->_dataChangeSets = array(); + $this->_entityChangeSets = array(); } /** - * Gets the data changeset for an entity. + * Gets the changeset for an entity. * * @return array */ - public function getDataChangeSet($entity) + public function getEntityChangeSet($entity) { $oid = spl_object_hash($entity); - if (isset($this->_dataChangeSets[$oid])) { - return $this->_dataChangeSets[$oid]; + if (isset($this->_entityChangeSets[$oid])) { + return $this->_entityChangeSets[$oid]; } return array(); } /** - * Computes all the changes that have been done to entities in the identity map - * since the last commit and stores these changes in _dataChangeSet temporarily - * for access by the persisters, until the UoW commit is finished. + * Computes all the changes that have been done to entities + * since the last commit and stores these changes in the _entityChangeSet map + * temporarily for access by the persisters, until the UoW commit is finished. * * @param array $entities The entities for which to compute the changesets. If this * parameter is not specified, the changesets of all entities in the identity * map are computed. */ - public function computeDataChangeSet(array $entities = null) + public function computeEntityChangeSets(array $entities = null) { $entitySet = array(); if ( ! is_null($entities)) { foreach ($entities as $entity) { - $className = get_class($entity); - if ( ! isset($entitySet[$className])) { - $entitySet[$className] = array(); - } - $entitySet[$className][] = $entity; + $entitySet[get_class($entity)][] = $entity; } } else { $entitySet = $this->_identityMap; @@ -294,23 +289,42 @@ class Doctrine_ORM_UnitOfWork $actualData[$name] = $refProp->getValue($entity); } - if ($state == self::STATE_NEW) { - $this->_dataChangeSets[$oid] = $actualData; + 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->_entityChangeSets[$oid] = $actualData; $this->_originalEntityData[$oid] = $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; + $orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null; if (is_object($orgValue) && $orgValue !== $actualValue) { $changeSet[$propName] = array($orgValue => $actualValue); } else if ($orgValue != $actualValue || (is_null($orgValue) xor is_null($actualValue))) { $changeSet[$propName] = array($orgValue => $actualValue); } + + if (isset($changeSet[$propName])) { + if ($class->hasAssociation($propName)) { + $assoc = $class->getAssociationMapping($propName); + if ($assoc->isOneToOne() && $assoc->isOwningSide()) { + $entityIsDirty = true; + } + $this->_handleAssociationValueChanged($assoc, $actualValue); + } else { + $entityIsDirty = true; + } + } } if ($changeSet) { - $this->_dirtyEntities[$oid] = $entity; - $this->_dataChangeSets[$oid] = $changeSet; + if ($entityIsDirty) { + $this->_dirtyEntities[$oid] = $entity; + } + $this->_entityChangeSets[$oid] = $changeSet; $this->_originalEntityData[$oid] = $actualData; } } @@ -319,6 +333,58 @@ class Doctrine_ORM_UnitOfWork } } + /** + * Handles the case during changeset computation where an association value + * has changed. For a to-one association this means a new associated instance + * has been set. For a to-many association this means a new associated collection/array + * of entities has been set. + * + * @param $assoc + * @param $value + */ + private function _handleAssociationValueChanged($assoc, $value) + { + if ($assoc->isOneToOne()) { + $value = array($value); + } + + $targetClass = $this->_em->getClassMetadata($assoc->getTargetEntityName()); + foreach ($value as $entry) { + $state = $this->getEntityState($entry); + $oid = spl_object_hash($entry); + if ($state == self::STATE_NEW) { + // Get identifier, if possible (not post-insert) + $idGen = $this->_em->getIdGenerator($targetClass->getClassName()); + if ( ! $idGen->isPostInsertGenerator()) { + $idValue = $idGen->generate($entry); + $this->_entityStates[$oid] = self::STATE_MANAGED; + if ( ! $idGen instanceof Doctrine_ORM_Id_Assigned) { + $this->_entityIdentifiers[$oid] = array($idValue); + $targetClass->getSingleIdReflectionProperty()->setValue($entry, $idValue); + } else { + $this->_entityIdentifiers[$oid] = $idValue; + } + $this->addToIdentityMap($entry); + } + + // NEW entities are INSERTed within the current unit of work. + $data = array(); + foreach ($targetClass->getReflectionProperties() as $name => $refProp) { + $data[$name] = $refProp->getValue($entry); + } + $oid = spl_object_hash($entry); + $this->_newEntities[$oid] = $entry; + $this->_entityChangeSets[$oid] = $data; + $this->_originalEntityData[$oid] = $data; + } else if ($state == self::STATE_DELETED) { + throw new Doctrine_Exception("Deleted entity in collection detected during flush."); + } + // MANAGED associated entities are already taken into account + // during changeset calculation anyway, since they are in the identity map. + } + + } + /** * Executes all entity insertions for entities of the specified type. * @@ -355,11 +421,10 @@ class Doctrine_ORM_UnitOfWork */ private function _executeUpdates($class) { - try { throw new Exception(); } catch (Exception $e) { echo $e->getTraceAsString(); } $className = $class->getClassName(); $persister = $this->_em->getEntityPersister($className); foreach ($this->_dirtyEntities as $entity) { - if ($entity->getClass()->getClassName() == $className) { + if (get_class($entity) == $className) { $persister->update($entity); } } @@ -375,7 +440,7 @@ class Doctrine_ORM_UnitOfWork $className = $class->getClassName(); $persister = $this->_em->getEntityPersister($className); foreach ($this->_deletedEntities as $entity) { - if ($entity->getClass()->getClassName() == $className) { + if (get_class($entity) == $className) { $persister->delete($entity); } } @@ -454,13 +519,13 @@ class Doctrine_ORM_UnitOfWork $oid = spl_object_hash($entity); if (isset($this->_dirtyEntities[$oid])) { - throw new Doctrine_Connection_Exception("Dirty object can't be registered as new."); + throw new Doctrine_Exception("Dirty object can't be registered as new."); } if (isset($this->_deletedEntities[$oid])) { - throw new Doctrine_Connection_Exception("Removed object can't be registered as new."); + throw new Doctrine_Exception("Removed object can't be registered as new."); } if (isset($this->_newEntities[$oid])) { - throw new Doctrine_Connection_Exception("Object already registered as new. Can't register twice."); + throw new Doctrine_Exception("Object already registered as new. Can't register twice."); } $this->_newEntities[$oid] = $entity; @@ -783,14 +848,14 @@ class Doctrine_ORM_UnitOfWork if ( ! empty($insertNow)) { // We have no choice. This means that there are new entities // with an IDENTITY column key generation strategy. - $this->computeDataChangeSet($insertNow); + $this->computeEntityChangeSets($insertNow); $commitOrder = $this->_getCommitOrder($insertNow); foreach ($commitOrder as $class) { $this->_executeInserts($class); } - // remove them from _newEntities and _dataChangeSets + // remove them from _newEntities and _entityChangeSets $this->_newEntities = array_diff_key($this->_newEntities, $insertNow); - $this->_dataChangeSets = array_diff_key($this->_dataChangeSets, $insertNow); + $this->_entityChangeSets = array_diff_key($this->_entityChangeSets, $insertNow); } } @@ -799,7 +864,7 @@ class Doctrine_ORM_UnitOfWork * This method is internally called during save() cascades as it tracks * the already visited entities to prevent infinite recursions. * - * @param Doctrine\ORM\Entity $entity The entity to save. + * @param object $entity The entity to save. * @param array $visited The already visited entities. */ private function _doSave($entity, array &$visited, array &$insertNow) @@ -822,10 +887,12 @@ class Doctrine_ORM_UnitOfWork $insertNow[$oid] = $entity; } else { $idValue = $idGen->generate($entity); - $this->_entityIdentifiers[$oid] = array($idValue); $this->_entityStates[$oid] = self::STATE_MANAGED; if ( ! $idGen instanceof Doctrine_ORM_Id_Assigned) { + $this->_entityIdentifiers[$oid] = array($idValue); $class->getSingleIdReflectionProperty()->setValue($entity, $idValue); + } else { + $this->_entityIdentifiers[$oid] = $idValue; } } $this->registerNew($entity); @@ -835,7 +902,7 @@ class Doctrine_ORM_UnitOfWork throw new Doctrine_Exception("Behavior of save() for a detached entity " . "is not yet defined."); case self::STATE_DELETED: - // $entity becomes managed again + // entity becomes managed again if ($this->isRegisteredRemoved($entity)) { //TODO: better a method for this? unset($this->_deletedEntities[$oid]); @@ -855,11 +922,12 @@ class Doctrine_ORM_UnitOfWork /** * Deletes an entity as part of the current unit of work. * - * @param Doctrine_ORM_Entity $entity + * @param object $entity */ public function delete($entity) { - $this->_doDelete($entity, array()); + $visited = array(); + $this->_doDelete($entity, $visited); } /** @@ -911,8 +979,8 @@ class Doctrine_ORM_UnitOfWork } $relatedEntities = $class->getReflectionProperty($assocMapping->getSourceFieldName()) ->getValue($entity); - if ($relatedEntities instanceof Doctrine_ORM_Collection && - count($relatedEntities) > 0) { + if (($relatedEntities instanceof Doctrine_ORM_Collection || is_array($relatedEntities)) + && count($relatedEntities) > 0) { foreach ($relatedEntities as $relatedEntity) { $this->_doSave($relatedEntity, $visited, $insertNow); } @@ -1151,6 +1219,9 @@ class Doctrine_ORM_UnitOfWork /** * Gets the identifier of an entity. + * The returned value is always an array of identifier values. If the entity + * has a composite primary key then the identifier values are in the same + * order as the identifier field names as returned by ClassMetadata#getIdentifierFieldNames(). * * @param object $entity * @return array The identifier values. diff --git a/tests/Orm/Functional/BasicCRUDTest.php b/tests/Orm/Functional/BasicCRUDTest.php index 8267c4e15..49489cc13 100644 --- a/tests/Orm/Functional/BasicCRUDTest.php +++ b/tests/Orm/Functional/BasicCRUDTest.php @@ -8,14 +8,14 @@ require_once 'lib/DoctrineTestInit.php'; * @author robo */ class Orm_Functional_BasicCRUDTest extends Doctrine_OrmFunctionalTestCase { - public function testFoo() { + public function testSingleEntityCRUD() { $em = $this->_getEntityManager(); $exporter = new Doctrine_ORM_Export_ClassExporter($em); $exporter->exportClasses(array( - $em->getClassMetadata('CmsUser'), - $em->getClassMetadata('CmsPhonenumber') - )); + $em->getClassMetadata('CmsUser'), + $em->getClassMetadata('CmsPhonenumber') + )); // Create $user = new CmsUser; @@ -24,25 +24,33 @@ class Orm_Functional_BasicCRUDTest extends Doctrine_OrmFunctionalTestCase { $this->assertTrue(is_numeric($user->id)); $this->assertTrue($em->contains($user)); - $user2 = new CmsUser; - $user2->name = 'jwage'; - $em->save($user2); - $this->assertTrue(is_numeric($user2->id)); - $this->assertTrue($em->contains($user2)); - // Read - $user3 = $em->find('CmsUser', $user->id); - $this->assertTrue($user === $user3); - - $user4 = $em->find('CmsUser', $user2->id); - $this->assertTrue($user2 === $user4); + $user2 = $em->find('CmsUser', $user->id); + $this->assertTrue($user === $user2); + // Add a phonenumber $ph = new CmsPhonenumber; $ph->phonenumber = "12345"; + $user->addPhonenumber($ph); + $em->flush(); + $this->assertTrue($em->contains($ph)); + $this->assertTrue($em->contains($user)); - $user->phonenumbers[] = $ph; + // Update + $user->name = 'guilherme'; + $em->flush(); + $this->assertEquals('guilherme', $user->name); - //var_dump($em->getUnitOfWork()) + // Delete + $em->delete($user); + $this->assertTrue($em->getUnitOfWork()->isRegisteredRemoved($user)); + $em->flush(); + $this->assertFalse($em->getUnitOfWork()->isRegisteredRemoved($user)); + + } + + public function testMore() { + } } diff --git a/tests/Orm/UnitOfWorkTest.php b/tests/Orm/UnitOfWorkTest.php index cf91d84d0..b24ba73bf 100644 --- a/tests/Orm/UnitOfWorkTest.php +++ b/tests/Orm/UnitOfWorkTest.php @@ -119,15 +119,21 @@ class Orm_UnitOfWorkTest extends Doctrine_OrmTestCase $this->assertEquals(0, count($avatarPersister->getDeletes())); } - public function testComputeDataChangeSet() + public function testComputeEntityChangeSets() { + // We need an ID generator for ForumAvatar, because we attach a NEW ForumAvatar + // to a (faked) MANAGED instance. During changeset computation this will result + // in the UnitOfWork requesting the Id generator of ForumAvatar. + $avatarIdGeneratorMock = new Doctrine_IdentityIdGeneratorMock($this->_emMock); + $this->_emMock->setIdGenerator('ForumAvatar', $avatarIdGeneratorMock); + $user1 = new ForumUser(); $user1->id = 1; $user1->username = "romanb"; $user1->avatar = new ForumAvatar(); // Fake managed state $this->_unitOfWork->setEntityState($user1, Doctrine_ORM_UnitOfWork::STATE_MANAGED); - + $user2 = new ForumUser(); $user2->id = 2; $user2->username = "jwage"; @@ -143,10 +149,10 @@ class Orm_UnitOfWorkTest extends Doctrine_OrmTestCase )); // Go - $this->_unitOfWork->computeDataChangeSet(array($user1, $user2)); + $this->_unitOfWork->computeEntityChangeSets(array($user1, $user2)); // Verify - $user1ChangeSet = $this->_unitOfWork->getDataChangeSet($user1); + $user1ChangeSet = $this->_unitOfWork->getEntityChangeSet($user1); $this->assertTrue(is_array($user1ChangeSet)); $this->assertEquals(2, count($user1ChangeSet)); $this->assertTrue(isset($user1ChangeSet['username'])); @@ -154,7 +160,7 @@ class Orm_UnitOfWorkTest extends Doctrine_OrmTestCase $this->assertTrue(isset($user1ChangeSet['avatar'])); $this->assertSame(array(null => $user1->avatar), $user1ChangeSet['avatar']); - $user2ChangeSet = $this->_unitOfWork->getDataChangeSet($user2); + $user2ChangeSet = $this->_unitOfWork->getEntityChangeSet($user2); $this->assertTrue(is_array($user2ChangeSet)); $this->assertEquals(1, count($user2ChangeSet)); $this->assertTrue(isset($user2ChangeSet['username'])); diff --git a/tests/lib/mocks/Doctrine_EntityManagerMock.php b/tests/lib/mocks/Doctrine_EntityManagerMock.php index 35534cda8..b17fbeca3 100644 --- a/tests/lib/mocks/Doctrine_EntityManagerMock.php +++ b/tests/lib/mocks/Doctrine_EntityManagerMock.php @@ -81,6 +81,7 @@ class Doctrine_EntityManagerMock extends Doctrine_ORM_EntityManager $this->_idGenerators[$className] = $generator; } + /** @override */ public function getIdGenerator($className) { if (isset($this->_idGenerators[$className])) { diff --git a/tests/lib/mocks/Doctrine_UnitOfWorkMock.php b/tests/lib/mocks/Doctrine_UnitOfWorkMock.php index eab783d82..cf14e2b44 100644 --- a/tests/lib/mocks/Doctrine_UnitOfWorkMock.php +++ b/tests/lib/mocks/Doctrine_UnitOfWorkMock.php @@ -14,10 +14,10 @@ class Doctrine_UnitOfWorkMock extends Doctrine_ORM_UnitOfWork { * @param $entity * @override */ - public function getDataChangeSet($entity) { + public function getEntityChangeSet($entity) { $oid = spl_object_hash($entity); return isset($this->_mockDataChangeSets[$oid]) ? - $this->_mockDataChangeSets[$oid] : parent::getDataChangeSet($entity); + $this->_mockDataChangeSets[$oid] : parent::getEntityChangeSet($entity); } /* MOCK API */ diff --git a/tests/models/cms/CmsPhonenumber.php b/tests/models/cms/CmsPhonenumber.php index 3ff3d342a..e7494db78 100755 --- a/tests/models/cms/CmsPhonenumber.php +++ b/tests/models/cms/CmsPhonenumber.php @@ -3,7 +3,7 @@ /** * @DoctrineEntity */ -class CmsPhonenumber implements Doctrine_ORM_Entity +class CmsPhonenumber { /** * @DoctrineColumn(type="varchar", length=50) @@ -14,4 +14,9 @@ class CmsPhonenumber implements Doctrine_ORM_Entity * @DoctrineManyToOne(targetEntity="CmsUser", joinColumns={"user_id" = "id"}) */ public $user; + + public function setUser(CmsUser $user) { + $this->user = $user; + $user->addPhonenumber($this); + } } diff --git a/tests/models/cms/CmsUser.php b/tests/models/cms/CmsUser.php index 052653f8a..91750e8e8 100644 --- a/tests/models/cms/CmsUser.php +++ b/tests/models/cms/CmsUser.php @@ -33,4 +33,14 @@ class CmsUser * @DoctrineOneToMany(targetEntity="CmsArticle", mappedBy="user") */ public $articles; + + /** + * Adds a phonenumber to the user. + * + * @param $phone + */ + public function addPhonenumber(CmsPhonenumber $phone) { + $this->phonenumbers[] = $phone; + $phone->user = $this; + } }