diff --git a/src/SaveRelationsBehavior.php b/src/SaveRelationsBehavior.php index bdc4d42..a1f5e1a 100644 --- a/src/SaveRelationsBehavior.php +++ b/src/SaveRelationsBehavior.php @@ -211,51 +211,8 @@ class SaveRelationsBehavior extends Behavior { /** @var BaseActiveRecord $modelClass */ $modelClass = $relation->modelClass; - // Get the related model foreign keys - if (is_array($data)) { - $fks = []; - - // search PK - foreach ($modelClass::primaryKey() as $modelAttribute) { - if (array_key_exists($modelAttribute, $data) && !empty($data[$modelAttribute])) { - $fks[$modelAttribute] = $data[$modelAttribute]; - } else { - $fks = []; - break; - } - } - if (empty($fks)) { - // Get the right link definition - if ($relation->via instanceof BaseActiveRecord) { - $link = $relation->via->link; - } elseif (is_array($relation->via)) { - list($viaName, $viaQuery) = $relation->via; - $link = $viaQuery->link; - } else { - $link = $relation->link; - } - foreach ($link as $relatedAttribute => $modelAttribute) { - if (array_key_exists($modelAttribute, $data) && !empty($data[$modelAttribute])) { - $fks[$modelAttribute] = $data[$modelAttribute]; - } - } - } - } else { - $fks = $data; - } - // Load existing model or create one if no key was provided and data is not empty - /** @var BaseActiveRecord $relationModel */ - $relationModel = null; - if (!empty($fks)) { - $relationModel = $modelClass::findOne($fks); - } - if (!($relationModel instanceof BaseActiveRecord) && !empty($data)) { - $relationModel = new $modelClass; - } - if (($relationModel instanceof BaseActiveRecord) && is_array($data)) { - $relationModel->setAttributes($data); - } - return $relationModel; + $fks = $this->_getRelatedFks($data, $relation, $modelClass); + return $this->_loadOrCreateRelationModel($data, $fks, $modelClass); } /** @@ -636,16 +593,88 @@ class SaveRelationsBehavior extends Behavior */ protected function startTransactionForModel(BaseActiveRecord $model) { - if ( - method_exists($model, 'isTransactional') - && is_null($model->getDb()->transaction) - && ( - ($model->isNewRecord && $model->isTransactional($model::OP_INSERT)) - || (!$model->isNewRecord && $model->isTransactional($model::OP_UPDATE)) - || $model->isTransactional($model::OP_ALL) - ) - ) { + if ($this->isModelTransactional($model) && is_null($model->getDb()->transaction)) { $this->_transaction = $model->getDb()->beginTransaction(); } } + + + /** + * @param BaseActiveRecord $model + * @return bool + */ + protected function isModelTransactional(BaseActiveRecord $model) + { + if (method_exists($model, 'isTransactional')) { + return ($model->isNewRecord && $model->isTransactional($model::OP_INSERT)) + || (!$model->isNewRecord && $model->isTransactional($model::OP_UPDATE)) + || $model->isTransactional($model::OP_ALL); + } + return false; + } + + /** + * Load existing model or create one if no key was provided and data is not empty + * @param $data + * @param $fks + * @param $modelClass + * @return BaseActiveRecord + */ + private function _loadOrCreateRelationModel($data, $fks, $modelClass) + { + /** @var BaseActiveRecord $relationModel */ + $relationModel = null; + if (!empty($fks)) { + $relationModel = $modelClass::findOne($fks); + } + if (!($relationModel instanceof BaseActiveRecord) && !empty($data)) { + $relationModel = new $modelClass; + } + if (($relationModel instanceof BaseActiveRecord) && is_array($data)) { + $relationModel->setAttributes($data); + } + return $relationModel; + } + + /** + * Get the related model foreign keys + * @param $data + * @param $relation + * @param BaseActiveRecord $modelClass + * @return array + */ + private function _getRelatedFks($data, $relation, $modelClass) + { + $fks = []; + if (is_array($data)) { + // search PK + foreach ($modelClass::primaryKey() as $modelAttribute) { + if (array_key_exists($modelAttribute, $data) && !empty($data[$modelAttribute])) { + $fks[$modelAttribute] = $data[$modelAttribute]; + } else { + $fks = []; + break; + } + } + if (empty($fks)) { + // Get the right link definition + if ($relation->via instanceof BaseActiveRecord) { + $link = $relation->via->link; + } elseif (is_array($relation->via)) { + list($viaName, $viaQuery) = $relation->via; + $link = $viaQuery->link; + } else { + $link = $relation->link; + } + foreach ($link as $relatedAttribute => $modelAttribute) { + if (array_key_exists($modelAttribute, $data) && !empty($data[$modelAttribute])) { + $fks[$modelAttribute] = $data[$modelAttribute]; + } + } + } + } else { + $fks = $data; + } + return $fks; + } }