diff --git a/src/Wave/DB/Model.php b/src/Wave/DB/Model.php index eb1c22e..5db00fd 100644 --- a/src/Wave/DB/Model.php +++ b/src/Wave/DB/Model.php @@ -383,6 +383,22 @@ public function _getJoinedObjects() { return $this->_joined_objects; } + public function _setRelationDefault($relation_name) + { + $relation = static::_getRelation($relation_name); + + switch($relation['relation_type']) { + case Relation::ONE_TO_ONE: + case Relation::MANY_TO_ONE: + $this->_data[$relation_name] = null; + break; + case Relation::ONE_TO_MANY: + case Relation::MANY_TO_MANY: + $this->_data[$relation_name] = array(); + break; + } + } + /** * Returns the joined objects for a given class name. Looks for the class in the list * of aliases used when registering joined objects against this model diff --git a/src/Wave/DB/Query.php b/src/Wave/DB/Query.php index 8f4c00a..9706d86 100644 --- a/src/Wave/DB/Query.php +++ b/src/Wave/DB/Query.php @@ -10,6 +10,7 @@ use Wave; use Wave\Config; +use Wave\Inflector; /** * @method \Wave\DB\Query and () and ($condition, mixed $params = array()) @@ -158,7 +159,8 @@ public function with($relation, &$alias = null) { //this needs recording so the object can be added as a relation, not a join $this->with[$alias] = array( 'relation_type' => $relation_data['relation_type'], - 'relation_name' => Wave\Inflector::singularize($relation) + 'relation_name' => $relation, + 'singular_name' => Wave\Inflector::singularize($relation) ); return $this; @@ -743,8 +745,15 @@ public function fetchRow($parse_objects = true, $debug = false) { //if there's no instance of the main class, create a new one. - if(!isset($object_instances[$this->from_alias])) + if(!isset($object_instances[$this->from_alias])) { $object_instances[$this->from_alias] = $this->buildClassInstance($this->from_alias); + + if($object_instances[$this->from_alias] !== null && !empty($this->with)) { + foreach($this->with as $with) { + $object_instances[$this->from_alias]->_setRelationDefault($with['relation_name']); + } + } + } if($object_instances[$this->from_alias] === null) { trigger_error('Insufficient data in SELECT to build object instance.'); @@ -785,11 +794,11 @@ public function fetchRow($parse_objects = true, $debug = false) { switch($this->with[$join['table_alias']]['relation_type']) { case Wave\DB\Relation::ONE_TO_ONE: case Wave\DB\Relation::MANY_TO_ONE: - $object_instances[$join['target_alias']]->{'set' . $this->with[$join['table_alias']]['relation_name']}($object_instances[$join['table_alias']], false); + $object_instances[$join['target_alias']]->{'set' . $this->with[$join['table_alias']]['singular_name']}($object_instances[$join['table_alias']], false); break; case Wave\DB\Relation::ONE_TO_MANY: case Wave\DB\Relation::MANY_TO_MANY: - $object_instances[$join['target_alias']]->{'add' . $this->with[$join['table_alias']]['relation_name']}($object_instances[$join['table_alias']], false); + $object_instances[$join['target_alias']]->{'add' . $this->with[$join['table_alias']]['singular_name']}($object_instances[$join['table_alias']], false); break; } } else { diff --git a/src/Wave/Validator/Constraints/ExistsConstraint.php b/src/Wave/Validator/Constraints/ExistsConstraint.php index 3d9f9f4..cf0fa47 100644 --- a/src/Wave/Validator/Constraints/ExistsConstraint.php +++ b/src/Wave/Validator/Constraints/ExistsConstraint.php @@ -16,6 +16,7 @@ class ExistsConstraint extends AbstractConstraint implements CleanerInterface { protected $type = 'exists'; protected $message = null; private $match_fields = array(); + private $with_relations = array(); private $instance = null; public function __construct($property, $arguments, Validator &$validator) { @@ -29,6 +30,8 @@ public function __construct($property, $arguments, Validator &$validator) { $this->match_fields = array($arguments['property'] => $property); } + $this->with_relations = $arguments['with'] ?? []; + if(empty($this->match_fields)) throw new \InvalidArgumentException("[$this->type] constraint requires at least one property to match"); @@ -39,10 +42,14 @@ public function __construct($property, $arguments, Validator &$validator) { * @return bool */ public function evaluate() { - $statement = DB::get()->from($this->arguments['model']); + $statement = DB::get()->from($this->arguments['model'], $alias); + + foreach($this->with_relations as $relation_name) { + $statement->with($relation_name); + } foreach($this->match_fields as $column => $input_key) { - $statement->where($column . ' = ?', $this->validator[$input_key]); + $statement->where("$alias.$column = ?", $this->validator[$input_key]); } $this->instance = $statement->fetchRow();