diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php index 00c9d73..bcb7672 100644 --- a/core/lib/Drupal/Core/Entity/EntityManager.php +++ b/core/lib/Drupal/Core/Entity/EntityManager.php @@ -328,11 +328,28 @@ protected function buildBaseFieldDefinitions($entity_type_id) { $entity_type = $this->getDefinition($entity_type_id); $class = $entity_type->getClass(); + $provider = $entity_type->getProvider(); $base_field_definitions = $class::baseFieldDefinitions($entity_type); + foreach ($base_field_definitions as $definition) { + $definition->setProvider($provider); + } + + // Retrieve base field definitions from modules. + $base_field_module_definitions = array(); + $hook = 'entity_base_field_info'; + foreach ($this->moduleHandler->getImplementations($hook) as $module) { + $module_definitions = call_user_func($module . '_' . $hook, $entity_type); + if (isset($module_definitions) && is_array($module_definitions)) { + // Ensure the module key actually matches the name of the module defining + // the field. + foreach ($module_definitions as $definition) { + $definition->setProvider($provider); + } + $return = NestedArray::mergeDeep($base_field_module_definitions, $module_definitions); + } + } - // Invoke hook. - $result = $this->moduleHandler->invokeAll('entity_base_field_info', array($entity_type)); - $base_field_definitions = NestedArray::mergeDeep($base_field_definitions, $result); + $base_field_definitions = NestedArray::mergeDeep($base_field_definitions, $base_field_module_definitions); // Automatically set the field name for non-configurable fields. foreach ($base_field_definitions as $field_name => $base_field_definition) { @@ -343,7 +360,7 @@ protected function buildBaseFieldDefinitions($entity_type_id) { } // Invoke alter hook. - $this->moduleHandler->alter('entity_base_field_info', $base_field_definitions, $entity_type); + $this->moduleHandler->alter($hook, $base_field_definitions, $entity_type); // Ensure all basic fields are not defined as translatable. $keys = array_intersect_key(array_filter($entity_type->getKeys()), array_flip(array('id', 'revision', 'uuid', 'bundle'))); @@ -402,10 +419,29 @@ protected function buildBundleFieldDefinitions($entity_type_id, $bundle, array $ $class = $entity_type->getClass(); // Allow the entity class to override the base fields. + $provider = $entity_type->getProvider(); $bundle_field_definitions = $class::bundleFieldDefinitions($entity_type, $bundle, $base_field_definitions); + foreach ($base_field_definitions as $definition) { + $definition->setProvider($provider); + } + + // Retrieve base field definitions from modules. + $base_field_module_definitions = array(); + $hook = 'entity_bundle_field_info'; + foreach ($this->moduleHandler->getImplementations($hook) as $module) { + $module_definitions = call_user_func($module . '_' . $hook, $entity_type, $bundle, $base_field_definitions); + if (isset($module_definitions) && is_array($module_definitions)) { + // Ensure the module key actually matches the name of the module defining + // the field. + foreach ($module_definitions as $definition) { + $definition->setProvider($provider); + } + $return = NestedArray::mergeDeep($base_field_module_definitions, $module_definitions); + } + } // Invoke 'per bundle' hook. - $result = $this->moduleHandler->invokeAll('entity_bundle_field_info', array($entity_type, $bundle, $base_field_definitions)); + $result = $this->moduleHandler->invokeAll($hook, array($entity_type, $bundle, $base_field_definitions)); $bundle_field_definitions = NestedArray::mergeDeep($bundle_field_definitions, $result); // Automatically set the field name for non-configurable fields. diff --git a/core/lib/Drupal/Core/Field/FieldDefinition.php b/core/lib/Drupal/Core/Field/FieldDefinition.php index 70a985a..c0732ad 100644 --- a/core/lib/Drupal/Core/Field/FieldDefinition.php +++ b/core/lib/Drupal/Core/Field/FieldDefinition.php @@ -151,6 +151,27 @@ public function setSetting($setting_name, $value) { /** * {@inheritdoc} */ + public function getProvider() { + return $this->definition['provider']; + } + + /** + * Sets the name of the provider of this field. + * + * @param string $provider + * The provider name. + * + * @return static + * The object itself for chaining. + */ + public function setProvider($provider) { + $this->definition['provider'] = $provider; + return $this; + } + + /** + * {@inheritdoc} + */ public function isTranslatable() { return !empty($this->definition['translatable']); } @@ -453,4 +474,26 @@ public static function getReservedColumns() { return array('deleted'); } + /** + * {@inheritdoc} + */ + public function isCustomStorage() { + return !empty($this->definition['custom_storage']); + } + + /** + * Sets the storage behavior for this field. + * + * @param bool $custom_storage + * Pass TRUE if the field module will take care of storing field values, + * FALSE otherwise. + * + * @return static + * The object itself for chaining. + */ + public function setCustomStorage($custom_storage) { + $this->definition['custom_storage'] = $custom_storage; + return $this; + } + } diff --git a/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php b/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php index c28f911..cfc497b 100644 --- a/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php +++ b/core/lib/Drupal/Core/Field/FieldDefinitionInterface.php @@ -104,6 +104,14 @@ public function getSettings(); public function getSetting($setting_name); /** + * Returns the name of the provider of this field. + * + * @return string + * The module name. + */ + public function getProvider(); + + /** * Returns whether the field is translatable. * * @return bool @@ -336,4 +344,16 @@ public function getSchema(); */ public function getColumns(); + /** + * Returns the storage behavior for this field. + * + * This indicates whether the storage controller should take care of storing + * the field values or whether the field module will do it. + * + * @return bool + * TRUE if the field module takes care of storing field values, FALSE + * otherwise. + */ + public function isCustomStorage(); + } diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php index 20ff0de..522264a 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php @@ -478,6 +478,13 @@ public function getSchema() { /** * {@inheritdoc} */ + public function isCustomStorage() { + return FALSE; + } + + /** + * {@inheritdoc} + */ public function getColumns() { $schema = $this->getSchema(); // A typical use case for the method is to iterate on the columns, while @@ -576,6 +583,13 @@ public function setTranslatable($translatable) { /** * {@inheritdoc} */ + public function getProvider() { + return 'field'; + } + + /** + * {@inheritdoc} + */ public function getLabel() { return $this->label(); } diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php index 2b8e87f..73a0845 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php @@ -501,6 +501,13 @@ public function getSetting($setting_name) { /** * {@inheritdoc} */ + public function getProvider() { + return $this->field->getProvider(); + } + + /** + * {@inheritdoc} + */ public function isTranslatable() { return $this->field->translatable; } @@ -765,4 +772,11 @@ public function getColumns() { return $this->field->getColumns(); } + /** + * {@inheritdoc} + */ + public function isCustomStorage() { + return $this->field->isCustomStorage(); + } + }