|
|
@ -73,16 +73,40 @@ class SaveRelationsBehavior extends Behavior |
|
|
|
public function __set($name, $value) |
|
|
|
public function __set($name, $value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (in_array($name, $this->relations)) { |
|
|
|
if (in_array($name, $this->relations)) { |
|
|
|
/** @var BaseActiveRecord $model */ |
|
|
|
|
|
|
|
$model = $this->owner; |
|
|
|
|
|
|
|
Yii::trace("Setting {$name} relation value", __METHOD__); |
|
|
|
Yii::trace("Setting {$name} relation value", __METHOD__); |
|
|
|
/** @var \yii\db\ActiveQuery $relation */ |
|
|
|
|
|
|
|
$relation = $model->getRelation($name); |
|
|
|
|
|
|
|
if (!isset($this->_oldRelationValue[$name])) { |
|
|
|
if (!isset($this->_oldRelationValue[$name])) { |
|
|
|
//Yii::trace("Initializing old {$name} relation value", __METHOD__); |
|
|
|
|
|
|
|
$this->_oldRelationValue[$name] = $this->owner->{$name}; |
|
|
|
$this->_oldRelationValue[$name] = $this->owner->{$name}; |
|
|
|
} |
|
|
|
} |
|
|
|
if ($relation->multiple === true) { |
|
|
|
if ($this->owner->getRelation($name)->multiple === true) { |
|
|
|
|
|
|
|
$this->setMultipleRelation($name, $value); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
$this->setSingleRelation($name, $value); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Set the named single relation with the given value |
|
|
|
|
|
|
|
* @param $name |
|
|
|
|
|
|
|
* @param $value |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
protected function setSingleRelation($name, $value) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
$relation = $this->owner->getRelation($name); |
|
|
|
|
|
|
|
if (!($value instanceof $relation->modelClass)) { |
|
|
|
|
|
|
|
$value = $this->processModelAsArray($value, $relation); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
$this->owner->populateRelation($name, $value); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Set the named multiple relation with the given value |
|
|
|
|
|
|
|
* @param $name |
|
|
|
|
|
|
|
* @param $value |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
protected function setMultipleRelation($name, $value) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
$relation = $this->owner->getRelation($name); |
|
|
|
$newRelations = []; |
|
|
|
$newRelations = []; |
|
|
|
if (!is_array($value)) { |
|
|
|
if (!is_array($value)) { |
|
|
|
if (!empty($value)) { |
|
|
|
if (!empty($value)) { |
|
|
@ -96,27 +120,20 @@ class SaveRelationsBehavior extends Behavior |
|
|
|
$newRelations[] = $entry; |
|
|
|
$newRelations[] = $entry; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// TODO handle this with one DB request to retrieve all models |
|
|
|
// TODO handle this with one DB request to retrieve all models |
|
|
|
$newRelations[] = $this->_processModelAsArray($entry, $relation); |
|
|
|
$newRelations[] = $this->processModelAsArray($entry, $relation); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
$model->populateRelation($name, $newRelations); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (!($value instanceof $relation->modelClass)) { |
|
|
|
|
|
|
|
$value = $this->_processModelAsArray($value, $relation); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
$model->populateRelation($name, $value); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
$this->owner->populateRelation($name, $newRelations); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Get an BaseActiveRecord model using the given $data parameter. |
|
|
|
* Get a BaseActiveRecord model using the given $data parameter. |
|
|
|
* $data could either be a model ID or an associative array representing model attributes => values |
|
|
|
* $data could either be a model ID or an associative array representing model attributes => values |
|
|
|
* @param mixed $data |
|
|
|
* @param mixed $data |
|
|
|
* @param \yii\db\ActiveQuery $relation |
|
|
|
* @param \yii\db\ActiveQuery $relation |
|
|
|
* @return BaseActiveRecord |
|
|
|
* @return BaseActiveRecord |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function _processModelAsArray($data, $relation) |
|
|
|
protected function processModelAsArray($data, $relation) |
|
|
|
{ |
|
|
|
{ |
|
|
|
/** @var BaseActiveRecord $modelClass */ |
|
|
|
/** @var BaseActiveRecord $modelClass */ |
|
|
|
$modelClass = $relation->modelClass; |
|
|
|
$modelClass = $relation->modelClass; |
|
|
@ -168,7 +185,7 @@ class SaveRelationsBehavior extends Behavior |
|
|
|
if ($this->_relationsSaveStarted == false && !empty($this->_oldRelationValue)) { |
|
|
|
if ($this->_relationsSaveStarted == false && !empty($this->_oldRelationValue)) { |
|
|
|
/* @var $model BaseActiveRecord */ |
|
|
|
/* @var $model BaseActiveRecord */ |
|
|
|
$model = $this->owner; |
|
|
|
$model = $this->owner; |
|
|
|
if ($this->_saveRelatedRecords($model, $event)) { |
|
|
|
if ($this->saveRelatedRecords($model, $event)) { |
|
|
|
// If relation is has_one, try to set related model attributes |
|
|
|
// 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... |
|
|
|
if (array_key_exists($relationName, $this->_oldRelationValue)) { // Relation was not set, do nothing... |
|
|
@ -196,7 +213,7 @@ class SaveRelationsBehavior extends Behavior |
|
|
|
* @param ModelEvent $event |
|
|
|
* @param ModelEvent $event |
|
|
|
* @return bool |
|
|
|
* @return bool |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function _saveRelatedRecords(BaseActiveRecord $model, ModelEvent $event) |
|
|
|
protected function saveRelatedRecords(BaseActiveRecord $model, ModelEvent $event) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (($model->isNewRecord && $model->isTransactional($model::OP_INSERT)) || (!$model->isNewRecord && $model->isTransactional($model::OP_UPDATE)) || $model->isTransactional($model::OP_ALL)) { |
|
|
|
if (($model->isNewRecord && $model->isTransactional($model::OP_INSERT)) || (!$model->isNewRecord && $model->isTransactional($model::OP_UPDATE)) || $model->isTransactional($model::OP_ALL)) { |
|
|
|
$this->_transaction = $model->getDb()->beginTransaction(); |
|
|
|
$this->_transaction = $model->getDb()->beginTransaction(); |
|
|
@ -209,13 +226,13 @@ class SaveRelationsBehavior extends Behavior |
|
|
|
if ($relation->multiple === false) { |
|
|
|
if ($relation->multiple === false) { |
|
|
|
// Save Has one relation new record |
|
|
|
// Save Has one relation new record |
|
|
|
$pettyRelationName = Inflector::camel2words($relationName, true); |
|
|
|
$pettyRelationName = Inflector::camel2words($relationName, true); |
|
|
|
$this->_saveModelRecord($model->{$relationName}, $event, $pettyRelationName, $relationName); |
|
|
|
$this->saveModelRecord($model->{$relationName}, $event, $pettyRelationName, $relationName); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// Save Has many relations new records |
|
|
|
// Save Has many relations new records |
|
|
|
/** @var BaseActiveRecord $relationModel */ |
|
|
|
/** @var BaseActiveRecord $relationModel */ |
|
|
|
foreach ($model->{$relationName} as $i => $relationModel) { |
|
|
|
foreach ($model->{$relationName} as $i => $relationModel) { |
|
|
|
$pettyRelationName = Inflector::camel2words($relationName, true) . " #{$i}"; |
|
|
|
$pettyRelationName = Inflector::camel2words($relationName, true) . " #{$i}"; |
|
|
|
$this->_validateRelationModel($pettyRelationName, $relationName, $relationModel, $event); |
|
|
|
$this->validateRelationModel($pettyRelationName, $relationName, $relationModel, $event); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -241,9 +258,9 @@ class SaveRelationsBehavior extends Behavior |
|
|
|
* @param $pettyRelationName |
|
|
|
* @param $pettyRelationName |
|
|
|
* @param $relationName |
|
|
|
* @param $relationName |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public function _saveModelRecord(BaseActiveRecord $model, ModelEvent $event, $pettyRelationName, $relationName) |
|
|
|
protected function saveModelRecord(BaseActiveRecord $model, ModelEvent $event, $pettyRelationName, $relationName) |
|
|
|
{ |
|
|
|
{ |
|
|
|
$this->_validateRelationModel($pettyRelationName, $relationName, $model, $event); |
|
|
|
$this->validateRelationModel($pettyRelationName, $relationName, $model, $event); |
|
|
|
if ($event->isValid && (count($model->dirtyAttributes) || $model->isNewRecord)) { |
|
|
|
if ($event->isValid && (count($model->dirtyAttributes) || $model->isNewRecord)) { |
|
|
|
Yii::trace("Saving {$pettyRelationName} relation model", __METHOD__); |
|
|
|
Yii::trace("Saving {$pettyRelationName} relation model", __METHOD__); |
|
|
|
$model->save(false); |
|
|
|
$model->save(false); |
|
|
@ -257,7 +274,7 @@ class SaveRelationsBehavior extends Behavior |
|
|
|
* @param BaseActiveRecord $relationModel |
|
|
|
* @param BaseActiveRecord $relationModel |
|
|
|
* @param ModelEvent $event |
|
|
|
* @param ModelEvent $event |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private function _validateRelationModel($pettyRelationName, $relationName, BaseActiveRecord $relationModel, ModelEvent $event) |
|
|
|
protected function validateRelationModel($pettyRelationName, $relationName, BaseActiveRecord $relationModel, ModelEvent $event) |
|
|
|
{ |
|
|
|
{ |
|
|
|
/** @var BaseActiveRecord $model */ |
|
|
|
/** @var BaseActiveRecord $model */ |
|
|
|
$model = $this->owner; |
|
|
|
$model = $this->owner; |
|
|
@ -384,6 +401,4 @@ class SaveRelationsBehavior extends Behavior |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|