/** * Builds a query to be used as a condition for filtering records in the * target table, it is constructed by cloning the original query that was used * to load records in the source table. * * @param \Cake\ORM\Query $query the original query used to load source records * @return \Cake\ORM\Query */ protected function _buildSubquery($query) { $filterQuery = clone $query; $filterQuery->autoFields(false); $filterQuery->mapReduce(null, null, true); $filterQuery->formatResults(null, true); $filterQuery->contain([], true); if (!$filterQuery->clause('limit')) { $filterQuery->limit(null); $filterQuery->order([], true); $filterQuery->offset(null); } $keys = (array) $this->bindingKey(); if ($this->type() === $this::MANY_TO_ONE) { $keys = (array) $this->foreignKey(); } $fields = $query->aliasFields($keys, $this->source()->alias()); $filterQuery->select($fields, true)->group(array_values($fields)); return $filterQuery; }
/** * Helper function used to conditionally append fields to the select clause of * a query from the fields found in another query object. * * @param \Cake\ORM\Query $query the query that will get the fields appended to * @param \Cake\ORM\Query $surrogate the query having the fields to be copied from * @param array $options options passed to the method `attachTo` * @return void */ protected function _appendFields($query, $surrogate, $options) { $fields = $surrogate->clause('select') ?: $options['fields']; $target = $this->_targetTable; $autoFields = $surrogate->autoFields(); if ($query->eagerLoader()->autoFields() === false) { return; } if (empty($fields) && !$autoFields) { if ($options['includeFields'] && ($fields === null || $fields !== false)) { $fields = $target->schema()->columns(); } } if ($autoFields === true) { $fields = array_merge((array) $fields, $target->schema()->columns()); } if (!empty($fields)) { $query->select($query->aliasFields($fields, $target->alias())); } }
/** * Builds a query to be used as a condition for filtering records in the * target table, it is constructed by cloning the original query that was used * to load records in the source table. * * @param \Cake\ORM\Query $query the original query used to load source records * @return \Cake\ORM\Query */ protected function _buildSubquery($query) { $filterQuery = clone $query; $filterQuery->limit(null); $filterQuery->order([], true); $filterQuery->contain([], true); $joins = $filterQuery->join(); foreach ($joins as $i => $join) { if (strtolower($join['type']) !== 'inner') { unset($joins[$i]); } } $keys = (array) $query->repository()->primaryKey(); if ($this->type() === $this::MANY_TO_ONE) { $keys = (array) $this->foreignKey(); } $filterQuery->join($joins, [], true); $fields = $query->aliasFields($keys); return $filterQuery->select($fields, true); }
/** * Calculate the fields that need to participate in a subquery. * * Normally this includes the binding key columns. If there is a an ORDER BY, * those columns are also included as the fields may be calculated or constant values, * that need to be present to ensure the correct association data is loaded. * * @param \Cake\ORM\Query $query The query to get fields from. * @return array The list of fields for the subquery. */ protected function _subqueryFields($query) { $keys = (array) $this->bindingKey(); if ($this->type() === $this::MANY_TO_ONE) { $keys = (array) $this->foreignKey(); } $fields = $query->aliasFields($keys, $this->source()->alias()); $group = $fields = array_values($fields); $order = $query->clause('order'); if ($order) { $columns = $query->clause('select'); $order->iterateParts(function ($direction, $field) use(&$fields, $columns) { if (isset($columns[$field])) { $fields[$field] = $columns[$field]; } }); } return ['select' => $fields, 'group' => $group]; }
/** * Helper function used to conditionally append fields to the select clause of * a query from the fields found in another query object. * * @param \Cake\ORM\Query $query the query that will get the fields appended to * @param \Cake\ORM\Query $surrogate the query having the fields to be copied from * @param array $options options passed to the method `attachTo` * @return void */ protected function _appendFields($query, $surrogate, $options) { $options['fields'] = $surrogate->clause('select') ?: $options['fields']; $target = $this->_targetTable; if (empty($options['fields'])) { $f = isset($options['fields']) ? $options['fields'] : null; if ($options['includeFields'] && ($f === null || $f !== false)) { $options['fields'] = $target->schema()->columns(); } } if (!empty($options['fields'])) { $query->select($query->aliasFields($options['fields'], $target->alias())); } }