/** * Save related entities * * @param ntityInterface $entity Entity to save relation from * @param string $relationName Name of the relation to save * @param array $options Options to pass to the mappers * @return boolean */ public function save(EntityInterface $entity, $relationName, $options = []) { $lastResult = 0; $relatedEntity = $entity->relation($relationName); if ($relatedEntity instanceof EntityInterface) { if ($relatedEntity->isNew() || $relatedEntity->isModified()) { $relatedMapper = $this->mapper()->getMapper($this->entityName()); $lastResult = $relatedMapper->save($relatedEntity, $options); //Update the local key to match the related entity primary key if ($entity->get($this->localKey()) !== $relatedEntity->primaryKey()) { $relatedRelations = $entity->relations($relatedMapper, $relatedEntity); //Check if it was a hasOne or a hasMany relation, //if hasOne, we must unset old value foreach ($relatedRelations as $relatedRelation) { if ($relatedRelation instanceof Relation\HasOne && $relatedRelation->foreignKey() === $this->localKey()) { if ($relatedMapper->entityManager()->fields()[$relatedRelation->foreignKey()]['notnull']) { $lastResult = $relatedMapper->delete([$relatedRelation->foreignKey() => $entity->get($relatedRelation->foreignKey())]); } else { $lastResult = $relatedMapper->queryBuilder()->builder()->update($relatedMapper->table())->set($relatedRelation->foreignKey(), null)->where([$relatedRelation->foreignKey() => $entity->get($relatedRelation->foreignKey())]); } } } $entity->set($this->localKey(), $relatedEntity->primaryKey()); } } } return $lastResult; }
/** * Validate related entities using relations * @param EntityInterface $entity * @return EntityInterface */ protected function validateRelations($entity) { $relations = $entity->relations($this, $entity); foreach ($relations as $relationName => $relation) { if ($relation instanceof Relation\HasOne || $relation instanceof Relation\BelongsTo) { $relatedEntity = $entity->{$relationName}; if ($relatedEntity instanceof EntityInterface) { $errorsRelated = $this->validateRelatedEntity($relatedEntity, $entity, $relation); if (count($errorsRelated)) { $entity->errors([$relationName => $errorsRelated], false); } } } else { if ($relation instanceof Relation\HasMany || $relation instanceof Relation\HasManyThrough) { $relatedEntities = $entity->{$relationName}; //No point in validating Queries since they are not modified if ((is_array($relatedEntities) || $relatedEntities instanceof Entity\Collection) && count($relatedEntities)) { $errors = []; foreach ($relatedEntities as $key => $related) { $errorsRelated = $this->validateRelatedEntity($related, $entity, $relation); if (count($errorsRelated)) { $errors[$key] = $errorsRelated; } } if (count($errors)) { $entity->errors([$relationName => $errors], false); } } } } } return $entity; }