/**
  * 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;
 }
Example #2
0
 /**
  * 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];
 }
Example #5
0
 /**
  * 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()));
     }
 }