Skip to content
This repository
Browse code

[DataFixtures] Fixed N-N relations

  • Loading branch information...
commit 2e7bb13431a062d3a0707998b9797999c97aedc8 1 parent 35dbf79
William Durand willdurand authored
6 DataFixtures/AbstractDataHandler.php
@@ -11,7 +11,6 @@
11 11 namespace Propel\PropelBundle\DataFixtures;
12 12
13 13 use \Propel;
14   -
15 14 use Symfony\Component\Finder\Finder;
16 15
17 16 /**
@@ -65,7 +64,10 @@ protected function loadMapBuilders($connectionName = null)
65 64
66 65 if (0 === count($this->dbMap->getTables())) {
67 66 $finder = new Finder();
68   - $files = $finder->files()->name('*TableMap.php')->in($this->getRootDir() . '/../')->exclude('Tests');
  67 + $files = $finder->files()->name('*TableMap.php')
  68 + ->in($this->getRootDir() . '/../')
  69 + ->exclude('PropelBundle')
  70 + ->exclude('Tests');
69 71
70 72 foreach ($files as $file) {
71 73 $class = $this->guessFullClassName($file->getRelativePath(), basename($file, '.php'));
41 DataFixtures/Loader/AbstractDataLoader.php
@@ -10,15 +10,14 @@
10 10
11 11 namespace Propel\PropelBundle\DataFixtures\Loader;
12 12
13   -use \Propel;
  13 +
14 14 use \BasePeer;
15 15 use \BaseObject;
16 16 use \ColumnMap;
  17 +use \Propel;
17 18 use \PropelException;
18   -
19 19 use Propel\PropelBundle\DataFixtures\AbstractDataHandler;
20 20 use Propel\PropelBundle\Util\PropelInflector;
21   -
22 21 use Symfony\Component\Finder\Finder;
23 22
24 23 /**
@@ -156,17 +155,18 @@ protected function loadDataFromArray($data = null)
156 155 }
157 156
158 157 foreach ($data as $name => $value) {
159   - try {
160   - if (is_array($value) && 's' === substr($name, -1)) {
  158 + if (is_array($value) && 's' === substr($name, -1)) {
  159 + try {
161 160 // many to many relationship
162 161 $this->loadManyToMany($obj, substr($name, 0, -1), $value);
  162 +
163 163 continue;
164   - }
165   - } catch (\PropelException $e) {
166   - // Check whether this is actually an array stored in the object.
167   - if ('Cannot fetch TableMap for undefined table: '.substr($name, 0, -1) === $e->getMessage()) {
168   - if ('ARRAY' !== $tableMap->getColumn($name)->getType()) {
169   - throw $e;
  164 + } catch (PropelException $e) {
  165 + // Check whether this is actually an array stored in the object.
  166 + if ('Cannot fetch TableMap for undefined table: '.substr($name, 0, -1) === $e->getMessage()) {
  167 + if ('ARRAY' !== $tableMap->getColumn($name)->getType()) {
  168 + throw $e;
  169 + }
170 170 }
171 171 }
172 172 }
@@ -206,8 +206,7 @@ protected function loadDataFromArray($data = null)
206 206
207 207 if (false !== $pos = array_search($name, $column_names)) {
208 208 $obj->setByPosition($pos, $value);
209   - }
210   - elseif (is_callable(array($obj, $method = 'set'.ucfirst(PropelInflector::camelize($name))))) {
  209 + } elseif (is_callable(array($obj, $method = 'set'.ucfirst(PropelInflector::camelize($name))))) {
211 210 $obj->$method($value);
212 211 } else {
213 212 throw new \InvalidArgumentException(sprintf('Column "%s" does not exist for class "%s".', $name, $class));
@@ -234,12 +233,17 @@ protected function loadDataFromArray($data = null)
234 233 protected function loadManyToMany($obj, $middleTableName, $values)
235 234 {
236 235 $middleTable = $this->dbMap->getTable($middleTableName);
237   - $middleClass = $middleTable->getPhpName();
  236 + $middleClass = $middleTable->getClassname();
  237 + $tableName = constant(constant(get_class($obj).'::PEER').'::TABLE_NAME');
238 238
239 239 foreach ($middleTable->getColumns() as $column) {
240   - if ($column->isForeignKey() && constant(constant(get_class($obj).'::PEER').'::TABLE_NAME') != $column->getRelatedTableName()) {
241   - $relatedClass = $this->dbMap->getTable($column->getRelatedTableName())->getPhpName();
242   - break;
  240 + if ($column->isForeignKey()) {
  241 + if ($tableName !== $column->getRelatedTableName()) {
  242 + $relatedClass = $this->dbMap->getTable($column->getRelatedTableName())->getClassname();
  243 + $relatedSetter = 'set' . $column->getRelation()->getName();
  244 + } else {
  245 + $setter = 'set' . $column->getRelation()->getName();
  246 + }
243 247 }
244 248 }
245 249
@@ -247,9 +251,6 @@ protected function loadManyToMany($obj, $middleTableName, $values)
247 251 throw new \InvalidArgumentException(sprintf('Unable to find the many-to-many relationship for object "%s".', get_class($obj)));
248 252 }
249 253
250   - $setter = 'set'.get_class($obj);
251   - $relatedSetter = 'set'.$relatedClass;
252   -
253 254 foreach ($values as $value) {
254 255 if (!isset($this->object_references[$relatedClass.'_'.$value])) {
255 256 throw new \InvalidArgumentException(
15 Resources/doc/README.markdown
Source Rendered
@@ -262,15 +262,26 @@ A valid _XML fixtures file_ is:
262 262 A valid _YAML fixtures file_ is:
263 263
264 264 ``` yaml
265   -\Awesome\Object:
  265 +Awesome\Object:
266 266 o1:
267 267 Title: My title
268 268 MyFoo: bar
269 269
270   - \Awesome\Related:
  270 +Awesome\Related:
271 271 r1:
272 272 ObjectId: o1
273 273 Description: Hello world !
  274 +
  275 +Awesome\Tag:
  276 + t1:
  277 + name: Foo
  278 + t2:
  279 + name: Baz
  280 +
  281 +Awesome\Post:
  282 + p1:
  283 + title: A Post with tags (N-N relation)
  284 + tags: [ t1, t2 ]
274 285 ```
275 286
276 287 You can load all fixtures files from a given _bundle_:
41 Tests/DataFixtures/Loader/YamlDataLoaderTest.php
@@ -49,24 +49,24 @@ public function testYamlLoadManyToMany()
49 49 {
50 50 $schema = <<<XML
51 51 <database name="default" package="vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader" namespace="Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader" defaultIdMethod="native">
52   - <table name="book" phpName="YamlManyToManyBook">
  52 + <table name="table_book" phpName="YamlManyToManyBook">
53 53 <column name="id" type="integer" primaryKey="true" />
54 54 <column name="name" type="varchar" size="255" />
55 55 </table>
56 56
57   - <table name="author" phpName="YamlManyToManyAuthor">
  57 + <table name="table_author" phpName="YamlManyToManyAuthor">
58 58 <column name="id" type="integer" primaryKey="true" />
59 59 <column name="name" type="varchar" size="255" />
60 60 </table>
61 61
62   - <table name="book_author" phpName="YamlManyToManyBookAuthor">
  62 + <table name="table_book_author" phpName="YamlManyToManyBookAuthor" isCrossRef="true">
63 63 <column name="book_id" type="integer" required="true" primaryKey="true" />
64 64 <column name="author_id" type="integer" required="true" primaryKey="true" />
65 65
66   - <foreign-key foreignTable="book" phpName="Book" onDelete="CASCADE" onUpdate="CASCADE">
  66 + <foreign-key foreignTable="table_book" phpName="Book" onDelete="CASCADE" onUpdate="CASCADE">
67 67 <reference local="book_id" foreign="id" />
68 68 </foreign-key>
69   - <foreign-key foreignTable="author" phpName="Author" onDelete="CASCADE" onUpdate="CASCADE">
  69 + <foreign-key foreignTable="table_author" phpName="Author" onDelete="CASCADE" onUpdate="CASCADE">
70 70 <reference local="author_id" foreign="id" />
71 71 </foreign-key>
72 72 </table>
@@ -74,17 +74,27 @@ public function testYamlLoadManyToMany()
74 74 XML;
75 75
76 76 $fixtures = <<<YAML
77   -Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyAuthor:
78   - Author_1:
79   - name: 'A famous one'
80 77 Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBook:
81 78 Book_1:
  79 + id: 1
82 80 name: 'An important one'
  81 + Book_2:
  82 + id: 2
  83 + name: 'Les misérables'
  84 +
  85 +Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyAuthor:
  86 + Author_1:
  87 + id: 1
  88 + name: 'A famous one'
  89 + Author_2:
  90 + id: 2
  91 + name: 'Victor Hugo'
  92 + table_book_authors: [ Book_2 ]
  93 +
83 94 Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBookAuthor:
84 95 BookAuthor_1:
85 96 book_id: Book_1
86 97 author_id: Author_1
87   -
88 98 YAML;
89 99
90 100 $filename = $this->getTempFile($fixtures);
@@ -97,16 +107,23 @@ public function testYamlLoadManyToMany()
97 107 $loader->load(array($filename), 'default');
98 108
99 109 $books = \Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBookPeer::doSelect(new \Criteria(), $con);
100   - $this->assertCount(1, $books);
  110 + $this->assertCount(2, $books);
101 111 $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBook', $books[0]);
  112 + $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBook', $books[1]);
102 113
103 114 $authors = \Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyAuthorPeer::doSelect(new \Criteria(), $con);
104   - $this->assertCount(1, $authors);
  115 + $this->assertCount(2, $authors);
105 116 $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyAuthor', $authors[0]);
  117 + $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyAuthor', $authors[1]);
106 118
107 119 $bookAuthors = \Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBookAuthorPeer::doSelect(new \Criteria(), $con);
108   - $this->assertCount(1, $bookAuthors);
  120 + $this->assertCount(2, $bookAuthors);
109 121 $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBookAuthor', $bookAuthors[0]);
  122 + $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBookAuthor', $bookAuthors[1]);
  123 +
  124 + $this->assertEquals('Victor Hugo', $authors[1]->getName());
  125 + $this->assertTrue($authors[1]->getBooks()->contains($books[1]));
  126 + $this->assertEquals('Les misérables', $authors[1]->getBooks()->get(0)->getName());
110 127 }
111 128
112 129 public function testLoadSelfReferencing()
4 Tests/DataFixtures/TestCase.php
@@ -56,9 +56,7 @@ protected function setUp()
56 56
57 57 $builder = new \PropelQuickBuilder();
58 58 $builder->setSchema($schema);
59   - if (!class_exists('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\Book')) {
60   - $builder->setClassTargets(array('peer', 'object', 'query', 'peerstub', 'objectstub', 'querystub'));
61   - } else {
  59 + if (class_exists('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\Book')) {
62 60 $builder->setClassTargets(array());
63 61 }
64 62
58 Tests/Fixtures/DataFixtures/Loader/map/BookAuthorTableMap.php
... ... @@ -1,58 +0,0 @@
1   -<?php
2   -
3   -namespace Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\map;
4   -
5   -use \RelationMap;
6   -use \TableMap;
7   -
8   -
9   -/**
10   - * This class defines the structure of the 'author' table.
11   - *
12   - *
13   - *
14   - * This map class is used by Propel to do runtime db structure discovery.
15   - * For example, the createSelectSql() method checks the type of a given column used in an
16   - * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive
17   - * (i.e. if it's a text column type).
18   - *
19   - * @package propel.generator.vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader.map
20   - */
21   -class BookAuthorTableMap extends TableMap
22   -{
23   -
24   - /**
25   - * The (dot-path) name of this class
26   - */
27   - const CLASS_NAME = 'vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader.map.BookAuthorTableMap';
28   -
29   - /**
30   - * Initialize the table attributes, columns and validators
31   - * Relations are not initialized by this method since they are lazy loaded
32   - *
33   - * @return void
34   - * @throws PropelException
35   - */
36   - public function initialize()
37   - {
38   - // attributes
39   - $this->setName('book_author');
40   - $this->setPhpName('BookAuthor');
41   - $this->setClassname('Propel\\PropelBundle\\Tests\\Fixtures\\DataFixtures\\Loader\\BookAuthor');
42   - $this->setPackage('vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader');
43   - $this->setUseIdGenerator(false);
44   - // columns
45   - $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null);
46   - $this->addColumn('NAME', 'Name', 'VARCHAR', false, 255, null);
47   - // validators
48   - } // initialize()
49   -
50   - /**
51   - * Build the RelationMap objects for this table relationships
52   - */
53   - public function buildRelations()
54   - {
55   - $this->addRelation('Book', 'Propel\\PropelBundle\\Tests\\Fixtures\\DataFixtures\\Loader\\Book', RelationMap::ONE_TO_MANY, array('id' => 'author_id', ), 'RESTRICT', 'CASCADE', 'Books');
56   - } // buildRelations()
57   -
58   -} // AuthorTableMap
59 Tests/Fixtures/DataFixtures/Loader/map/BookTableMap.php
... ... @@ -1,59 +0,0 @@
1   -<?php
2   -
3   -namespace Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\map;
4   -
5   -use \RelationMap;
6   -use \TableMap;
7   -
8   -
9   -/**
10   - * This class defines the structure of the 'book' table.
11   - *
12   - *
13   - *
14   - * This map class is used by Propel to do runtime db structure discovery.
15   - * For example, the createSelectSql() method checks the type of a given column used in an
16   - * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive
17   - * (i.e. if it's a text column type).
18   - *
19   - * @package propel.generator.vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader.map
20   - */
21   -class BookTableMap extends TableMap
22   -{
23   -
24   - /**
25   - * The (dot-path) name of this class
26   - */
27   - const CLASS_NAME = 'vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader.map.BookTableMap';
28   -
29   - /**
30   - * Initialize the table attributes, columns and validators
31   - * Relations are not initialized by this method since they are lazy loaded
32   - *
33   - * @return void
34   - * @throws PropelException
35   - */
36   - public function initialize()
37   - {
38   - // attributes
39   - $this->setName('book');
40   - $this->setPhpName('Book');
41   - $this->setClassname('Propel\\PropelBundle\\Tests\\Fixtures\\DataFixtures\\Loader\\Book');
42   - $this->setPackage('vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader');
43   - $this->setUseIdGenerator(false);
44   - // columns
45   - $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null);
46   - $this->addColumn('NAME', 'Name', 'VARCHAR', false, 255, null);
47   - $this->addForeignKey('AUTHOR_ID', 'AuthorId', 'INTEGER', 'book_author', 'ID', true, null, null);
48   - // validators
49   - } // initialize()
50   -
51   - /**
52   - * Build the RelationMap objects for this table relationships
53   - */
54   - public function buildRelations()
55   - {
56   - $this->addRelation('BookAuthor', 'Propel\\PropelBundle\\Tests\\Fixtures\\DataFixtures\\Loader\\BookAuthor', RelationMap::MANY_TO_ONE, array('author_id' => 'id', ), 'RESTRICT', 'CASCADE');
57   - } // buildRelations()
58   -
59   -} // BookTableMap
2  composer.json
@@ -13,7 +13,7 @@
13 13 "propel/propel1": "1.6.*"
14 14 },
15 15 "require-dev": {
16   - "sensio/framework-extra-bundle": "*"
  16 + "sensio/framework-extra-bundle": "dev-master"
17 17 },
18 18 "autoload": {
19 19 "psr-0": { "Propel\\PropelBundle": "" }

0 comments on commit 2e7bb13

Please sign in to comment.
Something went wrong with that request. Please try again.