Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add inheritance support for fixtures with many to many relationship #256

Merged
merged 4 commits into from

3 participants

@pimpreneil

In propel fixtures, when using many to many relationship on a child object (when using a propel inheritance behaviour), an error gets triggered because it cannot find the relation between the object and one of its parents relation.

The error is:

PHP Fatal error:  Method name must be a string in /home/arnaud/www/primo/vendor/propel/propel-bundle/Propel/PropelBundle/DataFixtures/Loader/AbstractDataLoader.php on line 306

Here is a concrete use case (that triggers the error above):
Let's assume that the CampaignSystem class inherits from the Campaign class, and that the Campaign class is linked with a many to many relationship to the locale class through the crossRef CampaignLocale class.

The fixtures would look like this:

Locale:
    locale_en_us:
        locale: 'en_US'
    locale_en_gb:
        locale: 'fr_FR'

CampaignSystem:
    campaign_1:
        campaign_locales: [locale_en_us, locale_fr_FR]

So to sum the things up, the issue is that it is impossible for a child object to use its parents relationship.

The attached pull request fixes this issue.

@willdurand
Owner

tests?

@pimpreneil

In addition of the tests of the inheritance bug, I have added a small fix for the inheritance feeding that did not work when the linked class was also a child object.
Even if the second fix is very small, I will still try to write some tests for it asap...

@pimpreneil

Done with the commits, do you think it is mergeable as is or do you have any comments about it?

@willdurand
Owner

I guess it is ok. @havvg wdyt?

@havvg
Collaborator

Looks good to me.

Thanks!

@havvg havvg merged commit 2e54427 into propelorm:1.2
@pimpreneil pimpreneil deleted the pimpreneil:1.2 branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
25 DataFixtures/Loader/AbstractDataLoader.php
@@ -257,8 +257,7 @@ protected function saveParentReference($class, $key, &$obj)
$reflectionClass = new \ReflectionClass($parentClass);
if (!$reflectionClass->isAbstract()) {
- $parentObj = new $parentClass;
- $parentObj->fromArray($obj->toArray());
+ $parentObj = $obj->getParentOrCreate();
$this->saveParentReference($parentClass, $key, $parentObj);
}
@@ -268,6 +267,24 @@ protected function saveParentReference($class, $key, &$obj)
}
/**
+ * Retrieve all the parent classes of a given class (for the inheritance).
+ *
+ * @param string $class Class name of the current object
+ */
+ protected function getInheritedClasses($class) {
+ $reflectionClass = new \ReflectionClass($class);
+ $classes = array();
+
+ while (!$reflectionClass->isAbstract()) {
+ $classes[] = constant(constant($class.'::PEER').'::TABLE_NAME');
+ $class = get_parent_class(get_parent_class($class));
+ $reflectionClass = new \ReflectionClass($class);
+ }
+
+ return $classes;
+ }
+
+ /**
* Loads many to many objects.
*
* @param BaseObject $obj A Propel object
@@ -278,11 +295,11 @@ protected function loadManyToMany($obj, $middleTableName, $values)
{
$middleTable = $this->dbMap->getTable($middleTableName);
$middleClass = $middleTable->getClassname();
- $tableName = constant(constant(get_class($obj).'::PEER').'::TABLE_NAME');
+ $inheritedClasses = $this->getInheritedClasses(get_class($obj));
foreach ($middleTable->getColumns() as $column) {
if ($column->isForeignKey()) {
- if ($tableName !== $column->getRelatedTableName()) {
+ if (!in_array($column->getRelatedTableName(), $inheritedClasses)) {
$relatedClass = $this->dbMap->getTable($column->getRelatedTableName())->getClassname();
$relatedSetter = 'set' . $column->getRelation()->getName();
} else {
View
75 Tests/DataFixtures/Loader/YamlDataLoaderTest.php
@@ -379,6 +379,81 @@ public function testLoadWithInheritedRelationship()
$this->assertInstanceOf('Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlInheritedRelationshipAuthor', $author);
}
+ public function testLoadWithInheritedManyToManyRelationship()
+ {
+ $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="table_book_inherited_m2m_relationship" phpName="YamlInheritedM2MRelationshipBook">
+ <column name="id" type="integer" primaryKey="true" autoIncrement="true" />
+ <column name="name" type="varchar" size="255" />
+ </table>
+
+ <table name="table_history_book_inherited_m2m_relationship" phpName="YamlInheritedM2MRelationshipHistoryBook">
+ <behavior name="concrete_inheritance">
+ <parameter name="extends" value="table_book_inherited_m2m_relationship" />
+ </behavior>
+ </table>
+
+ <table name="table_author_inherited_m2m_relationship" phpName="YamlInheritedM2MRelationshipAuthor">
+ <column name="id" type="integer" primaryKey="true" autoIncrement="true" />
+ <column name="name" type="varchar" size="255" />
+ </table>
+
+ <table name="table_nobelized_author_inherited_m2m_relationship" phpName="YamlInheritedM2MRelationshipNobelizedAuthor">
+ <column name="nobel_year" type="integer" />
+ <behavior name="concrete_inheritance">
+ <parameter name="extends" value="table_author_inherited_m2m_relationship" />
+ </behavior>
+ </table>
+
+ <table name="table_book_author_inherited_m2m_relationship" phpName="YamlInheritedM2MRelationshipBookAuthor" isCrossRef="true">
+ <column name="author_id" type="integer" primaryKey="true" />
+ <column name="book_id" type="integer" primaryKey="true" />
+ <foreign-key foreignTable="table_author_inherited_m2m_relationship" phpName="Author">
+ <reference local="author_id" foreign="id" />
+ </foreign-key>
+ <foreign-key foreignTable="table_book_inherited_m2m_relationship" phpName="Book">
+ <reference local="book_id" foreign="id" />
+ </foreign-key>
+ </table>
+
+</database>
+XML;
+
+ $fixtures = <<<YAML
+Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlInheritedM2MRelationshipBook:
+ Book_1:
+ name: 'Supplice du santal'
+
+Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlInheritedM2MRelationshipHistoryBook:
+ Book_2:
+ name: 'Qiushui'
+
+Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlInheritedM2MRelationshipNobelizedAuthor:
+ NobelizedAuthor_1:
+ nobel_year: 2012
+ table_book_author_inherited_m2m_relationships: [Book_1, Book_2]
+
+YAML;
+
+ $filename = $this->getTempFile($fixtures);
+
+ $builder = new \PropelQuickBuilder();
+ $builder->setSchema($schema);
+ $con = $builder->build();
+
+ $loader = new YamlDataLoader(__DIR__.'/../../Fixtures/DataFixtures/Loader');
+ $loader->load(array($filename), 'default');
+
+ $authors = \Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\YamlInheritedM2MRelationshipNobelizedAuthorPeer::doSelect(new \Criteria(), $con);
+ $this->assertCount(1, $authors);
+
+ $author = $authors[0];
+ $books = $author->getBooks();
+ $this->assertCount(2, $books);
+ }
+
public function testLoadArrayToObjectType()
{
$schema = <<<XML
Something went wrong with that request. Please try again.