Skip to content

Commit

Permalink
Fixed so versionable behavior loads correct relations when populating…
Browse files Browse the repository at this point in the history
… from a an older version.

See propelorm#198 for more info about this issue.
  • Loading branch information
martinj committed Nov 25, 2011
1 parent 5ce2674 commit 6704737
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
Expand Up @@ -282,7 +282,11 @@ protected function addPopulateFromVersion(&$script)
{
$ARclassName = $this->getActiveRecordClassName();
$versionTable = $this->behavior->getVersionTable();
$versionColumnName = $versionTable->getColumn($this->behavior->getParameter('version_column'))->getPhpName();
$versionARClassname = $this->builder->getNewStubObjectBuilder($versionTable)->getClassname();
$tablePKs = $this->table->getPrimaryKey();
$primaryKeyName = $tablePKs[0]->getPhpName();

$script .= "
/**
* Sets the properties of the curent object to the value they had at a specific version
Expand All @@ -292,8 +296,15 @@ protected function addPopulateFromVersion(&$script)
*
* @return {$ARclassName} The current object (for fluent API support)
*/
public function populateFromVersion(\$version, \$con = null)
{";
public function populateFromVersion(\$version, \$con = null, &\$loadedObjects = null)
{
if (!\$loadedObjects) {
\$loadedObjects = array();
}
";
$script .= "
\$loadedObjects['{$ARclassName}'][\$version->get{$primaryKeyName}()][\$version->get{$versionColumnName}()] = \$this;";

foreach ($this->table->getColumns() as $col) {
$script .= "
\$this->set" . $col->getPhpName() . "(\$version->get" . $col->getPhpName() . "());";
Expand All @@ -310,13 +321,17 @@ public function populateFromVersion(\$version, \$con = null)
// FIXME: breaks lazy-loading
$script .= "
if (\$fkValue = \$version->get{$fkColumnPhpName}()) {
\$related = new {$relatedClassname}();
\$relatedVersion = {$relatedVersionQueryClassname}::create()
->filterBy{$fk->getForeignColumn()->getPhpName()}(\$fkValue)
->filterByVersion(\$version->get{$fkVersionColumnPhpName}())
->findOne(\$con);
\$related->populateFromVersion(\$relatedVersion, \$con);
\$related->setNew(false);
if (isset(\$loadedObjects['{$relatedClassname}']) && isset(\$loadedObjects['{$relatedClassname}'][\$fkValue]) && isset(\$loadedObjects['{$relatedClassname}'][\$fkValue][\$version->get{$fkVersionColumnPhpName}()])) {
\$related = \$loadedObjects['{$relatedClassname}'][\$fkValue][\$version->get{$fkVersionColumnPhpName}()];
} else {
\$related = new {$relatedClassname}();
\$relatedVersion = {$relatedVersionQueryClassname}::create()
->filterBy{$fk->getForeignColumn()->getPhpName()}(\$fkValue)
->filterByVersion(\$version->get{$fkVersionColumnPhpName}())
->findOne(\$con);
\$related->populateFromVersion(\$relatedVersion, \$con, \$loadedObjects);
\$related->setNew(false);
}
\$this->set{$fkPhpname}(\$related);
}";
}
Expand All @@ -329,22 +344,29 @@ public function populateFromVersion(\$version, \$con = null)
$fkColumnIds = $this->behavior->getReferrerIdsColumn($fk);
$fkColumnVersions = $this->behavior->getReferrerVersionsColumn($fk);
$relatedVersionQueryClassname = $this->builder->getNewStubQueryBuilder($foreignVersionTable)->getClassname();
$relatedVersionPeerClassname = $this->builder->getNewStubPeerBuilder($foreignVersionTable)->getClassname();
$relatedClassname = $this->builder->getNewStubObjectBuilder($foreignTable)->getClassname();
$fkColumn = $fk->getForeignColumn();
$fkVersionColumn = $foreignVersionTable->getColumn($this->behavior->getParameter('version_column'));
$script .= "
if (\$fkValues = \$version->get{$fkColumnIds->getPhpName()}()) {
\$this->clear{$fkPhpNames}();
\$fkVersions = \$version->get{$fkColumnVersions->getPhpName()}();
\$query = {$relatedVersionQueryClassname}::create();
foreach (\$fkValues as \$key => \$value) {
\$c1 = \$query->getNewCriterion({$this->builder->getColumnConstant($fkColumnIds)}, \$value);
\$c2 = \$query->getNewCriterion({$this->builder->getColumnConstant($fkColumnVersions)}, \$fkVersions[\$key]);
\$c1 = \$query->getNewCriterion({$this->builder->getColumnConstant($fkColumn, $relatedVersionPeerClassname)}, \$value);
\$c2 = \$query->getNewCriterion({$this->builder->getColumnConstant($fkVersionColumn, $relatedVersionPeerClassname)}, \$fkVersions[\$key]);
\$c1->addAnd(\$c2);
\$query->addOr(\$c1);
}
foreach (\$query->find(\$con) as \$relatedVersion) {
\$related = new {$relatedClassname}();
\$related->populateFromVersion(\$relatedVersion, \$con);
\$related->setNew(false);
if (isset(\$loadedObjects['{$relatedClassname}']) && isset(\$loadedObjects['{$relatedClassname}'][\$relatedVersion->get{$fkColumn->getPhpName()}()]) && isset(\$loadedObjects['{$relatedClassname}'][\$relatedVersion->get{$fkColumn->getPhpName()}()][\$relatedVersion->get{$fkVersionColumn->getPhpName()}()])) {
\$related = \$loadedObjects['{$relatedClassname}'][\$relatedVersion->get{$fkColumn->getPhpName()}()][\$relatedVersion->get{$fkVersionColumn->getPhpName()}()];
} else {
\$related = new {$relatedClassname}();
\$related->populateFromVersion(\$relatedVersion, \$con, \$loadedObjects);
\$related->setNew(false);
}
\$this->add{$fkPhpName}(\$related);
}
}";
Expand Down
Expand Up @@ -397,6 +397,11 @@ public function testToVersionPreservesVersionedReferrerObjects()
$this->assertEquals(2, $bs[0]->getVersion());
$this->assertEquals(1, $bs[1]->getVersion());
$this->assertEquals(1, $bs[2]->getVersion());

$a->toVersion(1);
$bs = $a->getVersionableBehaviorTest5s();
$this->assertEquals(1, $bs[0]->getVersion());
$this->assertEquals(1, $bs[1]->getVersion());
}

public function testGetLastVersionNumber()
Expand Down

0 comments on commit 6704737

Please sign in to comment.