diff --git a/core/modules/field/field.crud.inc b/core/modules/field/field.crud.inc index ec2daa3..bbd0d45 100644 --- a/core/modules/field/field.crud.inc +++ b/core/modules/field/field.crud.inc @@ -154,64 +154,11 @@ function field_read_fields($conditions = array(), $include_additional = array()) // the $conditions parameters. $include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']) || (isset($conditions['deleted']) && $conditions['deleted']); - // Get fields stored in configuration. - if (isset($conditions['field_name'])) { - // Optimize for the most frequent case where we do have a specific ID. - $fields = entity_load_multiple('field_entity', array($conditions['field_name'])); - } - else { - // No specific ID, we need to examine all existing fields. - $fields = entity_load_multiple('field_entity'); - } - - // Merge deleted fields (stored in state) if needed. - if ($include_deleted) { - $deleted_fields = Drupal::state()->get('field.field.deleted') ?: array(); - foreach ($deleted_fields as $id => $config) { - $fields[$id] = entity_create('field_entity', $config); - } - } - - // Translate "do not include inactive instances" into actual conditions. - if (!$include_inactive) { - $conditions['active'] = TRUE; - $conditions['storage.active'] = TRUE; - } - - // Collect matching fields. - $matching_fields = array(); - foreach ($fields as $field) { - foreach ($conditions as $key => $value) { - // Extract the actual value against which the condition is checked. - switch ($key) { - case 'storage.active': - $checked_value = $field->storage['active']; - break; - - case 'field_name'; - $checked_value = $field->id; - break; - - default: - $checked_value = $field->$key; - break; - } - - // Skip to the next field as soon as one condition does not match. - if ($checked_value != $value) { - continue 2; - } - } - - module_invoke_all('field_read_field', $field); - - // When returning deleted fields, key the results by UUID since they can - // include several fields with the same ID. - $key = $include_deleted ? $field->uuid : $field->id; - $matching_fields[$key] = $field; - } + // Pass include_inactive and include_deleted to the $conditions array. + $conditions['include_inactive'] = $include_inactive; + $conditions['include_deleted'] = $include_deleted; - return $matching_fields; + return entity_load_multiple_by_properties('field_entity', $conditions); } /** @@ -362,80 +309,11 @@ function field_read_instances($conditions = array(), $include_additional = array // or the $conditions parameters. $include_deleted = (isset($include_additional['include_deleted']) && $include_additional['include_deleted']) || (isset($conditions['deleted']) && $conditions['deleted']); - // Get instances stored in configuration. - if (isset($conditions['entity_type']) && isset($conditions['bundle']) && isset($conditions['field_name'])) { - // Optimize for the most frequent case where we do have a specific ID. - $instances = entity_load_multiple('field_instance', array($conditions['entity_type'] . '.' . $conditions['bundle'] . '.' . $conditions['field_name'])); - } - else { - // No specific ID, we need to examine all existing instances. - $instances = entity_load_multiple('field_instance'); - } - - // Merge deleted instances (stored in state) if needed. - if ($include_deleted) { - $state = Drupal::state(); - $deleted_fields = $state->get('field.field.deleted'); - $deleted_instances = $state->get('field.instance.deleted') ?: array(); - foreach ($deleted_instances as $id => $config) { - $instances[$id] = entity_create('field_instance', $config); - } - } - - // Translate "do not include inactive fields" into actual conditions. - if (!$include_inactive) { - $conditions['field.active'] = TRUE; - $conditions['field.storage.active'] = TRUE; - } - - // Collect matching instances. - $matching_instances = array(); - foreach ($instances as $instance) { - // Only include instances on unknown entity types if 'include_inactive'. - if (!$include_inactive && !entity_get_info($instance->entity_type)) { - continue; - } - - // Some conditions are checked against the field. - $field = $instance->getField(); - - // Only keep the instance if it matches all conditions. - foreach ($conditions as $key => $value) { - // Extract the actual value against which the condition is checked. - switch ($key) { - case 'field_name': - $checked_value = $field->id; - break; - - case 'field.active': - $checked_value = $field->active; - break; - - case 'field.storage.active': - $checked_value = $field->storage['active']; - break; - - case 'field_id': - $checked_value = $instance->field_uuid; - break; - - default: - $checked_value = $instance->$key; - break; - } - - // Skip to the next instance as soon as one condition does not match. - if ($checked_value != $value) { - continue 2; - } - } - - module_invoke_all('field_read_instance', $instance); - - $matching_instances[] = $instance; - } + // Pass include_inactive and include_deleted to the $conditions array. + $conditions['include_inactive'] = $include_inactive; + $conditions['include_deleted'] = $include_deleted; - return $matching_instances; + return entity_load_multiple_by_properties('field_instance', $conditions); } /** diff --git a/core/modules/field/lib/Drupal/field/FieldInstanceStorageController.php b/core/modules/field/lib/Drupal/field/FieldInstanceStorageController.php index 1af555e..71b9424 100644 --- a/core/modules/field/lib/Drupal/field/FieldInstanceStorageController.php +++ b/core/modules/field/lib/Drupal/field/FieldInstanceStorageController.php @@ -9,6 +9,11 @@ use Drupal\Core\Config\Config; use Drupal\Core\Config\Entity\ConfigStorageController; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\Config\ConfigFactory; +use Drupal\Core\Config\StorageInterface; +use Drupal\Core\Entity\EntityManager; +use Drupal\Core\Extension\ModuleHandler; /** * Controller class for field instances. @@ -21,6 +26,69 @@ class FieldInstanceStorageController extends ConfigStorageController { /** + * The module handler. + * + * @var \Drupal\Core\Extension\ModuleHandler + */ + protected $moduleHandler; + + /** + * The entity manager + * + * @var \Drupal\Core\Entity\EntityManager + */ + protected $entityManager; + + /** + * Constructs a FieldInstanceStorageController object. + * + * @param string $entity_type + * The entity type for which the instance is created. + * @param array $entity_info + * An array of entity info for the entity type. + * @param \Drupal\Core\Config\ConfigFactory $config_factory + * The config factory service. + * @param \Drupal\Core\Config\StorageInterface $config_storage + * The config storage service. + * @param \Drupal\Core\Entity\EntityManager $entity_manager + * The entity manager. + * @param \Drupal\Core\Extension\ModuleHandler $module_handler + * The module handler. + */ + public function __construct($entity_type, array $entity_info, ConfigFactory $config_factory, StorageInterface $config_storage, EntityManager $entity_manager, ModuleHandler $module_handler) { + $this->entityType = $entity_type; + $this->entityInfo = $entity_info; + $this->hookLoadArguments = array(); + $this->idKey = $this->entityInfo['entity_keys']['id']; + + if (isset($this->entityInfo['entity_keys']['status'])) { + $this->statusKey = $this->entityInfo['entity_keys']['status']; + } + else { + $this->statusKey = FALSE; + } + + $this->configFactory = $config_factory; + $this->configStorage = $config_storage; + $this->entityManager = $entity_manager; + $this->moduleHandler = $module_handler; + } + + /** + * {@inheritdoc} + */ + public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) { + return new static( + $entity_type, + $entity_info, + $container->get('config.factory'), + $container->get('config.storage'), + $container->get('plugin.manager.entity'), + $container->get('module_handler') + ); + } + + /** * {@inheritdoc} */ public function importDelete($name, Config $new_config, Config $old_config) { @@ -33,4 +101,91 @@ public function importDelete($name, Config $new_config, Config $old_config) { return parent::importDelete($name, $new_config, $old_config); } + /** + * {@inheritdoc} + */ + public function loadByProperties(array $conditions = array()) { + // Include instances of inactive fields if specified in the + // $conditions parameters. + $include_inactive = $conditions['include_inactive']; + unset($conditions['include_inactive']); + // Include deleted instances if specified in the $conditions parameters. + $include_deleted = $conditions['include_deleted']; + unset($conditions['include_deleted']); + + // Get instances stored in configuration. + if (isset($conditions['entity_type']) && isset($conditions['bundle']) && isset($conditions['field_name'])) { + // Optimize for the most frequent case where we do have a specific ID. + $instances = $this->entityManager->getStorageController($this->entityType)->load(array($conditions['entity_type'] . '.' . $conditions['bundle'] . '.' . $conditions['field_name'])); + } + else { + // No specific ID, we need to examine all existing instances. + $instances = $this->entityManager->getStorageController($this->entityType)->load(); + } + + // Merge deleted instances (stored in state) if needed. + if ($include_deleted) { + $state = \Drupal::state(); + $deleted_instances = $state->get('field.instance.deleted') ?: array(); + foreach ($deleted_instances as $id => $config) { + $instances[$id] = $this->entityManager->getStorageController($this->entityType)->create($config); + } + } + + // Translate "do not include inactive fields" into actual conditions. + if (!$include_inactive) { + $conditions['field.active'] = TRUE; + $conditions['field.storage.active'] = TRUE; + } + + // Collect matching instances. + $matching_instances = array(); + foreach ($instances as $instance) { + // Only include instances on unknown entity types if 'include_inactive'. + if (!$include_inactive && !$this->entityManager->getDefinition($instance->entity_type)) { + continue; + } + + // Some conditions are checked against the field. + $field = $instance->getField(); + + // Only keep the instance if it matches all conditions. + foreach ($conditions as $key => $value) { + // Extract the actual value against which the condition is checked. + switch ($key) { + case 'field_name': + $checked_value = $field->id; + break; + + case 'field.active': + $checked_value = $field->active; + break; + + case 'field.storage.active': + $checked_value = $field->storage['active']; + break; + + case 'field_id': + $checked_value = $instance->field_uuid; + break; + + default: + $checked_value = $instance->$key; + break; + } + + // Skip to the next instance as soon as one condition does not match. + if ($checked_value != $value) { + continue 2; + } + } + + $this->moduleHandler->invokeAll('field_read_instance', $instance); + + $matching_instances[] = $instance; + } + + return $matching_instances; + } + } diff --git a/core/modules/field/lib/Drupal/field/FieldStorageController.php b/core/modules/field/lib/Drupal/field/FieldStorageController.php new file mode 100644 index 0000000..53ca2fa --- /dev/null +++ b/core/modules/field/lib/Drupal/field/FieldStorageController.php @@ -0,0 +1,158 @@ +entityType = $entity_type; + $this->entityInfo = $entity_info; + $this->hookLoadArguments = array(); + $this->idKey = $this->entityInfo['entity_keys']['id']; + + if (isset($this->entityInfo['entity_keys']['status'])) { + $this->statusKey = $this->entityInfo['entity_keys']['status']; + } + else { + $this->statusKey = FALSE; + } + + $this->configFactory = $config_factory; + $this->configStorage = $config_storage; + $this->entityManager = $entity_manager; + $this->moduleHandler = $module_handler; + } + + /** + * {@inheritdoc} + */ + public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) { + return new static( + $entity_type, + $entity_info, + $container->get('config.factory'), + $container->get('config.storage'), + $container->get('plugin.manager.entity'), + $container->get('module_handler') + ); + } + + /** + * {@inheritdoc} + */ + public function loadByProperties(array $conditions = array()) { + // Include instances of inactive fields if specified in the + // $conditions parameters. + $include_inactive = $conditions['include_inactive']; + unset($conditions['include_inactive']); + // Include deleted instances if specified in the $conditions parameters. + $include_deleted = $conditions['include_deleted']; + unset($conditions['include_deleted']); + + // Get fields stored in configuration. + if (isset($conditions['field_name'])) { + // Optimize for the most frequent case where we do have a specific ID. + $fields = $this->entityManager->getStorageController($this->entityType)->load(array($conditions['field_name'])); + } + else { + // No specific ID, we need to examine all existing fields. + $fields = $this->entityManager->getStorageController($this->entityType)->load(); + } + + // Merge deleted fields (stored in state) if needed. + if ($include_deleted) { + $deleted_fields = \Drupal::state()->get('field.field.deleted') ?: array(); + foreach ($deleted_fields as $id => $config) { + $fields[$id] = $this->entityManager->getStorageController($this->entityType)->create($config); + } + } + + // Translate "do not include inactive instances" into actual conditions. + if (!$include_inactive) { + $conditions['active'] = TRUE; + $conditions['storage.active'] = TRUE; + } + + // Collect matching fields. + $matching_fields = array(); + foreach ($fields as $field) { + foreach ($conditions as $key => $value) { + // Extract the actual value against which the condition is checked. + switch ($key) { + case 'storage.active': + $checked_value = $field->storage['active']; + break; + + case 'field_name'; + $checked_value = $field->id; + break; + + default: + $checked_value = $field->$key; + break; + } + + // Skip to the next field as soon as one condition does not match. + if ($checked_value != $value) { + continue 2; + } + } + + $this->moduleHandler->invokeAll('field_read_field', $field); + + // When returning deleted fields, key the results by UUID since they can + // include several fields with the same ID. + $key = $include_deleted ? $field->uuid : $field->id; + $matching_fields[$key] = $field; + } + + return $matching_fields; + + } +} diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/Field.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/Field.php index 262781c..55e53cf 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/Field.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/Field.php @@ -24,7 +24,7 @@ * label = @Translation("Field"), * module = "field", * controllers = { - * "storage" = "Drupal\Core\Config\Entity\ConfigStorageController" + * "storage" = "Drupal\field\FieldStorageController" * }, * config_prefix = "field.field", * entity_keys = {