From 2e7bb13431a062d3a0707998b9797999c97aedc8 Mon Sep 17 00:00:00 2001 From: William DURAND Date: Sat, 5 May 2012 20:53:14 +0200 Subject: [PATCH] [DataFixtures] Fixed N-N relations --- DataFixtures/AbstractDataHandler.php | 6 +- DataFixtures/Loader/AbstractDataLoader.php | 41 ++++++------- Resources/doc/README.markdown | 15 ++++- .../Loader/YamlDataLoaderTest.php | 41 +++++++++---- Tests/DataFixtures/TestCase.php | 4 +- .../Loader/map/BookAuthorTableMap.php | 58 ------------------ .../DataFixtures/Loader/map/BookTableMap.php | 59 ------------------- composer.json | 2 +- 8 files changed, 69 insertions(+), 157 deletions(-) delete mode 100644 Tests/Fixtures/DataFixtures/Loader/map/BookAuthorTableMap.php delete mode 100644 Tests/Fixtures/DataFixtures/Loader/map/BookTableMap.php diff --git a/DataFixtures/AbstractDataHandler.php b/DataFixtures/AbstractDataHandler.php index 8bdaa08b..433106fd 100644 --- a/DataFixtures/AbstractDataHandler.php +++ b/DataFixtures/AbstractDataHandler.php @@ -11,7 +11,6 @@ namespace Propel\PropelBundle\DataFixtures; use \Propel; - use Symfony\Component\Finder\Finder; /** @@ -65,7 +64,10 @@ protected function loadMapBuilders($connectionName = null) if (0 === count($this->dbMap->getTables())) { $finder = new Finder(); - $files = $finder->files()->name('*TableMap.php')->in($this->getRootDir() . '/../')->exclude('Tests'); + $files = $finder->files()->name('*TableMap.php') + ->in($this->getRootDir() . '/../') + ->exclude('PropelBundle') + ->exclude('Tests'); foreach ($files as $file) { $class = $this->guessFullClassName($file->getRelativePath(), basename($file, '.php')); diff --git a/DataFixtures/Loader/AbstractDataLoader.php b/DataFixtures/Loader/AbstractDataLoader.php index e229d537..2f216226 100644 --- a/DataFixtures/Loader/AbstractDataLoader.php +++ b/DataFixtures/Loader/AbstractDataLoader.php @@ -10,15 +10,14 @@ namespace Propel\PropelBundle\DataFixtures\Loader; -use \Propel; + use \BasePeer; use \BaseObject; use \ColumnMap; +use \Propel; use \PropelException; - use Propel\PropelBundle\DataFixtures\AbstractDataHandler; use Propel\PropelBundle\Util\PropelInflector; - use Symfony\Component\Finder\Finder; /** @@ -156,17 +155,18 @@ protected function loadDataFromArray($data = null) } foreach ($data as $name => $value) { - try { - if (is_array($value) && 's' === substr($name, -1)) { + if (is_array($value) && 's' === substr($name, -1)) { + try { // many to many relationship $this->loadManyToMany($obj, substr($name, 0, -1), $value); + continue; - } - } catch (\PropelException $e) { - // Check whether this is actually an array stored in the object. - if ('Cannot fetch TableMap for undefined table: '.substr($name, 0, -1) === $e->getMessage()) { - if ('ARRAY' !== $tableMap->getColumn($name)->getType()) { - throw $e; + } catch (PropelException $e) { + // Check whether this is actually an array stored in the object. + if ('Cannot fetch TableMap for undefined table: '.substr($name, 0, -1) === $e->getMessage()) { + if ('ARRAY' !== $tableMap->getColumn($name)->getType()) { + throw $e; + } } } } @@ -206,8 +206,7 @@ protected function loadDataFromArray($data = null) if (false !== $pos = array_search($name, $column_names)) { $obj->setByPosition($pos, $value); - } - elseif (is_callable(array($obj, $method = 'set'.ucfirst(PropelInflector::camelize($name))))) { + } elseif (is_callable(array($obj, $method = 'set'.ucfirst(PropelInflector::camelize($name))))) { $obj->$method($value); } else { throw new \InvalidArgumentException(sprintf('Column "%s" does not exist for class "%s".', $name, $class)); @@ -234,12 +233,17 @@ protected function loadDataFromArray($data = null) protected function loadManyToMany($obj, $middleTableName, $values) { $middleTable = $this->dbMap->getTable($middleTableName); - $middleClass = $middleTable->getPhpName(); + $middleClass = $middleTable->getClassname(); + $tableName = constant(constant(get_class($obj).'::PEER').'::TABLE_NAME'); foreach ($middleTable->getColumns() as $column) { - if ($column->isForeignKey() && constant(constant(get_class($obj).'::PEER').'::TABLE_NAME') != $column->getRelatedTableName()) { - $relatedClass = $this->dbMap->getTable($column->getRelatedTableName())->getPhpName(); - break; + if ($column->isForeignKey()) { + if ($tableName !== $column->getRelatedTableName()) { + $relatedClass = $this->dbMap->getTable($column->getRelatedTableName())->getClassname(); + $relatedSetter = 'set' . $column->getRelation()->getName(); + } else { + $setter = 'set' . $column->getRelation()->getName(); + } } } @@ -247,9 +251,6 @@ protected function loadManyToMany($obj, $middleTableName, $values) throw new \InvalidArgumentException(sprintf('Unable to find the many-to-many relationship for object "%s".', get_class($obj))); } - $setter = 'set'.get_class($obj); - $relatedSetter = 'set'.$relatedClass; - foreach ($values as $value) { if (!isset($this->object_references[$relatedClass.'_'.$value])) { throw new \InvalidArgumentException( diff --git a/Resources/doc/README.markdown b/Resources/doc/README.markdown index c8fd1753..34fe1a23 100644 --- a/Resources/doc/README.markdown +++ b/Resources/doc/README.markdown @@ -262,15 +262,26 @@ A valid _XML fixtures file_ is: A valid _YAML fixtures file_ is: ``` yaml -\Awesome\Object: +Awesome\Object: o1: Title: My title MyFoo: bar - \Awesome\Related: +Awesome\Related: r1: ObjectId: o1 Description: Hello world ! + +Awesome\Tag: + t1: + name: Foo + t2: + name: Baz + +Awesome\Post: + p1: + title: A Post with tags (N-N relation) + tags: [ t1, t2 ] ``` You can load all fixtures files from a given _bundle_: diff --git a/Tests/DataFixtures/Loader/YamlDataLoaderTest.php b/Tests/DataFixtures/Loader/YamlDataLoaderTest.php index eba38359..954ead93 100644 --- a/Tests/DataFixtures/Loader/YamlDataLoaderTest.php +++ b/Tests/DataFixtures/Loader/YamlDataLoaderTest.php @@ -49,24 +49,24 @@ public function testYamlLoadManyToMany() { $schema = << - +
- +
- +
- + - +
@@ -74,17 +74,27 @@ public function testYamlLoadManyToMany() XML; $fixtures = <<getTempFile($fixtures); @@ -97,16 +107,23 @@ public function testYamlLoadManyToMany() $loader->load(array($filename), 'default'); $books = \Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBookPeer::doSelect(new \Criteria(), $con); - $this->assertCount(1, $books); + $this->assertCount(2, $books); $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBook', $books[0]); + $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBook', $books[1]); $authors = \Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyAuthorPeer::doSelect(new \Criteria(), $con); - $this->assertCount(1, $authors); + $this->assertCount(2, $authors); $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyAuthor', $authors[0]); + $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyAuthor', $authors[1]); $bookAuthors = \Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBookAuthorPeer::doSelect(new \Criteria(), $con); - $this->assertCount(1, $bookAuthors); + $this->assertCount(2, $bookAuthors); $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBookAuthor', $bookAuthors[0]); + $this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBookAuthor', $bookAuthors[1]); + + $this->assertEquals('Victor Hugo', $authors[1]->getName()); + $this->assertTrue($authors[1]->getBooks()->contains($books[1])); + $this->assertEquals('Les misérables', $authors[1]->getBooks()->get(0)->getName()); } public function testLoadSelfReferencing() diff --git a/Tests/DataFixtures/TestCase.php b/Tests/DataFixtures/TestCase.php index 8a5e52aa..08c85086 100644 --- a/Tests/DataFixtures/TestCase.php +++ b/Tests/DataFixtures/TestCase.php @@ -56,9 +56,7 @@ protected function setUp() $builder = new \PropelQuickBuilder(); $builder->setSchema($schema); - if (!class_exists('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\Book')) { - $builder->setClassTargets(array('peer', 'object', 'query', 'peerstub', 'objectstub', 'querystub')); - } else { + if (class_exists('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\Book')) { $builder->setClassTargets(array()); } diff --git a/Tests/Fixtures/DataFixtures/Loader/map/BookAuthorTableMap.php b/Tests/Fixtures/DataFixtures/Loader/map/BookAuthorTableMap.php deleted file mode 100644 index 7486dd07..00000000 --- a/Tests/Fixtures/DataFixtures/Loader/map/BookAuthorTableMap.php +++ /dev/null @@ -1,58 +0,0 @@ -setName('book_author'); - $this->setPhpName('BookAuthor'); - $this->setClassname('Propel\\PropelBundle\\Tests\\Fixtures\\DataFixtures\\Loader\\BookAuthor'); - $this->setPackage('vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader'); - $this->setUseIdGenerator(false); - // columns - $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addColumn('NAME', 'Name', 'VARCHAR', false, 255, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('Book', 'Propel\\PropelBundle\\Tests\\Fixtures\\DataFixtures\\Loader\\Book', RelationMap::ONE_TO_MANY, array('id' => 'author_id', ), 'RESTRICT', 'CASCADE', 'Books'); - } // buildRelations() - -} // AuthorTableMap diff --git a/Tests/Fixtures/DataFixtures/Loader/map/BookTableMap.php b/Tests/Fixtures/DataFixtures/Loader/map/BookTableMap.php deleted file mode 100644 index c5ec02c3..00000000 --- a/Tests/Fixtures/DataFixtures/Loader/map/BookTableMap.php +++ /dev/null @@ -1,59 +0,0 @@ -setName('book'); - $this->setPhpName('Book'); - $this->setClassname('Propel\\PropelBundle\\Tests\\Fixtures\\DataFixtures\\Loader\\Book'); - $this->setPackage('vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader'); - $this->setUseIdGenerator(false); - // columns - $this->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); - $this->addColumn('NAME', 'Name', 'VARCHAR', false, 255, null); - $this->addForeignKey('AUTHOR_ID', 'AuthorId', 'INTEGER', 'book_author', 'ID', true, null, null); - // validators - } // initialize() - - /** - * Build the RelationMap objects for this table relationships - */ - public function buildRelations() - { - $this->addRelation('BookAuthor', 'Propel\\PropelBundle\\Tests\\Fixtures\\DataFixtures\\Loader\\BookAuthor', RelationMap::MANY_TO_ONE, array('author_id' => 'id', ), 'RESTRICT', 'CASCADE'); - } // buildRelations() - -} // BookTableMap diff --git a/composer.json b/composer.json index 848bec23..3299c199 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "propel/propel1": "1.6.*" }, "require-dev": { - "sensio/framework-extra-bundle": "*" + "sensio/framework-extra-bundle": "dev-master" }, "autoload": { "psr-0": { "Propel\\PropelBundle": "" }