Example #1
0
 /**
  * Save related entities
  *
  * @param EntityInterface $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 = false;
     $relatedEntity = $entity->relation($relationName);
     $relatedMapper = $this->mapper()->getMapper($this->entityName());
     //Autoloaded relation, no need to save
     if ($relatedEntity instanceof HasOne) {
         return 0;
     }
     if ($relatedEntity === false || $relatedEntity->get($this->foreignKey()) !== $entity->primaryKey()) {
         if ($relatedMapper->entityManager()->fields()[$this->foreignKey()]['notnull']) {
             $relatedMapper->delete([$this->foreignKey() => $entity->primaryKey()]);
         } else {
             $relatedMapper->queryBuilder()->builder()->update($relatedMapper->table())->set($this->foreignKey(), null)->where([$this->foreignKey() => $entity->primaryKey()]);
         }
         if ($relatedEntity instanceof EntityInterface) {
             //Update the foreign key to match the main entity primary key
             $relatedEntity->set($this->foreignKey(), $entity->primaryKey());
         }
     }
     if ($relatedEntity instanceof EntityInterface && ($relatedEntity->isNew() || $relatedEntity->isModified())) {
         $lastResult = $relatedMapper->save($relatedEntity, $options);
     }
     return $lastResult;
 }
Example #2
0
 /**
  * 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;
 }
Example #3
0
 /**
  * Run set validation rules on fields
  */
 public function validate(EntityInterface $entity)
 {
     $v = new \Valitron\Validator($entity->data());
     // Run beforeValidate to know whether or not we can continue
     if (false === $this->eventEmitter()->emit('beforeValidate', [$entity, $this, $v])) {
         return false;
     }
     // Check validation rules on each feild
     $uniqueWhere = [];
     foreach ($this->fields() as $field => $fieldAttrs) {
         // Required field
         if (isset($fieldAttrs['required']) && true === $fieldAttrs['required'] || $fieldAttrs['primary'] === true && $fieldAttrs['autoincrement'] === false) {
             $v->rule('required', $field);
         }
         // Unique field
         if ($entity->isNew() && isset($fieldAttrs['unique']) && !empty($fieldAttrs['unique']) && $entity->{$field} !== null) {
             if (is_string($fieldAttrs['unique'])) {
                 // Named group
                 $fieldKeyName = $fieldAttrs['unique'];
                 $uniqueWhere[$fieldKeyName][$field] = $entity->{$field};
             } else {
                 $uniqueWhere[$field] = $entity->{$field};
             }
         }
         // Run only if field required
         if ($entity->{$field} !== null && $fieldAttrs['required'] === true) {
             // Field with 'options'
             if (isset($fieldAttrs['options']) && is_array($fieldAttrs['options'])) {
                 $v->rule('in', $field, $fieldAttrs['options']);
             }
             // Valitron validation rules
             if (isset($fieldAttrs['validation']) && is_array($fieldAttrs['validation'])) {
                 foreach ($fieldAttrs['validation'] as $rule => $ruleName) {
                     $params = [];
                     if (is_string($rule)) {
                         $params = (array) $ruleName;
                         $ruleName = $rule;
                     }
                     $params = array_merge([$ruleName, $field], $params);
                     call_user_func_array([$v, 'rule'], $params);
                 }
             }
         }
     }
     // Unique validation
     if (!empty($uniqueWhere)) {
         foreach ($uniqueWhere as $field => $value) {
             if (!is_array($value)) {
                 $value = [$field => $entity->{$field}];
             }
             if (!in_array(null, $value, true) && $this->first($value) !== false) {
                 $entity->error($field, "" . ucwords(str_replace('_', ' ', $field)) . " '" . implode('-', $value) . "' is already taken.");
             }
         }
     }
     if (!$v->validate()) {
         $entity->errors($v->errors(), false);
     }
     // Run afterValidate to run additional/custom validations
     if (false === $this->eventEmitter()->emit('afterValidate', [$entity, $this, $v])) {
         return false;
     }
     // Return error result
     return !$entity->hasErrors();
 }
