From 30377e1054ab7678bc508e21c46245aaf59b20ec Mon Sep 17 00:00:00 2001 From: Alban Jubert Date: Sat, 24 Jun 2017 17:16:43 +0200 Subject: [PATCH] Preparing for enhancements #3, #5 and #15 to be able to set per relation properties --- src/SaveRelationsBehavior.php | 39 +++++++++++++++++++++++++++++++++------ tests/models/Link.php | 4 ++++ tests/models/Project.php | 2 +- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/SaveRelationsBehavior.php b/src/SaveRelationsBehavior.php index d09abc9..dd6da61 100644 --- a/src/SaveRelationsBehavior.php +++ b/src/SaveRelationsBehavior.php @@ -7,6 +7,7 @@ use Yii; use yii\base\Behavior; use yii\base\Exception; use yii\base\ModelEvent; +use yii\base\UnknownPropertyException; use yii\db\ActiveQueryInterface; use yii\db\BaseActiveRecord; use yii\db\Transaction; @@ -22,10 +23,36 @@ class SaveRelationsBehavior extends Behavior { public $relations = []; + private $_relations = []; private $_oldRelationValue = []; private $_relationsSaveStarted = false; private $_transaction; + private $_relationsScenario = []; + private $_relationsCascadeDelete = []; + + public function init() + { + parent::init(); + $allowedProperties = ['scenario', 'cascadeDelete']; + foreach ($this->relations as $key => $value) { + if (is_int($key)) { + $this->_relations[] = $value; + } else { + $this->_relations[] = $key; + if (is_array($value)) { + foreach ($value as $propertyKey => $propertyValue) { + if (in_array($propertyKey, $allowedProperties)) { + $this->{'_relations' . ucfirst($propertyKey)}[$key] = $propertyValue; + } else { + throw new UnknownPropertyException('The relation property named ' . $propertyKey . ' is not supported'); + } + } + } + } + } + } + public function events() { return [ @@ -58,7 +85,7 @@ class SaveRelationsBehavior extends Behavior public function canSetProperty($name, $checkVars = true) { $getter = 'get' . $name; - if (in_array($name, $this->relations) && method_exists($this->owner, $getter) && $this->owner->$getter() instanceof ActiveQueryInterface) { + if (in_array($name, $this->_relations) && method_exists($this->owner, $getter) && $this->owner->$getter() instanceof ActiveQueryInterface) { return true; } return parent::canSetProperty($name, $checkVars); @@ -72,7 +99,7 @@ class SaveRelationsBehavior extends Behavior */ public function __set($name, $value) { - if (in_array($name, $this->relations)) { + if (in_array($name, $this->_relations)) { Yii::trace("Setting {$name} relation value", __METHOD__); if (!isset($this->_oldRelationValue[$name])) { $this->_oldRelationValue[$name] = $this->owner->{$name}; @@ -187,7 +214,7 @@ class SaveRelationsBehavior extends Behavior $model = $this->owner; if ($this->saveRelatedRecords($model, $event)) { // If relation is has_one, try to set related model attributes - foreach ($this->relations as $relationName) { + foreach ($this->_relations as $relationName) { if (array_key_exists($relationName, $this->_oldRelationValue)) { // Relation was not set, do nothing... $relation = $model->getRelation($relationName); if ($relation->multiple === false && !empty($model->{$relationName})) { @@ -219,7 +246,7 @@ class SaveRelationsBehavior extends Behavior $this->_transaction = $model->getDb()->beginTransaction(); } try { - foreach ($this->relations as $relationName) { + foreach ($this->_relations as $relationName) { if (array_key_exists($relationName, $this->_oldRelationValue)) { // Relation was not set, do nothing... $relation = $model->getRelation($relationName); if (!empty($model->{$relationName})) { @@ -302,7 +329,7 @@ class SaveRelationsBehavior extends Behavior /** @var BaseActiveRecord $model */ $model = $this->owner; $this->_relationsSaveStarted = true; - foreach ($this->relations as $relationName) { + foreach ($this->_relations as $relationName) { if (array_key_exists($relationName, $this->_oldRelationValue)) { // Relation was not set, do nothing... Yii::trace("Linking {$relationName} relation", __METHOD__); $relation = $model->getRelation($relationName); @@ -390,7 +417,7 @@ class SaveRelationsBehavior extends Behavior { /** @var BaseActiveRecord $model */ $model = $this->owner; - foreach ($this->relations as $relationName) { + foreach ($this->_relations as $relationName) { $relation = $model->getRelation($relationName); $modelClass = $relation->modelClass; /** @var BaseActiveRecord $relationalModel */ diff --git a/tests/models/Link.php b/tests/models/Link.php index 3ed8eaa..23ecb0e 100644 --- a/tests/models/Link.php +++ b/tests/models/Link.php @@ -6,6 +6,10 @@ use lhs\Yii2SaveRelationsBehavior\SaveRelationsBehavior; class Link extends \yii\db\ActiveRecord { + + const SCENARIO_FIRST = 'first'; + const SCENARIO_SECOND = 'second'; + /** * @inheritdoc */ diff --git a/tests/models/Project.php b/tests/models/Project.php index 652dfe2..5450fce 100644 --- a/tests/models/Project.php +++ b/tests/models/Project.php @@ -22,7 +22,7 @@ class Project extends \yii\db\ActiveRecord return [ 'saveRelations' => [ 'class' => SaveRelationsBehavior::className(), - 'relations' => ['company', 'users', 'links'] + 'relations' => ['company', 'users', 'links' => ['scenario' => Link::SCENARIO_FIRST]] ], ]; }