diff --git a/src/ORM/EagerLoader.php b/src/ORM/EagerLoader.php index 39a6de41cee..c9eb37a12d9 100644 --- a/src/ORM/EagerLoader.php +++ b/src/ORM/EagerLoader.php @@ -99,6 +99,40 @@ public function matching($assoc, callable $builder = null) { return $this->contain($containments); } +/** + * Returns the fully normalized array of associations that should be eagerly + * loaded for a table. The normalized array will restructure the original array + * by sorting all associations under one key and special options under another. + * + * Additionally it will set an 'instance' key per association containing the + * association instance from the corresponding source table + * + * @param \Cake\ORM\Table $repository The table containing the association that + * will be normalized + * @return array + */ + public function normalized(Table $repository) { + if ($this->_normalized !== null || empty($this->_containments)) { + return $this->_normalized; + } + + $contain = []; + foreach ($this->_containments as $table => $options) { + if (!empty($options['instance'])) { + $contain = (array)$this->_containments; + break; + } + $contain[$table] = $this->_normalizeContain($repository, $table, $options); + } + + return $this->_normalized = $contain; + } + + public function hasExternal(Table $repository) { + $this->normalized($repository); + return !empty($this->_loadEagerly); + } + /** * Formats the containments array so that associations are always set as keys * in the array. This function merges the original associations array with @@ -148,64 +182,19 @@ protected function _reformatContain($associations, $original) { return $result; } -/** - * Returns the fully normalized array of associations that should be eagerly - * loaded for a table. The normalized array will restructure the original array - * by sorting all associations under one key and special options under another. - * - * Additionally it will set an 'instance' key per association containing the - * association instance from the corresponding source table - * - * @param \Cake\ORM\Table $repository The table containing the association that - * will be normalized - * @return array - */ - public function normalized(Table $repository) { - if ($this->_normalized !== null || empty($this->_containments)) { - return $this->_normalized; - } - - $contain = []; - foreach ($this->_containments as $table => $options) { - if (!empty($options['instance'])) { - $contain = (array)$this->_containments; - break; - } - $contain[$table] = $this->_normalizeContain( - $repository, - $table, - $options - ); - } - - return $this->_normalized = $contain; - } - /** * * @return void */ public function attachAssociations($query, $includeFields) { - $this->_loadEagerly = []; if (empty($this->_containments)) { return; } $contain = $this->normalized($query->repository()); - foreach ($contain as $relation => $meta) { - if ($meta['instance'] && !$meta['canBeJoined']) { - $this->_loadEagerly[$relation] = $meta; - } - } - foreach ($this->_resolveJoins($contain) as $options) { $config = $options['config'] + ['includeFields' => $includeFields]; $options['instance']->attachTo($query, $config); - foreach ($options['associations'] as $relation => $meta) { - if ($meta['instance'] && !$meta['canBeJoined']) { - $this->_loadEagerly[$relation] = $meta; - } - } } } @@ -238,6 +227,10 @@ protected function _normalizeContain(Table $parent, $alias, $options) { ]; $config['canBeJoined'] = $instance->canBeJoined($config['config']); + if (!$config['canBeJoined']) { + $this->_loadEagerly[$alias] = $config; + } + foreach ($extra as $t => $assoc) { $config['associations'][$t] = $this->_normalizeContain($table, $t, $assoc); } diff --git a/src/ORM/Query.php b/src/ORM/Query.php index 32ab709c5cd..ea71da5d173 100644 --- a/src/ORM/Query.php +++ b/src/ORM/Query.php @@ -903,11 +903,13 @@ protected function _decorateResults($result) { */ protected function _decorateStatement($statement) { $statement = parent::_decorateStatement($statement); - if ($this->_loadEagerly) { + $loader = $this->eagerLoader(); + + if ($loader->hasExternal($this->repository())) { if (!($statement instanceof BufferedStatement)) { $statement = new BufferedStatement($statement, $this->connection()->driver()); } - $statement = $this->eagerLoader()->eagerLoad($statement); + $statement = $loader->eagerLoad($statement); } return $statement;