Example #4
0
 /**
  * Save related entities
  *
  * @param EntityInterface $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 = [])
 {
     $relatedEntities = $entity->relation($relationName);
     $deletedIds = [];
     $lastResult = false;
     $relatedMapper = $this->mapper()->getMapper($this->entityName());
     if (is_array($relatedEntities) || $relatedEntities instanceof Entity\Collection) {
         $oldEntities = $this->execute();
         $relatedIds = [];
         foreach ($relatedEntities as $related) {
             if ($related->isNew() || $related->isModified() || $related->get($this->foreignKey()) !== $entity->primaryKey()) {
                 //Update the foreign key to match the main entity primary key
                 $related->set($this->foreignKey(), $entity->primaryKey());
                 $lastResult = $relatedMapper->save($related, $options);
             }
             $relatedIds[] = $related->id;
         }
         foreach ($oldEntities as $oldRelatedEntity) {
             if (!in_array($oldRelatedEntity, $relatedIds)) {
                 $deletedIds[] = $oldRelatedEntity->primaryKey();
             }
         }
     }
     if (count($deletedIds) || $relatedEntities === false) {
         $conditions = [$this->foreignKey() => $entity->primaryKey()];
         if (count($deletedIds)) {
             $conditions[$this->localKey() . ' :in'] = $deletedIds;
         }
         if ($relatedMapper->entityManager()->fields()[$this->foreignKey()]['notnull']) {
             $relatedMapper->delete($conditions);
         } else {
             $relatedMapper->queryBuilder()->builder()->update($relatedMapper->table())->set($this->foreignKey(), null)->where($conditions);
         }
     }
     return $lastResult;
 }
Example #5
0
 /**
  * Save related entities
  *
  * @param EntityInterface $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 = [])
 {
     $deletedIds = [];
     $lastResult = false;
     $relatedMapper = $this->mapper()->getMapper($this->entityName());
     $relatedEntities = $entity->relation($relationName);
     $oldEntities = $this->execute();
     if (is_array($relatedEntities) || $relatedEntities instanceof Entity\Collection) {
         $throughMapper = $this->mapper()->getMapper($this->throughEntityName());
         $relatedMapper = $this->mapper()->getMapper($this->entityName());
         $relatedIds = [];
         foreach ($relatedEntities as $related) {
             if ($related->isNew() || $related->isModified()) {
                 $lastResult = $relatedMapper->save($related, $options);
             }
             $relatedIds[] = $related->primaryKey();
             if (!count($throughMapper->where([$this->localKey() => $entity->primaryKey(), $this->foreignKey() => $related->primaryKey()]))) {
                 $lastResult = $throughMapper->create([$this->localKey() => $entity->primaryKey(), $this->foreignKey() => $related->primaryKey()]);
             }
         }
         $deletedIds = [];
         foreach ($oldEntities as $oldRelatedEntity) {
             if (!in_array($oldRelatedEntity->primaryKey(), $relatedIds)) {
                 $deletedIds[] = $oldRelatedEntity->primaryKey();
             }
         }
         if (!empty($deletedIds)) {
             $throughMapper->delete([$this->localKey() => $entity->primaryKey(), $this->foreignKey() . ' :in' => $deletedIds]);
         }
     } else {
         if ($relatedEntities === false) {
             //Relation was deleted, remove all
             $throughMapper = $this->mapper()->getMapper($this->throughEntityName());
             $throughMapper->delete([$this->localKey() => $entity->primaryKey()]);
         }
     }
     return $lastResult;
 }
Example #6
0
 /**
  * Validate related entity if it is new or modified only
  * @param \Spot\EntityInterface $relatedEntity
  * @param \Spot\EntityInterface $entity
  * @param \Spot\Relation\RelationAbstract $relation
  * @return array Related entity errors
  */
 protected function validateRelatedEntity(EntityInterface $relatedEntity, EntityInterface $entity, \Spot\Relation\RelationAbstract $relation)
 {
     $tainted = $relatedEntity->isNew() || $relatedEntity->isModified();
     $errorsRelated = [];
     if ($tainted && !$this->getMapper(get_class($relatedEntity))->validate($relatedEntity)) {
         $errorsRelated = $relatedEntity->errors();
         //Disable validation on foreign key field it will be filled up later on when the new entity is persisted
         if (($relation instanceof Relation\HasMany || $relation instanceof Relation\HasOne) && $relatedEntity->isNew()) {
             unset($errorsRelated[$relation->foreignKey()]);
         }
         $relatedEntity->errors($errorsRelated);
     }
     if ($relation instanceof Relation\BelongsTo && $entity->isNew()) {
         $errors = $entity->errors();
         unset($errors[$relation->localKey()]);
         $entity->errors($errors);
     }
     return $errorsRelated;
 }