3 namespace Doctrine\Tests\ORM\Functional;
5 use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
6 use Doctrine\ORM\Mapping\AssociationMapping;
7 use Doctrine\ORM\Mapping\ClassMetadata;
9 require_once __DIR__ . '/../../TestInit.php';
12 * Tests a self referential many-to-many association mapping (from a model to the same model, without inheritance).
13 * For simplicity the relation duplicates entries in the association table
14 * to remain simmetrical.
16 class ManyToManySelfReferentialAssociationTest extends AbstractManyToManyAssociationTestCase
18 protected $_firstField = 'product_id';
19 protected $_secondField = 'related_id';
20 protected $_table = 'ecommerce_products_related';
21 private $firstProduct;
22 private $secondProduct;
23 private $firstRelated;
24 private $secondRelated;
26 protected function setUp()
28 $this->useModelSet('ecommerce');
30 $this->firstProduct = new ECommerceProduct();
31 $this->secondProduct = new ECommerceProduct();
32 $this->firstRelated = new ECommerceProduct();
33 $this->firstRelated->setName("Business");
34 $this->secondRelated = new ECommerceProduct();
35 $this->secondRelated->setName("Home");
38 public function testSavesAManyToManyAssociationWithCascadeSaveSet()
40 $this->firstProduct->addRelated($this->firstRelated);
41 $this->firstProduct->addRelated($this->secondRelated);
42 $this->_em->persist($this->firstProduct);
45 $this->assertForeignKeysContain($this->firstProduct->getId(),
46 $this->firstRelated->getId());
47 $this->assertForeignKeysContain($this->firstProduct->getId(),
48 $this->secondRelated->getId());
51 public function testRemovesAManyToManyAssociation()
53 $this->firstProduct->addRelated($this->firstRelated);
54 $this->firstProduct->addRelated($this->secondRelated);
55 $this->_em->persist($this->firstProduct);
56 $this->firstProduct->removeRelated($this->firstRelated);
60 $this->assertForeignKeysNotContain($this->firstProduct->getId(),
61 $this->firstRelated->getId());
62 $this->assertForeignKeysContain($this->firstProduct->getId(),
63 $this->secondRelated->getId());
66 public function testEagerLoadsOwningSide()
68 $this->_createLoadingFixture();
69 $products = $this->_findProducts();
70 $this->assertLoadingOfOwningSide($products);
73 public function testLazyLoadsOwningSide()
75 $this->_createLoadingFixture();
77 $metadata = $this->_em->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceProduct');
78 $metadata->associationMappings['related']['fetch'] = ClassMetadata::FETCH_LAZY;
80 $query = $this->_em->createQuery('SELECT p FROM Doctrine\Tests\Models\ECommerce\ECommerceProduct p');
81 $products = $query->getResult();
82 $this->assertLoadingOfOwningSide($products);
85 public function assertLoadingOfOwningSide($products)
87 list ($firstProduct, $secondProduct) = $products;
88 $this->assertEquals(2, count($firstProduct->getRelated()));
89 $this->assertEquals(2, count($secondProduct->getRelated()));
91 $categories = $firstProduct->getRelated();
92 $firstRelatedBy = $categories[0]->getRelated();
93 $secondRelatedBy = $categories[1]->getRelated();
95 $this->assertEquals(2, count($firstRelatedBy));
96 $this->assertEquals(2, count($secondRelatedBy));
98 $this->assertInstanceOf('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $firstRelatedBy[0]);
99 $this->assertInstanceOf('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $firstRelatedBy[1]);
100 $this->assertInstanceOf('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $secondRelatedBy[0]);
101 $this->assertInstanceOf('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $secondRelatedBy[1]);
103 $this->assertCollectionEquals($firstRelatedBy, $secondRelatedBy);
106 protected function _createLoadingFixture()
108 $this->firstProduct->addRelated($this->firstRelated);
109 $this->firstProduct->addRelated($this->secondRelated);
110 $this->secondProduct->addRelated($this->firstRelated);
111 $this->secondProduct->addRelated($this->secondRelated);
112 $this->_em->persist($this->firstProduct);
113 $this->_em->persist($this->secondProduct);
119 protected function _findProducts()
121 $query = $this->_em->createQuery('SELECT p, r FROM Doctrine\Tests\Models\ECommerce\ECommerceProduct p LEFT JOIN p.related r ORDER BY p.id, r.id');
122 return $query->getResult();