/** * Alters a Query object to include the associated target table data in the final * result * * The options array accept the following keys: * * - includeFields: Whether to include target model fields in the result or not * - foreignKey: The name of the field to use as foreign key, if false none * will be used * - conditions: array with a list of conditions to filter the join with * - fields: a list of fields in the target table to include in the result * - type: The type of join to be used (e.g. INNER) * * @param Query $query the query to be altered to include the target table data * @param array $options Any extra options or overrides to be taken in account * @return void */ public function attachTo(Query $query, array $options = []) { parent::attachTo($query, $options); $junction = $this->junction(); $belongsTo = $junction->association($this->source()->alias()); $cond = $belongsTo->_joinCondition(['foreignKey' => $belongsTo->foreignKey()]); if (isset($options['includeFields'])) { $includeFields = $options['includeFields']; } unset($options['queryBuilder']); $options = ['conditions' => [$cond]] + compact('includeFields'); $options['foreignKey'] = $this->targetForeignKey(); $assoc = $this->_targetTable->association($junction->alias()); $assoc->attachTo($query, $options); $query->eagerLoader()->addToJoinsMap($junction->alias(), $assoc, true); }
/** * Alters a Query object to include the associated target table data in the final * result * * The options array accept the following keys: * * - includeFields: Whether to include target model fields in the result or not * - foreignKey: The name of the field to use as foreign key, if false none * will be used * - conditions: array with a list of conditions to filter the join with * - fields: a list of fields in the target table to include in the result * - type: The type of join to be used (e.g. INNER) * * @param Query $query the query to be altered to include the target table data * @param array $options Any extra options or overrides to be taken in account * @return void */ public function attachTo(Query $query, array $options = []) { parent::attachTo($query, $options); $junction = $this->junction(); $belongsTo = $junction->association($this->source()->alias()); $cond = $belongsTo->_joinCondition(['foreignKey' => $belongsTo->foreignKey()]); $cond += $this->junctionConditions(); if (isset($options['includeFields'])) { $includeFields = $options['includeFields']; } // Attach the junction table as well we need it to populate _joinData. $assoc = $this->_targetTable->association($junction->alias()); $query->removeJoin($assoc->name()); $options = array_intersect_key($options, ['joinType' => 1, 'fields' => 1]); $options += ['conditions' => $cond, 'includeFields' => $includeFields, 'foreignKey' => $this->targetForeignKey()]; $assoc->attachTo($query, $options); $query->eagerLoader()->addToJoinsMap($junction->alias(), $assoc, true); }
/** * Alters a Query object to include the associated target table data in the final * result * * The options array accept the following keys: * * - includeFields: Whether to include target model fields in the result or not * - foreignKey: The name of the field to use as foreign key, if false none * will be used * - conditions: array with a list of conditions to filter the join with * - fields: a list of fields in the target table to include in the result * - type: The type of join to be used (e.g. INNER) * * @param \Cake\ORM\Query $query the query to be altered to include the target table data * @param array $options Any extra options or overrides to be taken in account * @return void */ public function attachTo(Query $query, array $options = []) { if (!empty($options['negateMatch'])) { $this->_appendNotMatching($query, $options); return; } $junction = $this->junction(); $belongsTo = $junction->association($this->source()->alias()); $cond = $belongsTo->_joinCondition(['foreignKey' => $belongsTo->foreignKey()]); $cond += $this->junctionConditions(); if (isset($options['includeFields'])) { $includeFields = $options['includeFields']; } // Attach the junction table as well we need it to populate _joinData. $assoc = $this->_targetTable->association($junction->alias()); $newOptions = array_intersect_key($options, ['joinType' => 1, 'fields' => 1]); $newOptions += ['conditions' => $cond, 'includeFields' => $includeFields, 'foreignKey' => false]; $assoc->attachTo($query, $newOptions); $query->eagerLoader()->addToJoinsMap($junction->alias(), $assoc, true); parent::attachTo($query, $options); $foreignKey = $this->targetForeignKey(); $thisJoin = $query->clause('join')[$this->name()]; $thisJoin['conditions']->add($assoc->_joinCondition(['foreignKey' => $foreignKey])); }