[2.0] Fixed DDC-18. Simplified proxy classes. Just 1 proxy class per entity now, instead of 2.
This commit is contained in:
parent
aa72619c5d
commit
f572c372dc
@ -323,7 +323,7 @@ class EntityManager
|
||||
if ( ! is_array($identifier)) {
|
||||
$identifier = array($class->identifier[0] => $identifier);
|
||||
}
|
||||
$entity = $this->_proxyFactory->getReferenceProxy($entityName, $identifier);
|
||||
$entity = $this->_proxyFactory->getProxy($entityName, $identifier);
|
||||
$this->_unitOfWork->registerManaged($entity, $identifier, array());
|
||||
|
||||
return $entity;
|
||||
|
@ -75,7 +75,6 @@ class ObjectHydrator extends AbstractHydrator
|
||||
if (isset($this->_rsm->relationMap[$dqlAlias])) {
|
||||
$targetClassName = $this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]];
|
||||
$targetClass = $this->_getClassMetadata($targetClassName);
|
||||
$this->_ce[$targetClassName] = $targetClass;
|
||||
$assoc = $targetClass->associationMappings[$this->_rsm->relationMap[$dqlAlias]];
|
||||
$this->_hints['fetched'][$assoc->sourceEntityName][$assoc->sourceFieldName] = true;
|
||||
if ($assoc->mappedByFieldName) {
|
||||
|
@ -8,4 +8,9 @@ class ORMException extends \Exception
|
||||
{
|
||||
return new self("Entity of type " . get_class($entity) . " is missing an assigned ID.");
|
||||
}
|
||||
|
||||
public static function unrecognizedField($field)
|
||||
{
|
||||
return new self("Unrecognized field: $field");
|
||||
}
|
||||
}
|
||||
|
@ -368,7 +368,8 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect
|
||||
$removed = $this->_coll->remove($key);
|
||||
if ($removed) {
|
||||
$this->_changed();
|
||||
if ($this->_association->isOneToMany() && $this->_association->orphanRemoval) {
|
||||
if ($this->_association !== null && $this->_association->isOneToMany() &&
|
||||
$this->_association->orphanRemoval) {
|
||||
$this->_em->getUnitOfWork()->scheduleOrphanRemoval($removed);
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
namespace Doctrine\ORM\Persisters;
|
||||
|
||||
use Doctrine\Common\DoctrineException,
|
||||
Doctrine\ORM\ORMException,
|
||||
Doctrine\Common\Collections\ArrayCollection,
|
||||
Doctrine\DBAL\Connection,
|
||||
Doctrine\DBAL\Types\Type,
|
||||
@ -410,13 +411,6 @@ class StandardEntityPersister
|
||||
public function load(array $criteria, $entity = null, $assoc = null)
|
||||
{
|
||||
$stmt = $this->_conn->prepare($this->_getSelectEntitiesSql($criteria, $assoc));
|
||||
if ($stmt === null) {
|
||||
try {
|
||||
throw new \Exception();
|
||||
} catch (\Exception $e) {
|
||||
var_dump($e->getTraceAsString());
|
||||
}
|
||||
}
|
||||
$stmt->execute(array_values($criteria));
|
||||
$result = $stmt->fetch(Connection::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
@ -464,12 +458,10 @@ class StandardEntityPersister
|
||||
|
||||
if ($assoc->isOwningSide) {
|
||||
$joinColumnValues = array();
|
||||
$targetColumns = array();
|
||||
foreach ($assoc->targetToSourceKeyColumns as $targetColumn => $srcColumn) {
|
||||
if ($metaColumns[$srcColumn] !== null) {
|
||||
$joinColumnValues[] = $metaColumns[$srcColumn];
|
||||
$joinColumnValues[$targetColumn] = $metaColumns[$srcColumn];
|
||||
}
|
||||
$targetColumns[] = $targetColumn;
|
||||
}
|
||||
if ( ! $joinColumnValues && $value !== null) {
|
||||
$this->_class->reflFields[$field]->setValue($entity, null);
|
||||
@ -486,16 +478,16 @@ class StandardEntityPersister
|
||||
$targetClass->reflFields[$inverseAssoc->sourceFieldName]->setValue($found, $entity);
|
||||
}
|
||||
$newData[$field] = $found;
|
||||
} else if ((array)$this->_class->getIdentifierValues($value) != $joinColumnValues) {
|
||||
$proxy = $this->_em->getProxyFactory()->getAssociationProxy($entity, $assoc, $joinColumnValues);
|
||||
} else {
|
||||
$proxy = $this->_em->getProxyFactory()->getProxy($assoc->targetEntityName, $joinColumnValues);
|
||||
$this->_class->reflFields[$field]->setValue($entity, $proxy);
|
||||
$newData[$field] = $proxy;
|
||||
$this->_em->getUnitOfWork()->addToIdentityMap($proxy);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Inverse side of 1-1/1-x can never be lazy
|
||||
$assoc->load($entity, null, $this->_em);
|
||||
$newData[$field] = $this->_class->reflFields[$field]->getValue($entity);
|
||||
// Inverse side of 1-1/1-x can never be lazy.
|
||||
$newData[$field] = $assoc->load($entity, null, $this->_em);
|
||||
}
|
||||
} else if ($value instanceof PersistentCollection && $value->isInitialized()) {
|
||||
$value->setInitialized(false);
|
||||
@ -643,10 +635,12 @@ class StandardEntityPersister
|
||||
|
||||
if (isset($this->_class->columnNames[$field])) {
|
||||
$conditionSql .= $this->_class->getQuotedColumnName($field, $this->_platform);
|
||||
} else if (isset($this->_class->fieldNames[$field])) {
|
||||
$conditionSql .= $this->_class->getQuotedColumnName($this->_class->fieldNames[$field], $this->_platform);
|
||||
} else if ($assoc !== null) {
|
||||
$conditionSql .= $assoc->getQuotedJoinColumnName($field, $this->_platform);
|
||||
} else {
|
||||
throw DoctrineException::unrecognizedField($field);
|
||||
throw ORMException::unrecognizedField($field);
|
||||
}
|
||||
$conditionSql .= ' = ?';
|
||||
}
|
||||
|
@ -75,9 +75,9 @@ class ProxyFactory
|
||||
* @param mixed $identifier
|
||||
* @return object
|
||||
*/
|
||||
public function getReferenceProxy($className, $identifier)
|
||||
public function getProxy($className, $identifier)
|
||||
{
|
||||
$proxyClassName = str_replace('\\', '', $className) . 'RProxy';
|
||||
$proxyClassName = str_replace('\\', '', $className) . 'Proxy';
|
||||
$fqn = $this->_proxyNamespace . '\\' . $proxyClassName;
|
||||
|
||||
if ($this->_autoGenerate && ! class_exists($fqn, false)) {
|
||||
@ -95,32 +95,6 @@ class ProxyFactory
|
||||
return new $fqn($entityPersister, $identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an association proxy instance.
|
||||
*
|
||||
* @param object $owner
|
||||
* @param AssociationMapping $assoc
|
||||
* @param array $joinColumnValues
|
||||
* @return object
|
||||
*/
|
||||
public function getAssociationProxy($owner, AssociationMapping $assoc, array $joinColumnValues)
|
||||
{
|
||||
$proxyClassName = str_replace('\\', '', $assoc->targetEntityName) . 'AProxy';
|
||||
$fqn = $this->_proxyNamespace . '\\' . $proxyClassName;
|
||||
|
||||
if ($this->_autoGenerate && ! class_exists($fqn, false)) {
|
||||
$fileName = $this->_proxyDir . DIRECTORY_SEPARATOR . $proxyClassName . '.php';
|
||||
$this->_generateProxyClass($this->_em->getClassMetadata($assoc->targetEntityName), $proxyClassName, $fileName, self::$_assocProxyClassTemplate);
|
||||
require $fileName;
|
||||
}
|
||||
|
||||
if ( ! $this->_em->getMetadataFactory()->hasMetadataFor($fqn)) {
|
||||
$this->_em->getMetadataFactory()->setMetadataFor($fqn, $this->_em->getClassMetadata($assoc->targetEntityName));
|
||||
}
|
||||
|
||||
return new $fqn($this->_em, $assoc, $owner, $joinColumnValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates proxy classes for all given classes.
|
||||
*
|
||||
@ -134,12 +108,9 @@ class ProxyFactory
|
||||
$proxyDir = $toDir ?: $this->_proxyDir;
|
||||
$proxyDir = rtrim($proxyDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
foreach ($classes as $class) {
|
||||
$AproxyClassName = str_replace('\\', '', $class->name) . 'AProxy';
|
||||
$RproxyClassName = str_replace('\\', '', $class->name) . 'RProxy';
|
||||
$AproxyFileName = $proxyDir . $AproxyClassName . '.php';
|
||||
$RproxyFileName = $proxyDir . $RproxyClassName . '.php';
|
||||
$this->_generateProxyClass($class, $RproxyClassName, $RproxyFileName, self::$_proxyClassTemplate);
|
||||
$this->_generateProxyClass($class, $AproxyClassName, $AproxyFileName, self::$_assocProxyClassTemplate);
|
||||
$proxyClassName = str_replace('\\', '', $class->name) . 'Proxy';
|
||||
$proxyFileName = $proxyDir . $proxyClassName . '.php';
|
||||
$this->_generateProxyClass($class, $proxyClassName, $proxyFileName, self::$_proxyClassTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -301,47 +272,4 @@ namespace <namespace> {
|
||||
}
|
||||
}
|
||||
}';
|
||||
|
||||
/** Association Proxy class code template */
|
||||
private static $_assocProxyClassTemplate =
|
||||
'<?php
|
||||
namespace <namespace> {
|
||||
/**
|
||||
* THIS CLASS WAS GENERATED BY THE DOCTRINE ORM. DO NOT EDIT THIS FILE.
|
||||
*/
|
||||
class <proxyClassName> extends \<className> implements \Doctrine\ORM\Proxy\Proxy {
|
||||
private $_em;
|
||||
private $_assoc;
|
||||
private $_owner;
|
||||
private $_joinColumnValues;
|
||||
private $_loaded = false;
|
||||
public function __construct($em, $assoc, $owner, array $joinColumnValues) {
|
||||
$this->_em = $em;
|
||||
$this->_assoc = $assoc;
|
||||
$this->_owner = $owner;
|
||||
$this->_joinColumnValues = $joinColumnValues;
|
||||
<constructorInvocation>
|
||||
}
|
||||
private function _load() {
|
||||
if ( ! $this->_loaded) {
|
||||
$this->_assoc->load($this->_owner, $this, $this->_em, $this->_joinColumnValues);
|
||||
unset($this->_em);
|
||||
unset($this->_owner);
|
||||
unset($this->_assoc);
|
||||
unset($this->_joinColumnValues);
|
||||
$this->_loaded = true;
|
||||
}
|
||||
}
|
||||
public function __isInitialized__() { return $this->_loaded; }
|
||||
|
||||
<methods>
|
||||
|
||||
public function __sleep() {
|
||||
if (!$this->_loaded) {
|
||||
throw new \RuntimeException("Not fully loaded proxy can not be serialized.");
|
||||
}
|
||||
<sleepImpl>
|
||||
}
|
||||
}
|
||||
}';
|
||||
}
|
||||
|
@ -59,8 +59,7 @@ final class Query extends AbstractQuery
|
||||
const HINT_REFRESH = 'doctrine.refresh';
|
||||
/**
|
||||
* The forcePartialLoad query hint forces a particular query to return
|
||||
* partial objects when partial objects in general are disallowed in the
|
||||
* configuration.
|
||||
* partial objects.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
@ -1330,10 +1330,17 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$prop->setValue($managedCopy, $prop->getValue($entity));
|
||||
} else {
|
||||
$assoc2 = $class->associationMappings[$name];
|
||||
if ($assoc2->isOneToOne() && ! $assoc2->isCascadeMerge) {
|
||||
$targetClass = $this->_em->getClassMetadata($assoc2->targetEntityName);
|
||||
$prop->setValue($managedCopy, $this->_em->getProxyFactory()
|
||||
->getReferenceProxy($assoc2->targetEntityName, $targetClass->getIdentifierValues($entity)));
|
||||
if ($assoc2->isOneToOne()) {
|
||||
if ( ! $assoc2->isCascadeMerge) {
|
||||
$other = $class->reflFields[$name]->getValue($entity);
|
||||
if ($other !== null) {
|
||||
$targetClass = $this->_em->getClassMetadata($assoc2->targetEntityName);
|
||||
$id = $targetClass->getIdentifierValues($other);
|
||||
$proxy = $this->_em->getProxyFactory()->getProxy($assoc2->targetEntityName, $id);
|
||||
$prop->setValue($managedCopy, $proxy);
|
||||
$this->registerManaged($proxy, (array)$id, array());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$coll = new PersistentCollection($this->_em,
|
||||
$this->_em->getClassMetadata($assoc2->targetEntityName),
|
||||
@ -1695,49 +1702,59 @@ class UnitOfWork implements PropertyChangedListener
|
||||
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])) {
|
||||
if ($assoc->isOneToOne()) {
|
||||
if ($assoc->isOwningSide) {
|
||||
$joinColumns = array();
|
||||
foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
|
||||
$joinColumnValue = $data[$assoc->joinColumnFieldNames[$srcColumn]];
|
||||
if ($joinColumnValue !== null) {
|
||||
$joinColumns[$srcColumn] = $joinColumnValue;
|
||||
}
|
||||
}
|
||||
if ( ! $joinColumns) {
|
||||
$class->reflFields[$field]->setValue($entity, null);
|
||||
$this->_originalEntityData[$oid][$field] = null;
|
||||
} else {
|
||||
//TODO: If its in the identity map just get it from there if possible!
|
||||
// Inject proxy
|
||||
$proxy = $this->_em->getProxyFactory()->getAssociationProxy($entity, $assoc, $joinColumns);
|
||||
$this->_originalEntityData[$oid][$field] = $proxy;
|
||||
$class->reflFields[$field]->setValue($entity, $proxy);
|
||||
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[$targetColumn] = $joinColumnValue;
|
||||
}
|
||||
}
|
||||
if ( ! $associatedId) {
|
||||
$class->reflFields[$field]->setValue($entity, null);
|
||||
$this->_originalEntityData[$oid][$field] = null;
|
||||
} else {
|
||||
// Inverse side can never be lazy.
|
||||
$targetEntity = $assoc->load($entity, new $assoc->targetEntityName, $this->_em);
|
||||
$class->reflFields[$field]->setValue($entity, $targetEntity);
|
||||
// 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 {
|
||||
$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 {
|
||||
// Inject collection
|
||||
$reflField = $class->reflFields[$field];
|
||||
$pColl = new PersistentCollection(
|
||||
$this->_em,
|
||||
$this->_em->getClassMetadata($assoc->targetEntityName),
|
||||
$reflField->getValue($entity) ?: new ArrayCollection
|
||||
);
|
||||
$pColl->setOwner($entity, $assoc);
|
||||
$reflField->setValue($entity, $pColl);
|
||||
if ($assoc->isLazilyFetched()) {
|
||||
$pColl->setInitialized(false);
|
||||
} else {
|
||||
//TODO: Allow more efficient and configurable batching of these loads
|
||||
$assoc->load($entity, $pColl, $this->_em);
|
||||
}
|
||||
$this->_originalEntityData[$oid][$field] = $pColl;
|
||||
// Inverse side can never be lazy
|
||||
$targetEntity = $assoc->load($entity, new $assoc->targetEntityName, $this->_em);
|
||||
$class->reflFields[$field]->setValue($entity, $targetEntity);
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,8 +74,6 @@ class DetachedEntityTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
$this->_em->persist($ph2);
|
||||
|
||||
//$removed = $user->removePhonenumber(1); // [romanb] this is currently broken, I'm on it.
|
||||
|
||||
// Merge back in
|
||||
$user = $this->_em->merge($user); // merge cascaded to phonenumbers
|
||||
$this->_em->flush();
|
||||
|
@ -38,7 +38,7 @@ class ReferenceProxyTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
$id = $product->getId();
|
||||
|
||||
$productProxy = $this->_factory->getReferenceProxy('Doctrine\Tests\Models\ECommerce\ECommerceProduct', array('id' => $id));
|
||||
$productProxy = $this->_factory->getProxy('Doctrine\Tests\Models\ECommerce\ECommerceProduct', array('id' => $id));
|
||||
$this->assertEquals('Doctrine Cookbook', $productProxy->getName());
|
||||
}
|
||||
}
|
||||
|
@ -122,12 +122,12 @@ class ObjectHydratorTest extends HydrationTestCase
|
||||
);
|
||||
|
||||
// mocking the proxy factory
|
||||
$proxyFactory = $this->getMock('Doctrine\ORM\Proxy\ProxyFactory', array('getAssociationProxy'), array(), '', false, false, false);
|
||||
$proxyFactory = $this->getMock('Doctrine\ORM\Proxy\ProxyFactory', array('getProxy'), array(), '', false, false, false);
|
||||
$proxyFactory->expects($this->once())
|
||||
->method('getAssociationProxy')
|
||||
->with($this->isInstanceOf('Doctrine\Tests\Models\ECommerce\ECommerceProduct'),
|
||||
$this->isInstanceOf('Doctrine\ORM\Mapping\OneToOneMapping'),
|
||||
array('shipping_id' => 42));
|
||||
->method('getProxy')
|
||||
->with($this->equalTo('Doctrine\Tests\Models\ECommerce\ECommerceShipping'),
|
||||
array('id' => 42))
|
||||
->will($this->returnValue(new \stdClass));
|
||||
|
||||
$this->_em->setProxyFactory($proxyFactory);
|
||||
|
||||
|
@ -48,11 +48,11 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testReferenceProxyDelegatesLoadingToThePersister()
|
||||
{
|
||||
$identifier = array('id' => 42);
|
||||
$proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureRProxy';
|
||||
$proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureProxy';
|
||||
$persister = $this->_getMockPersister();
|
||||
$this->_uowMock->setEntityPersister('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $persister);
|
||||
|
||||
$proxy = $this->_proxyFactory->getReferenceProxy('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $identifier);
|
||||
$proxy = $this->_proxyFactory->getProxy('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $identifier);
|
||||
|
||||
$persister->expects($this->atLeastOnce())
|
||||
->method('load')
|
||||
@ -64,10 +64,10 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
public function testReferenceProxyExecutesLoadingOnlyOnce()
|
||||
{
|
||||
$identifier = array('id' => 42);
|
||||
$proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureRProxy';
|
||||
$proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureProxy';
|
||||
$persister = $this->_getMockPersister();
|
||||
$this->_uowMock->setEntityPersister('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $persister);
|
||||
$proxy = $this->_proxyFactory->getReferenceProxy('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $identifier);
|
||||
$proxy = $this->_proxyFactory->getProxy('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $identifier);
|
||||
$persister->expects($this->atLeastOnce())
|
||||
->method('load')
|
||||
->with($this->equalTo($identifier), $this->isInstanceOf($proxyClass));
|
||||
@ -77,10 +77,10 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
public function testReferenceProxyRespectsMethodsParametersTypeHinting()
|
||||
{
|
||||
$proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureRProxy';
|
||||
$proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureProxy';
|
||||
$persister = $this->_getMockPersister();
|
||||
$this->_uowMock->setEntityPersister('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $persister);
|
||||
$proxy = $this->_proxyFactory->getReferenceProxy('Doctrine\Tests\Models\ECommerce\ECommerceFeature', null);
|
||||
$proxy = $this->_proxyFactory->getProxy('Doctrine\Tests\Models\ECommerce\ECommerceFeature', null);
|
||||
|
||||
$method = new \ReflectionMethod(get_class($proxy), 'setProduct');
|
||||
$params = $method->getParameters();
|
||||
@ -91,43 +91,18 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
public function testCreatesAssociationProxyAsSubclassOfTheOriginalOne()
|
||||
{
|
||||
$proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureRProxy';
|
||||
$proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureProxy';
|
||||
$this->assertTrue(is_subclass_of($proxyClass, 'Doctrine\Tests\Models\ECommerce\ECommerceFeature'));
|
||||
}
|
||||
|
||||
|
||||
public function testAllowsConcurrentCreationOfBothProxyTypes()
|
||||
{
|
||||
$referenceProxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureRProxy';
|
||||
$referenceProxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureProxy';
|
||||
$associationProxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureAProxy';
|
||||
$this->assertNotEquals($referenceProxyClass, $associationProxyClass);
|
||||
}
|
||||
|
||||
public function testAssociationProxyDelegatesLoadingToTheAssociation()
|
||||
{
|
||||
$proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureAProxy';
|
||||
$product = new ECommerceProduct;
|
||||
$foreignKeys = array('customer_id' => 42);
|
||||
$assoc = $this->_getAssociationMock();
|
||||
$assoc->targetEntityName = 'Doctrine\Tests\Models\ECommerce\ECommerceFeature';
|
||||
$proxy = $this->_proxyFactory->getAssociationProxy($product, $assoc, $foreignKeys);
|
||||
$assoc->expects($this->atLeastOnce())
|
||||
->method('load')
|
||||
->with($product, $this->isInstanceOf($proxyClass), $this->isInstanceOf('Doctrine\Tests\Mocks\EntityManagerMock'), $foreignKeys);
|
||||
$proxy->getDescription();
|
||||
}
|
||||
|
||||
public function testAssociationProxyExecutesLoadingOnlyOnce()
|
||||
{
|
||||
$proxyClass = 'Proxies\DoctrineTestsModelsECommerceECommerceFeatureAProxy';
|
||||
$assoc = $this->_getAssociationMock();
|
||||
$assoc->targetEntityName = 'Doctrine\Tests\Models\ECommerce\ECommerceFeature';
|
||||
$proxy = $this->_proxyFactory->getAssociationProxy(null, $assoc, array());
|
||||
$assoc->expects($this->once())->method('load');
|
||||
$proxy->getDescription();
|
||||
$proxy->getDescription();
|
||||
}
|
||||
|
||||
protected function _getAssociationMock()
|
||||
{
|
||||
$assoc = $this->getMock('Doctrine\ORM\Mapping\AssociationMapping', array('load'), array(), '', false, false, false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user