Permalink
Browse files

[DataFixtures] Fixed N-N relations

  • Loading branch information...
1 parent 35dbf79 commit 2e7bb13431a062d3a0707998b9797999c97aedc8 @willdurand willdurand committed May 5, 2012
@@ -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'));
@@ -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,22 +233,24 @@ 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();
+ }
}
}
if (!isset($relatedClass)) {
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(
@@ -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_:
@@ -49,42 +49,52 @@ public function testYamlLoadManyToMany()
{
$schema = <<<XML
<database name="default" package="vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader" namespace="Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader" defaultIdMethod="native">
- <table name="book" phpName="YamlManyToManyBook">
+ <table name="table_book" phpName="YamlManyToManyBook">
<column name="id" type="integer" primaryKey="true" />
<column name="name" type="varchar" size="255" />
</table>
- <table name="author" phpName="YamlManyToManyAuthor">
+ <table name="table_author" phpName="YamlManyToManyAuthor">
<column name="id" type="integer" primaryKey="true" />
<column name="name" type="varchar" size="255" />
</table>
- <table name="book_author" phpName="YamlManyToManyBookAuthor">
+ <table name="table_book_author" phpName="YamlManyToManyBookAuthor" isCrossRef="true">
<column name="book_id" type="integer" required="true" primaryKey="true" />
<column name="author_id" type="integer" required="true" primaryKey="true" />
- <foreign-key foreignTable="book" phpName="Book" onDelete="CASCADE" onUpdate="CASCADE">
+ <foreign-key foreignTable="table_book" phpName="Book" onDelete="CASCADE" onUpdate="CASCADE">
<reference local="book_id" foreign="id" />
</foreign-key>
- <foreign-key foreignTable="author" phpName="Author" onDelete="CASCADE" onUpdate="CASCADE">
+ <foreign-key foreignTable="table_author" phpName="Author" onDelete="CASCADE" onUpdate="CASCADE">
<reference local="author_id" foreign="id" />
</foreign-key>
</table>
</database>
XML;
$fixtures = <<<YAML
-Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyAuthor:
- Author_1:
- name: 'A famous one'
Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBook:
Book_1:
+ id: 1
name: 'An important one'
+ Book_2:
+ id: 2
+ name: 'Les misérables'
+
+Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyAuthor:
+ Author_1:
+ id: 1
+ name: 'A famous one'
+ Author_2:
+ id: 2
+ name: 'Victor Hugo'
+ table_book_authors: [ Book_2 ]
+
Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlManyToManyBookAuthor:
BookAuthor_1:
book_id: Book_1
author_id: Author_1
-
YAML;
$filename = $this->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()
@@ -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());
}
@@ -1,58 +0,0 @@
-<?php
-
-namespace Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\map;
-
-use \RelationMap;
-use \TableMap;
-
-
-/**
- * This class defines the structure of the 'author' table.
- *
- *
- *
- * This map class is used by Propel to do runtime db structure discovery.
- * For example, the createSelectSql() method checks the type of a given column used in an
- * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive
- * (i.e. if it's a text column type).
- *
- * @package propel.generator.vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader.map
- */
-class BookAuthorTableMap extends TableMap
-{
-
- /**
- * The (dot-path) name of this class
- */
- const CLASS_NAME = 'vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader.map.BookAuthorTableMap';
-
- /**
- * Initialize the table attributes, columns and validators
- * Relations are not initialized by this method since they are lazy loaded
- *
- * @return void
- * @throws PropelException
- */
- public function initialize()
- {
- // attributes
- $this->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
@@ -1,59 +0,0 @@
-<?php
-
-namespace Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\map;
-
-use \RelationMap;
-use \TableMap;
-
-
-/**
- * This class defines the structure of the 'book' table.
- *
- *
- *
- * This map class is used by Propel to do runtime db structure discovery.
- * For example, the createSelectSql() method checks the type of a given column used in an
- * ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive
- * (i.e. if it's a text column type).
- *
- * @package propel.generator.vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader.map
- */
-class BookTableMap extends TableMap
-{
-
- /**
- * The (dot-path) name of this class
- */
- const CLASS_NAME = 'vendor.bundles.Propel.PropelBundle.Tests.Fixtures.DataFixtures.Loader.map.BookTableMap';
-
- /**
- * Initialize the table attributes, columns and validators
- * Relations are not initialized by this method since they are lazy loaded
- *
- * @return void
- * @throws PropelException
- */
- public function initialize()
- {
- // attributes
- $this->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
View
@@ -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": "" }

0 comments on commit 2e7bb13

Please sign in to comment.