/** * Builds a query for loading the passed list of entity objects along with the * associations specified in $contain. * * @param \Cake\Collection\CollectionInterface $objects The original entities * @param array $contain The associations to be loaded * @param \Cake\ORM\Table $source The table to use for fetching the top level entities * @return \Cake\ORM\Query */ protected function _getQuery($objects, $contain, $source) { $primaryKey = $source->primaryKey(); $method = is_string($primaryKey) ? 'get' : 'extract'; $keys = $objects->map(function ($entity) use($primaryKey, $method) { return $entity->{$method}($primaryKey); }); $query = $source->find()->select((array) $primaryKey)->where(function ($exp, $q) use($primaryKey, $keys, $source) { if (is_array($primaryKey) && count($primaryKey) === 1) { $primaryKey = current($primaryKey); } if (is_string($primaryKey)) { return $exp->in($source->aliasField($primaryKey), $keys->toList()); } $types = array_intersect_key($q->defaultTypes(), array_flip($primaryKey)); $primaryKey = array_map([$source, 'aliasField'], $primaryKey); return new TupleComparison($primaryKey, $keys->toList(), $types, 'IN'); })->contain($contain); foreach ($query->eagerLoader()->attachableAssociations($source) as $loadable) { $config = $loadable->config(); $config['includeFields'] = true; $loadable->config($config); } return $query; }
/** * {@inheritDoc} */ protected function _hydrateEntities(CollectionInterface $entities, array $args) { return $entities->map(function ($entity) use($args) { if ($entity instanceof EntityInterface) { $entity = $this->_prepareCachedColumns($entity); $entity = $this->_attachEntityFields($entity, $args); if ($entity === null) { return self::NULL_ENTITY; } } return $entity; })->filter(function ($entity) { return $entity !== self::NULL_ENTITY; }); }