diff --git a/CHANGELOG.md b/CHANGELOG.md index 010df47..4f367f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Yii2 Active Record Save Relations Behavior Change Log +## [1.7.0] (unreleased) +### Added +- Enh #42: Add the ability to retrieve old relations values + ## [1.6.0] ### Fixed - Bug #36: Fix an issue with HasMany relations with composite keys (thx @leandrogehlen) diff --git a/README.md b/README.md index 1e37c8a..29dc2f4 100644 --- a/README.md +++ b/README.md @@ -282,3 +282,15 @@ The `relationKeyName` property can be used to decide how the relations data will Possible constants values are: * `SaveRelationsBehavior::RELATION_KEY_FORM_NAME` (default): the key name will be computed using the model [`formName()`](https://www.yiiframework.com/doc/api/2.0/yii-base-model#formName()-detail) method * `SaveRelationsBehavior::RELATION_KEY_RELATION_NAME`: the relation name as defined in the behavior declarations will be used + + +Get old relations values +------------------------ + +To retrieve relations value prior to there most recent modification until the model is saved, you can use: +* `getOldAttribute($name)` method: Get a named relation old value. +* `getOldAttribute()` method: Get an array of relations index by there name with there old values. + +> **Notes** +> * If a relation has not been modified yet, its initial value will be returned +> * Only relations defined in the behavior parameters will be returned diff --git a/src/SaveRelationsBehavior.php b/src/SaveRelationsBehavior.php index f7bea78..140534d 100644 --- a/src/SaveRelationsBehavior.php +++ b/src/SaveRelationsBehavior.php @@ -763,4 +763,27 @@ class SaveRelationsBehavior extends Behavior } return $keyName; } + + /** + * Return the old relations values. + * @return array + */ + public function getOldRelations() + { + $oldRelations = []; + foreach ($this->_relations as $relationName) { + $oldRelations[$relationName] = $this->getOldRelation($relationName); + } + return $oldRelations; + } + + /** + * Returns the old value of the named relation. + * @param $relationName + * @return mixed + */ + public function getOldRelation($relationName) + { + return array_key_exists($relationName, $this->_oldRelationValue) ? $this->_oldRelationValue[$relationName] : $this->owner->{$relationName}; + } } diff --git a/tests/SaveRelationsBehaviorTest.php b/tests/SaveRelationsBehaviorTest.php index d0f9841..ddbad76 100644 --- a/tests/SaveRelationsBehaviorTest.php +++ b/tests/SaveRelationsBehaviorTest.php @@ -561,7 +561,7 @@ class SaveRelationsBehaviorTest extends \PHPUnit_Framework_TestCase 'path' => '/images/macosx_new.png' ], [ - 'id' => 2, + 'id' => 2, 'path' => '/images/macosx_updated.png' ] ] @@ -905,4 +905,49 @@ class SaveRelationsBehaviorTest extends \PHPUnit_Framework_TestCase $this->assertEquals('user1', $company->users[0]->username); $this->assertEquals('user2', $company->users[1]->username); } + + public function testGetOldRelations() + { + $project = Project::findOne(1); + $project->company = Company::findOne(2); + $links = [ + ['language' => 'fr', 'name' => 'windows10', 'link' => 'https://www.microsoft.com/fr-fr/windows/features', 'link_type_id' => 2], + ['language' => 'en', 'name' => 'windows10', 'link' => 'https://www.microsoft.com/en-us/windows/features', 'link_type_id' => 2] + ]; + $project->links = $links; + $oldRelations = $project->getOldRelations(); + $this->assertArrayHasKey('company', $oldRelations); + $this->assertArrayHasKey('links', $oldRelations); + $this->assertCount(2, $oldRelations['links']); + $oldLinks = $project->getOldRelation('links'); + $this->assertInternalType('array', $oldLinks); + $this->assertEquals($oldLinks[0]->language, 'fr'); + $this->assertEquals($oldLinks[0]->name, 'mac_os_x'); + $this->assertEquals($oldLinks[0]->link, 'http://www.apple.com/fr/osx/'); + $this->assertEquals($oldLinks[0]->link_type_id, 1); + $this->assertEquals($oldLinks[1]->language, 'en'); + $this->assertEquals($oldLinks[1]->name, 'mac_os_x'); + $this->assertEquals($oldLinks[1]->link, 'http://www.apple.com/osx/'); + $this->assertEquals($oldLinks[1]->link_type_id, 1); + $oldCompany = $project->getOldRelation('company'); + $this->assertInstanceOf(Company::className(), $oldCompany); + $this->assertEquals($oldCompany->id, 1); + $this->assertEquals($oldCompany->name, 'Apple'); + $this->assertTrue($project->save()); + $oldLinks = $project->getOldRelation('links'); + $this->assertInternalType('array', $oldLinks); + $this->assertEquals($oldLinks[0]->language, 'fr'); + $this->assertEquals($oldLinks[0]->name, 'windows10'); + $this->assertEquals($oldLinks[0]->link, 'https://www.microsoft.com/fr-fr/windows/features'); + $this->assertEquals($oldLinks[0]->link_type_id, 2); + $this->assertEquals($oldLinks[1]->language, 'en'); + $this->assertEquals($oldLinks[1]->name, 'windows10'); + $this->assertEquals($oldLinks[1]->link, 'https://www.microsoft.com/en-us/windows/features'); + $this->assertEquals($oldLinks[1]->link_type_id, 2); + $oldCompany = $project->getOldRelation('company'); + $this->assertInstanceOf(Company::className(), $oldCompany); + $this->assertEquals($oldCompany->id, 2); + $this->assertEquals($oldCompany->name, 'Microsoft'); + + } }