/** * Return the specified relation objects with the primary object * * @param string $relation The class name of the relation to join to the primary object. * @param string|null $alias [optional] Provide a custom alias to use for the joined object, or null to have one * generated. This property is passed by reference so it can be used to get a * handle on the generated alias. * * @return Query */ public function with($relation, &$alias = null) { $from_class = $this->unaliasClass($this->from_alias); $relation_data = $from_class::_getRelation($relation); //if it's many to many, load the related class and flag the first join to be attached as relation data if ($relation_data['relation_type'] === Wave\DB\Relation::MANY_TO_MANY) { $this->leftJoin($relation_data['related_class'], $related_alias, $target_alias); //more iteration for multi-column relations foreach ($relation_data['related_columns'] as $index => $related_column) { $func = $index === 0 ? 'on' : 'and'; $this->{$func}(sprintf('%s.%s = %s.%s', $related_alias, $this->escape($related_column), $this->from_alias, $this->escape($relation_data['local_columns'][$index]))); } $this->leftJoin($relation_data['target_relation']['related_class'], $alias); foreach ($relation_data['target_relation']['related_columns'] as $index => $related_column) { $func = $index === 0 ? 'on' : 'and'; $this->{$func}(sprintf('%s.%s = %s.%s', $alias, $this->escape($related_column), $related_alias, $this->escape($relation_data['target_relation']['local_columns'][$index]))); } //go back and set the target alias to the joined row $target_alias = $alias; } else { //any other type of join is a simple table-table join $this->leftJoin($relation_data['related_class'], $alias); //more iteration for multi-column relations foreach ($relation_data['related_columns'] as $index => $related_column) { $func = $index === 0 ? 'on' : 'and'; $this->{$func}(sprintf('%s.%s = %s.%s', $alias, $this->escape($related_column), $this->from_alias, $this->escape($relation_data['local_columns'][$index]))); } } //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)); return $this; }