/**
* For each related model, try to save it first.
* If set in the owner model, operation is done in a transactional way so if one of the models should not validate
* or be saved, a rollback will occur.
* This is done during the before validation process to be able to set the related foreign keys.
* @param ActiveRecord $model
* @param ModelEvent $event
* @return bool
*/
public function _saveRelatedRecords(ActiveRecord $model, ModelEvent $event)
{
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();
}
try {
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})) {
if ($relation->multiple === false) {
// Save Has one relation new record
$pettyRelationName = Inflector::camel2words($relationName, true);
$this->_saveModelRecord($model->{$relationName}, $event, $pettyRelationName, $relationName);
} else {
// Save Has many relations new records
/** @var ActiveRecord $relationModel */
foreach ($model->{$relationName} as $i => $relationModel) {
$pettyRelationName = Inflector::camel2words($relationName, true) . " #{$i}";
$this->_validateRelationModel($pettyRelationName, $relationName, $relationModel, $event);
}
}
}
}
}
if (!$event->isValid) {
throw new Exception("One of the related model could not be validated");
}
} catch (Exception $e) {
if ($this->_transaction instanceof Transaction && $this->_transaction->isActive) {
$this->_transaction->rollBack();
// If anything goes wrong, transaction will be rolled back
}
$event->isValid = false;
// Stop saving, something went wrong
return false;
}
return true;
}