diff --git a/core/lib/Drupal/Core/Config/Entity/Query/Query.php b/core/lib/Drupal/Core/Config/Entity/Query/Query.php index 130f171..5782503 100644 --- a/core/lib/Drupal/Core/Config/Entity/Query/Query.php +++ b/core/lib/Drupal/Core/Config/Entity/Query/Query.php @@ -84,17 +84,10 @@ public function condition($property, $value = NULL, $operator = NULL, $langcode * Implements \Drupal\Core\Entity\Query\QueryInterface::execute(). */ public function execute() { - // Load all config files. - $entity_info = $this->entityManager->getDefinition($this->getEntityType()); - $prefix = $entity_info->getConfigPrefix() . '.'; - $prefix_length = strlen($prefix); - $names = $this->configStorage->listAll($prefix); - $configs = array(); - $config_objects = $this->configFactory->loadMultiple($names); - foreach ($config_objects as $config) { - $configs[substr($config->getName(), $prefix_length)] = $config->get(); - } + // Load the relevant config records. + $configs = $this->loadRecords(); + // Apply conditions. $result = $this->condition->compile($configs); // Apply sort settings. @@ -124,4 +117,54 @@ public function execute() { return $result; } + /** + * Loads the config records to examine for the query. + * + * @return array + * Config records keyed by entity IDs. + */ + protected function loadRecords() { + $entity_info = $this->entityManager->getDefinition($this->getEntityType()); + $prefix = $entity_info['config_prefix'] . '.'; + $prefix_length = strlen($prefix); + + // If there are conditions on the config ID, we can narrow the list of + // records to load and parse. + $ids = array(); + if ($this->condition->getConjunction() == 'AND') { + foreach ($this->condition->conditions() as $condition) { + if ($condition['field'] == $entity_info['entity_keys']['id']) { + $operator = $condition['operator']; + if (!isset($condition['operator'])) { + $operator = is_array($condition['value']) ? 'IN' : '='; + } + if ($operator == '=' || $operator == 'IN') { + $ids = is_array($condition['value']) ? $condition['value'] : array($condition['value']); + // We can stop at the first condition on ID. In the (weird) case + // where other conditions additionally restrict IDs, results will + // be eliminated when the conditions are checked on the loaded + // records. + break; + } + } + } + } + if ($ids) { + $names = array_map(function ($id) use ($prefix) { + return $prefix . $id; + }, $ids); + } + else { + // If no conditions on IDs were found, we need to parse all records. + $names = $this->configStorage->listAll($prefix); + } + + // Load the corresponding records. + $records = array(); + foreach ($this->configFactory->loadMultiple($names) as $config) { + $records[substr($config->getName(), $prefix_length)] = $config->get(); + } + return $records; + } + }