/** * Add a condition over a relation. * * This is not the same as perform a join. An involved table will be used * and conditions given by the relation object will be added. But no JOIN * will be performed. * * This method is particularly useful to connect tables between subquery and * main query. * * Important: * ---------- * Current Model (CM) of relation is the table to involve ; Linked Model * (LM) is the current builder's root model. * * @param Relation $rel * @param string $lmAlias An alias for the linked model. */ public function whereRelation(Relation $rel, $lmAlias = null) { if ($lmAlias === null) { $lmAlias = self::DEFAULT_ROOT_ALIAS; } $lmTable = $rel->cm->t; $this->setInvolvedTable($lmAlias, $lmTable); // Make the join between both tables: $sep = Cfg::get('queryOptionRelationSeparator'); if ($rel instanceof ManyMany) { $mdTable = $rel->getMiddleTableName(); $mdAlias = $rel->getMiddleTableAlias(); $mdAlias = $lmAlias === self::DEFAULT_ROOT_ALIAS ? $mdAlias : $lmAlias . '.' . $mdAlias; // Join middle table. $jc = new JoinClause($mdTable, $mdAlias); $jc->on($this->getRootAlias(), $rel->lm->column, $mdAlias, $rel->jm->to); $this->setJoinClause($mdAlias, $jc); // Where on relation. $lmCols = $rel->cm->column; $mdCols = $rel->jm->from; $this->whereCol($mdAlias, $mdCols, '=', $lmAlias, $lmCols); } else { // $lmAttr: attribute of the model to link. (The relation CM attr) // $cmAttr: current builder root model attribute. (The relation LM attr) foreach ($rel->getJoinAttributes() as $lmAttr => $cmAttr) { $this->whereAttr($cmAttr, $lmAlias . $sep . $lmAttr); } } return $this; }