diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module index 97e9db0..528a8af 100644 --- a/core/modules/entity_reference/entity_reference.module +++ b/core/modules/entity_reference/entity_reference.module @@ -192,33 +192,35 @@ function entity_reference_field_settings_form($field, $instance, $has_data) { } /** - * Implements hook_field_update_field(). + * Implements hook_entity_update(). * * Reset the instance handler settings, when the target type is changed. */ -function entity_reference_field_update_field($field, $prior_field, $has_data) { - if ($field['type'] != 'entity_reference') { - // Not an entity reference field. - return; - } +function entity_reference_entity_update(EntityInterface $entity) { + if ($entity->entityType() == 'field_entity' && $entity->type == 'entity_reference') { + if ($entity['type'] != 'entity_reference') { + // Not an entity reference field. + return; + } - if ($field['settings']['target_type'] == $prior_field['settings']['target_type']) { - // Target type didn't change. - return; - } + if ($entity['settings']['target_type'] == $entity->originalField['settings']['target_type']) { + // Target type didn't change. + return; + } - if (empty($field['bundles'])) { - // Field has no instances. - return; - } + if (empty($entity['bundles'])) { + // Field has no instances. + return; + } - $field_name = $field['field_name']; + $field_name = $$entity['field_name']; - foreach ($field['bundles'] as $entity_type => $bundles) { - foreach ($bundles as $bundle) { - $instance = field_info_instance($entity_type, $field_name, $bundle); - $instance['settings']['handler_settings'] = array(); - field_update_instance($instance); + foreach ($entity['bundles'] as $entity_type => $bundles) { + foreach ($bundles as $bundle) { + $instance = field_info_instance($entity_type, $field_name, $bundle); + $instance['settings']['handler_settings'] = array(); + field_update_instance($instance); + } } } } diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php index 75a99df..2202978 100644 --- a/core/modules/field/field.api.php +++ b/core/modules/field/field.api.php @@ -1820,33 +1820,6 @@ function hook_field_info_max_weight($entity_type, $bundle, $context, $context_mo */ /** - * Act on a field being created. - * - * This hook lets modules react to the creation of a field. It is called after - * the definition is saved, so it cannot be used to modify the field itself. - * - * @param $field - * The field just created. - */ -function hook_field_create_field($field) { - // @todo Needs function body. -} - -/** - * Act on a field instance being created. - * - * This hook lets modules react to the creation of a field instance. It is - * called after the definition is saved, so it cannot be used to modify the - * instance itself. - * - * @param $instance - * The instance just created. - */ -function hook_field_create_instance($instance) { - // @todo Needs function body. -} - -/** * Forbid a field update from occurring. * * Any module may forbid any update for any reason. For example, the @@ -1887,67 +1860,6 @@ function hook_field_update_forbid($field, $prior_field, $has_data) { } /** - * Act on a field being updated. - * - * This hook lets modules react to the update of an existing field. It is - * called after the definition is saved, so it cannot be used to modify the - * field itself. - * - * @param $field - * The field as it is post-update. - * @param $prior_field - * The field as it was pre-update. - * @param $has_data - * Whether any data already exists for this field. - */ -function hook_field_update_field($field, $prior_field, $has_data) { - // Reset the static value that keeps track of allowed values for list fields. - drupal_static_reset('list_allowed_values'); -} - -/** - * Act on a field being deleted. - * - * This hook lets modules react to the deletion of an existing field. It is - * called after the definition is deleted. - * - * @param $field - * The field just deleted. - */ -function hook_field_delete_field($field) { - // @todo Needs function body. -} - -/** - * Act on a field instance being updated. - * - * This hook lets modules react to the update of an existing field instance. It - * is called after the definition is saved, so it cannot be used to modify the - * instance itself. - * - * @param $instance - * The instance as it is post-update. - * @param $prior_$instance - * The instance as it was pre-update. - */ -function hook_field_update_instance($instance, $prior_instance) { - // @todo Needs function body. -} - -/** - * Act on a field instance being deleted. - * - * This hook lets modules react to the deletion of an existing field instance. - * It is called after the definition is deleted. - * - * @param $instance - * The instance just deleted. - */ -function hook_field_delete_instance($instance) { - // @todo Needs function body. -} - -/** * Act on field records being read from the database. * * This hook is invoked from field_read_fields() on each field being read. 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 6c2e022..9a7ec5e 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 @@ -196,6 +196,13 @@ class Field extends ConfigEntityBase implements FieldInterface { public $deleted = FALSE; /** + * Whether the field has data. + * + * @var boolean + */ + protected $hasData = FALSE; + + /** * The field schema. * * @var array @@ -210,6 +217,13 @@ class Field extends ConfigEntityBase implements FieldInterface { protected $storageDetails; /** + * The original field. + * + * @var \Drupal\field\Plugin\Core\Entity\Field + */ + public $originalField = NULL; + + /** * Constructs a Field object. * * @param array $values @@ -347,13 +361,11 @@ public function save() { // Invoke the storage backend's hook_field_storage_create_field(). $module_handler->invoke($this->storage['module'], 'field_storage_create_field', array($this)); - - $hook = 'field_create_field'; - $hook_args = array($this); } // Otherwise, the field is being updated. else { $original = $storage_controller->loadUnchanged($this->id()); + $this->originalField = $original; // Some updates are always disallowed. if ($this->type != $original->type) { @@ -372,6 +384,7 @@ public function save() { $this->settings += $original->settings; $has_data = field_has_data($this); + $this->hasData = $has_data; // See if any module forbids the update by throwing an exception. This // invokes hook_field_update_forbid(). @@ -382,20 +395,12 @@ public function save() { // definition update as invalid by raising an exception, which stops // execution before the definition is written to config. $module_handler->invoke($this->storage['module'], 'field_storage_update_field', array($this, $original, $has_data)); - - $hook = 'field_update_field'; - $hook_args = array($this, $original, $has_data); } // Save the configuration. $result = parent::save(); field_cache_clear(); - // Invoke external hooks after the cache is cleared for API consistency. - // This invokes either hook_field_create_field() or - // hook_field_update_field() depending on whether the field is new. - $module_handler->invokeAll($hook, $hook_args); - return $result; } @@ -441,9 +446,6 @@ public function delete() { // Clear the cache. field_cache_clear(); - - // Invoke hook_field_delete_field(). - $module_handler->invokeAll('field_delete_field', array($this)); } } diff --git a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php index 11c185a..de8b94b 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Core/Entity/FieldInstance.php @@ -201,6 +201,13 @@ class FieldInstance extends ConfigEntityBase implements FieldInstanceInterface { protected $bundle_rename_allowed = FALSE; /** + * The original instance. + * + * @var \Drupal\field\Plugin\Core\Entity\FieldInstance + */ + public $originalInstance = NULL; + + /** * Constructs a FieldInstance object. * * @param array $values @@ -332,9 +339,6 @@ public function save() { if ($prior_instance = current($instance_controller->load(array($this->id)))) { throw new FieldException(format_string('Attempt to create an instance of field @field_id on bundle @bundle that already has an instance of that field.', array('@field_id' => $this->field->id, '@bundle' => $this->bundle))); } - - $hook = 'field_create_instance'; - $hook_args = array($this); } // Otherwise, the field instance is being updated. else { @@ -342,6 +346,8 @@ public function save() { ->getStorageController($this->entityType) ->loadUnchanged($this->getOriginalID()); + $this->originalInstance = $original; + // Some updates are always disallowed. if ($this->entity_type != $original->entity_type) { throw new FieldException("Cannot change an existing instance's entity_type."); @@ -352,9 +358,6 @@ public function save() { if ($this->field_uuid != $original->field_uuid) { throw new FieldException("Cannot change an existing instance's field."); } - - $hook = 'field_update_instance'; - $hook_args = array($this, $original); } $field_type_info = field_info_field_types($this->field->type); @@ -366,11 +369,6 @@ public function save() { $result = parent::save(); field_cache_clear(); - // Invoke external hooks after the cache is cleared for API consistency. - // This invokes hook_field_create_instance() or hook_field_update_instance() - // depending on whether the field is new. - $module_handler->invokeAll($hook, $hook_args); - return $result; } @@ -405,10 +403,6 @@ public function delete($field_cleanup = TRUE) { // hook_field_storage_delete_instance(). $module_handler->invoke($this->field->storage['module'], 'field_storage_delete_instance', array($this)); - // Let modules react to the deletion of the instance with - // hook_field_delete_instance(). - $module_handler->invokeAll('field_delete_instance', array($this)); - // Remove the instance from the entity form displays. if ($form_display = entity_load('entity_form_display', $this->entity_type . '.' . $this->bundle . '.default')) { $form_display->removeComponent($this->field->id())->save(); diff --git a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php index 7960f82..5c65f1c 100644 --- a/core/modules/field/lib/Drupal/field/Tests/CrudTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/CrudTest.php @@ -43,8 +43,8 @@ function testCreateField() { field_test_memorize(); $field = field_create_field($field_definition); $mem = field_test_memorize(); - $this->assertIdentical($mem['field_test_field_create_field'][0][0]['field_name'], $field_definition['field_name'], 'hook_field_create_field() called with correct arguments.'); - $this->assertIdentical($mem['field_test_field_create_field'][0][0]['type'], $field_definition['type'], 'hook_field_create_field() called with correct arguments.'); + $this->assertIdentical($mem['field_test_entity_create'][0][0]['field_name'], $field_definition['field_name'], 'hook_entity_create() called with correct arguments.'); + $this->assertIdentical($mem['field_test_entity_create'][0][0]['type'], $field_definition['type'], 'hook_entity_create() called with correct arguments.'); // Read the configuration. Check against raw configuration data rather than // the loaded ConfigEntity, to be sure we check that the defaults are diff --git a/core/modules/field/tests/modules/field_test/field_test.module b/core/modules/field/tests/modules/field_test/field_test.module index c2070f2..3c26caa 100644 --- a/core/modules/field/tests/modules/field_test/field_test.module +++ b/core/modules/field/tests/modules/field_test/field_test.module @@ -153,8 +153,8 @@ function field_test_field_language_alter(&$display_langcode, $context) { * $mem = field_test_memorize(); * * // make sure hook_field_create_field() is invoked correctly - * assertEqual(count($mem['field_test_field_create_field']), 1); - * assertEqual($mem['field_test_field_create_field'][0], array($field)); + * assertEqual(count($mem['field_test_entity_create']), 1); + * assertEqual($mem['field_test_entity_create'][0], array($field)); * @endcode * * @param $key @@ -179,11 +179,13 @@ function field_test_memorize($key = NULL, $value = NULL) { } /** - * Memorize calls to hook_field_create_field(). + * Memorize calls to hook_entity_create() for field creation. */ -function field_test_field_create_field($field) { - $args = func_get_args(); - field_test_memorize(__FUNCTION__, $args); +function field_test_entity_create(EntityInterface $entity) { + if ($entity->entityType() == 'field_entity') { + $args = func_get_args(); + field_test_memorize(__FUNCTION__, $args); + } } /** diff --git a/core/modules/field/tests/modules/field_test/field_test.storage.inc b/core/modules/field/tests/modules/field_test/field_test.storage.inc index d3a7f82..b345733 100644 --- a/core/modules/field/tests/modules/field_test/field_test.storage.inc +++ b/core/modules/field/tests/modules/field_test/field_test.storage.inc @@ -441,14 +441,19 @@ function field_test_entity_bundle_rename($entity_type, $bundle_old, $bundle_new) } /** - * Implements hook_field_delete_instance(). + * Implements hook_entity_delete(). */ -function field_test_field_delete_instance($instance) { +function field_test_entity_delete(EntityInterface $entity) { + + if ($entity->entityType() != 'field_instance') { + return; + } + $data = _field_test_storage_data(); - $field = field_info_field($instance['field_name']); - if ($field['storage']['type'] == 'field_test_storage') { - $field_data = &$data[$field['uuid']]; + $field = $entity->getField(); + if ($field->storage['type'] == 'field_test_storage') { + $field_data = &$data[$field->uuid]; foreach (array('current', 'revisions') as $sub_table) { foreach ($field_data[$sub_table] as &$row) { if ($row->bundle == $instance['bundle']) { diff --git a/core/modules/field_sql_storage/field_sql_storage.module b/core/modules/field_sql_storage/field_sql_storage.module index dcbe476..b8c25d4 100644 --- a/core/modules/field_sql_storage/field_sql_storage.module +++ b/core/modules/field_sql_storage/field_sql_storage.module @@ -251,16 +251,6 @@ function field_sql_storage_field_storage_create_field($field) { } /** - * Implements hook_field_create_field(). - */ -function field_sql_storage_field_create_field($field) { - // Rebuild the schema now that the field has been saved. - if ($field['storage']['type'] == 'field_sql_storage') { - drupal_get_schema(NULL, TRUE); - } -} - -/** * Implements hook_field_update_forbid(). * * Forbids any field update that changes column definitions if there is any diff --git a/core/modules/image/image.module b/core/modules/image/image.module index 47b2e21..1229962 100644 --- a/core/modules/image/image.module +++ b/core/modules/image/image.module @@ -346,124 +346,7 @@ function image_file_predelete(File $file) { image_path_flush($file->uri); } -/** - * Implements hook_field_delete_field(). - */ -function image_field_delete_field($field) { - if ($field['type'] != 'image') { - return; - } - - // The value of a managed_file element can be an array if #extended == TRUE. - $fid = (isset($field['settings']['default_image']['fids']) ? $field['settings']['default_image']['fids'] : $field['settings']['default_image']); - if ($fid && ($file = file_load($fid[0]))) { - file_usage()->delete($file, 'image', 'default_image', $field['id']); - } -} - -/** - * Implements hook_field_update_field(). - */ -function image_field_update_field($field, $prior_field, $has_data) { - if ($field['type'] != 'image') { - return; - } - - // The value of a managed_file element can be an array if #extended == TRUE. - $fid_new = (isset($field['settings']['default_image']['fids']) ? $field['settings']['default_image']['fids'] : $field['settings']['default_image']); - $fid_old = (isset($prior_field['settings']['default_image']['fids']) ? $prior_field['settings']['default_image']['fids'] : $prior_field['settings']['default_image']); - - $file_new = $fid_new ? file_load($fid_new) : FALSE; - - if ($fid_new != $fid_old) { - - // Is there a new file? - if ($file_new) { - $file_new->status = FILE_STATUS_PERMANENT; - $file_new->save(); - file_usage()->add($file_new, 'image', 'default_image', $field['uuid']); - } - - // Is there an old file? - if ($fid_old && ($file_old = file_load($fid_old[0]))) { - file_usage()->delete($file_old, 'image', 'default_image', $field['uuid']); - } - } - - // If the upload destination changed, then move the file. - if ($file_new && (file_uri_scheme($file_new->uri) != $field['settings']['uri_scheme'])) { - $directory = $field['settings']['uri_scheme'] . '://default_images/'; - file_prepare_directory($directory, FILE_CREATE_DIRECTORY); - file_move($file_new, $directory . $file_new->filename); - } -} - -/** - * Implements hook_field_delete_instance(). - */ -function image_field_delete_instance($instance) { - // Only act on image fields. - $field = field_read_field($instance['field_name']); - if ($field['type'] != 'image') { - return; - } - - // The value of a managed_file element can be an array if the #extended - // property is set to TRUE. - $fid = $instance['settings']['default_image']; - if (is_array($fid)) { - $fid = $fid['fid']; - } - // Remove the default image when the instance is deleted. - if ($fid && ($file = file_load($fid))) { - file_usage()->delete($file, 'image', 'default_image', $instance['id']); - } -} - -/** - * Implements hook_field_update_instance(). - */ -function image_field_update_instance($instance, $prior_instance) { - // Only act on image fields. - $field = field_read_field($instance['field_name']); - if ($field['type'] != 'image') { - return; - } - - // The value of a managed_file element can be an array if the #extended - // property is set to TRUE. - $fid_new = $instance['settings']['default_image']; - if (isset($fid_new['fids'])) { - $fid_new = $fid_new['fids']; - } - $fid_old = $prior_instance['settings']['default_image']; - if (isset($fid_old['fids'])) { - $fid_old = $fid_old['fids']; - } - - // If the old and new files do not match, update the default accordingly. - $file_new = $fid_new ? file_load($fid_new[0]) : FALSE; - if ($fid_new != $fid_old) { - // Save the new file, if present. - if ($file_new) { - $file_new->status = FILE_STATUS_PERMANENT; - $file_new->save(); - file_usage()->add($file_new, 'image', 'default_image', $instance['uuid']); - } - // Delete the old file, if present. - if ($fid_old && ($file_old = file_load($fid_old[0]))) { - file_usage()->delete($file_old, 'image', 'default_image', $instance['uuid']); - } - } - - // If the upload destination changed, then move the file. - if ($file_new && (file_uri_scheme($file_new->uri) != $field['settings']['uri_scheme'])) { - $directory = $field['settings']['uri_scheme'] . '://default_images/'; - file_prepare_directory($directory, FILE_CREATE_DIRECTORY); - file_move($file_new, $directory . $file_new->filename); - } -} /** * Clears cached versions of a specific file in all styles. @@ -1081,3 +964,123 @@ function image_entity_presave(EntityInterface $entity, $type) { } } } + +/** + * Implements hook_entity_update(). + */ +function image_entity_update(EntityInterface $entity) { + + if ($entity->entityType() == 'field_entity' && $entity->type == 'image') { + + $field = $entity; + $prior_field = $field->originalField; + + // The value of a managed_file element can be an array if #extended == TRUE. + $fid_new = (isset($field['settings']['default_image']['fids']) ? $field['settings']['default_image']['fids'] : $field['settings']['default_image']); + $fid_old = (isset($prior_field['settings']['default_image']['fids']) ? $prior_field['settings']['default_image']['fids'] : $prior_field['settings']['default_image']); + + $file_new = $fid_new ? file_load($fid_new) : FALSE; + + if ($fid_new != $fid_old) { + + // Is there a new file? + if ($file_new) { + $file_new->status = FILE_STATUS_PERMANENT; + $file_new->save(); + file_usage()->add($file_new, 'image', 'default_image', $field['uuid']); + } + + // Is there an old file? + if ($fid_old && ($file_old = file_load($fid_old[0]))) { + file_usage()->delete($file_old, 'image', 'default_image', $field['uuid']); + } + } + + // If the upload destination changed, then move the file. + if ($file_new && (file_uri_scheme($file_new->uri) != $field['settings']['uri_scheme'])) { + $directory = $field['settings']['uri_scheme'] . '://default_images/'; + file_prepare_directory($directory, FILE_CREATE_DIRECTORY); + file_move($file_new, $directory . $file_new->filename); + } + } + + if ($entity->entityType() == 'field_instance') { + // Only act on image fields. + $field = $entity->getField(); + if ($field['type'] != 'image') { + return; + } + + $instance = $entity; + $prior_instance = $instance->originalInstance; + + // The value of a managed_file element can be an array if the #extended + // property is set to TRUE. + $fid_new = $instance['settings']['default_image']; + if (isset($fid_new['fids'])) { + $fid_new = $fid_new['fids']; + } + $fid_old = $prior_instance['settings']['default_image']; + if (isset($fid_old['fids'])) { + $fid_old = $fid_old['fids']; + } + + // If the old and new files do not match, update the default accordingly. + $file_new = $fid_new ? file_load($fid_new[0]) : FALSE; + if ($fid_new != $fid_old) { + // Save the new file, if present. + if ($file_new) { + $file_new->status = FILE_STATUS_PERMANENT; + $file_new->save(); + file_usage()->add($file_new, 'image', 'default_image', $instance['uuid']); + } + // Delete the old file, if present. + if ($fid_old && ($file_old = file_load($fid_old[0]))) { + file_usage()->delete($file_old, 'image', 'default_image', $instance['uuid']); + } + } + + // If the upload destination changed, then move the file. + if ($file_new && (file_uri_scheme($file_new->uri) != $field['settings']['uri_scheme'])) { + $directory = $field['settings']['uri_scheme'] . '://default_images/'; + file_prepare_directory($directory, FILE_CREATE_DIRECTORY); + file_move($file_new, $directory . $file_new->filename); + } + } + +} + +/** + * Implements hook_entity_delete(). + */ +function image_entity_delete(EntityInterface $entity) { + + if ($entity->entityType() == 'field_entity' && $entity->type == 'image') { + // The value of a managed_file element can be an array if #extended == TRUE. + $fid = (isset($entity['settings']['default_image']['fids']) ? $entity['settings']['default_image']['fids'] : $entity['settings']['default_image']); + if ($fid && ($file = file_load($fid[0]))) { + file_usage()->delete($file, 'image', 'default_image', $entity->uuid); + } + } + + if ($entity->entityType() == 'field_instance') { + // Only act on image fields. + $field = $entity->getField(); + if ($field->type != 'image') { + return; + } + + // The value of a managed_file element can be an array if the #extended + // property is set to TRUE. + $fid = $entity->settings['default_image']; + if (is_array($fid)) { + $fid = $fid['fid']; + } + + // Remove the default image when the instance is deleted. + if ($fid && ($file = file_load($fid))) { + file_usage()->delete($file, 'image', 'default_image', $entity['uuid']); + } + } + +} diff --git a/core/modules/options/options.module b/core/modules/options/options.module index 0d8ec00..fe55122 100644 --- a/core/modules/options/options.module +++ b/core/modules/options/options.module @@ -213,10 +213,12 @@ function options_field_settings_form_value_boolean_allowed_values($element, $inp } /** - * Implements hook_field_update_field(). + * Implements hook_entity_update(). */ -function options_field_update_field($field, $prior_field, $has_data) { - drupal_static_reset('options_allowed_values'); +function options_entity_update(EntityInterface $entity) { + if ($entity->entityType() == 'field_entity') { + drupal_static_reset('options_allowed_values'); + } } /** diff --git a/core/modules/views/views.module b/core/modules/views/views.module index d755506..0541ce2 100644 --- a/core/modules/views/views.module +++ b/core/modules/views/views.module @@ -16,6 +16,7 @@ use Drupal\Component\Plugin\Exception\PluginException; use Drupal\views\Plugin\Core\Entity\View; use Drupal\views\Views; +use Drupal\Core\Entity\EntityInterface; /** * Implements hook_forms(). @@ -645,26 +646,33 @@ function views_language_list($field = 'name', $flags = Language::STATE_ALL) { } /** - * Implements hook_field_create_instance. + * Implements hook_entity_create(). */ -function views_field_create_instance($instance) { - cache('views_info')->deleteAll(); - cache('views_results')->deleteAll(); +function views_entity_create(EntityInterface $entity) { + if ($entity->entityType() == 'field_instance') { + cache('views_info')->deleteAll(); + cache('views_results')->deleteAll(); + } } + /** - * Implements hook_field_update_instance. + * Implements hook_entity_update(). */ -function views_field_update_instance($instance, $prior_instance) { - cache('views_info')->deleteAll(); - cache('views_results')->deleteAll(); +function views_entity_update(EntityInterface $entity) { + if ($entity->entityType() == 'field_instance') { + cache('views_info')->deleteAll(); + cache('views_results')->deleteAll(); + } } /** - * Implements hook_field_delete_instance. + * Implements hook_entity_delete(). */ -function views_field_delete_instance($instance) { - cache('views_info')->deleteAll(); - cache('views_results')->deleteAll(); +function views_entity_delete(EntityInterface $entity) { + if ($entity->entityType() == 'field_instance') { + cache('views_info')->deleteAll(); + cache('views_results')->deleteAll(); + } } /**