diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module index 6ddcb4d8f5e4..88e6a7754f5e 100644 --- a/core/modules/datetime/datetime.module +++ b/core/modules/datetime/datetime.module @@ -115,7 +115,7 @@ function datetime_field_info() { /** * Implements hook_field_settings_form(). */ -function datetime_field_settings_form($field, $instance, $has_data) { +function datetime_field_settings_form($field, $instance) { $settings = $field['settings']; $form['datetime_type'] = array( diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module index 0d0c9680241c..cd302e92227e 100644 --- a/core/modules/entity_reference/entity_reference.module +++ b/core/modules/entity_reference/entity_reference.module @@ -143,7 +143,7 @@ function entity_reference_field_validate(EntityInterface $entity = NULL, $field, /** * Implements hook_field_settings_form(). */ -function entity_reference_field_settings_form($field, $instance, $has_data) { +function entity_reference_field_settings_form($field, $instance) { // Select the target entity type. $entity_type_options = array(); foreach (entity_get_info() as $entity_type => $entity_info) { @@ -161,7 +161,7 @@ function entity_reference_field_settings_form($field, $instance, $has_data) { '#options' => $entity_type_options, '#default_value' => $field['settings']['target_type'], '#required' => TRUE, - '#disabled' => $has_data, + '#disabled' => $field->hasData(), '#size' => 1, ); @@ -173,7 +173,7 @@ function entity_reference_field_settings_form($field, $instance, $has_data) { * * Reset the instance handler settings, when the target type is changed. */ -function entity_reference_field_update_field($field, $prior_field, $has_data) { +function entity_reference_field_update_field($field, $prior_field) { if ($field['type'] != 'entity_reference') { // Not an entity reference field. return; diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php index 259c4054b896..820afeffcc58 100644 --- a/core/modules/field/field.api.php +++ b/core/modules/field/field.api.php @@ -541,11 +541,9 @@ function hook_field_update(\Drupal\Core\Entity\EntityInterface $entity, $field, * The updated field structure to be saved. * @param $prior_field * The previously-saved field structure. - * @param $has_data - * TRUE if the field has data in storage currently. */ -function hook_field_storage_update_field($field, $prior_field, $has_data) { - if (!$has_data) { +function hook_field_storage_update_field($field, $prior_field) { + if (!$field->hasData()) { // There is no data. Re-create the tables completely. $prior_schema = _field_sql_storage_schema($prior_field); foreach ($prior_schema as $name => $table) { @@ -1853,15 +1851,13 @@ function hook_field_create_instance($instance) { * The field as it will be post-update. * @param $prior_field * The field as it is pre-update. - * @param $has_data - * Whether any data already exists for this field. */ -function hook_field_update_forbid($field, $prior_field, $has_data) { +function hook_field_update_forbid($field, $prior_field) { // A 'list' field stores integer keys mapped to display values. If // the new field will have fewer values, and any data exists for the // abandoned keys, the field will have no way to display them. So, // forbid such an update. - if ($has_data && count($field['settings']['allowed_values']) < count($prior_field['settings']['allowed_values'])) { + if ($field->hasData() && count($field['settings']['allowed_values']) < count($prior_field['settings']['allowed_values'])) { // Identify the keys that will be lost. $lost_keys = array_diff(array_keys($field['settings']['allowed_values']), array_keys($prior_field['settings']['allowed_values'])); // If any data exist for those keys, forbid the update. @@ -1887,10 +1883,8 @@ function hook_field_update_forbid($field, $prior_field, $has_data) { * 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) { +function hook_field_update_field($field, $prior_field) { // Reset the static value that keeps track of allowed values for list fields. drupal_static_reset('list_allowed_values'); } diff --git a/core/modules/field/field.module b/core/modules/field/field.module index 7ff93f33305c..299ada6dca49 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -885,43 +885,6 @@ function field_get_items(EntityInterface $entity, $field_name, $langcode = NULL) return isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array(); } -/** - * Determines whether a field has any data. - * - * @param $field - * A field structure. - * - * @return - * TRUE if the field has data for any entity; FALSE otherwise. - */ -function field_has_data($field) { - $columns = array_keys($field['columns']); - $factory = Drupal::service('entity.query'); - foreach ($field['bundles'] as $entity_type => $bundle) { - // Entity Query throws an exception if there is no base table. - $entity_info = entity_get_info($entity_type); - if (!isset($entity_info['base_table'])) { - continue; - } - $query = $factory->get($entity_type); - $group = $query->orConditionGroup(); - foreach ($columns as $column) { - $group->exists($field['field_name'] . '.' . $column); - } - $result = $query - ->condition($group) - ->count() - ->accessCheck(FALSE) - ->range(0, 1) - ->execute(); - if ($result) { - return TRUE; - } - } - - return FALSE; -} - /** * Determines whether the user has access to a given field. * diff --git a/core/modules/field/lib/Drupal/field/FieldUpdateForbiddenException.php b/core/modules/field/lib/Drupal/field/FieldUpdateForbiddenException.php index 6bf914f17b96..a63132a3a348 100644 --- a/core/modules/field/lib/Drupal/field/FieldUpdateForbiddenException.php +++ b/core/modules/field/lib/Drupal/field/FieldUpdateForbiddenException.php @@ -1,8 +1,8 @@ settings += $original->settings; - $has_data = field_has_data($this); - // See if any module forbids the update by throwing an exception. This // invokes hook_field_update_forbid(). - $module_handler->invokeAll('field_update_forbid', array($this, $original, $has_data)); + $module_handler->invokeAll('field_update_forbid', array($this, $original)); // Tell the storage engine to update the field by invoking the // hook_field_storage_update_field(). The storage engine can reject the // 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)); + $module_handler->invoke($this->storage['module'], 'field_storage_update_field', array($this, $original)); // Save the configuration. $result = parent::save(); @@ -438,7 +436,7 @@ class Field extends ConfigEntityBase implements FieldInterface { // Invoke hook_field_update_field() after the cache is cleared for API // consistency. - $module_handler->invokeAll('field_update_field', array($this, $original, $has_data)); + $module_handler->invokeAll('field_update_field', array($this, $original)); return $result; } @@ -724,4 +722,38 @@ class Field extends ConfigEntityBase implements FieldInterface { return array('deleted'); } + /** + * Determines whether a field has any data. + * + * @return + * TRUE if the field has data for any entity; FALSE otherwise. + */ + public function hasData() { + $storage_details = $this->getSchema(); + $columns = array_keys($storage_details['columns']); + $factory = \Drupal::service('entity.query'); + foreach ($this->getBundles() as $entity_type => $bundle) { + // Entity Query throws an exception if there is no base table. + $entity_info = \Drupal::entityManager()->getDefinition($entity_type); + if (!isset($entity_info['base_table'])) { + continue; + } + $query = $factory->get($entity_type); + $group = $query->orConditionGroup(); + foreach ($columns as $column) { + $group->exists($this->id() . '.' . $column); + } + $result = $query + ->condition($group) + ->count() + ->accessCheck(FALSE) + ->range(0, 1) + ->execute(); + if ($result) { + return TRUE; + } + } + + return FALSE; + } } diff --git a/core/modules/field/tests/modules/field_test/field_test.field.inc b/core/modules/field/tests/modules/field_test/field_test.field.inc index 23ae814f0c02..0ff40e797425 100644 --- a/core/modules/field/tests/modules/field_test/field_test.field.inc +++ b/core/modules/field/tests/modules/field_test/field_test.field.inc @@ -64,7 +64,7 @@ function field_test_field_widget_info_alter(&$info) { /** * Implements hook_field_update_forbid(). */ -function field_test_field_update_forbid($field, $prior_field, $has_data) { +function field_test_field_update_forbid($field, $prior_field) { if ($field['type'] == 'test_field' && $field['settings']['unchangeable'] != $prior_field['settings']['unchangeable']) { throw new FieldException("field_test 'unchangeable' setting cannot be changed'"); } @@ -145,7 +145,7 @@ function field_test_field_is_empty($item, $field_type) { /** * Implements hook_field_settings_form(). */ -function field_test_field_settings_form($field, $instance, $has_data) { +function field_test_field_settings_form($field, $instance) { $settings = $field['settings']; $form['test_field_setting'] = array( diff --git a/core/modules/field_sql_storage/field_sql_storage.module b/core/modules/field_sql_storage/field_sql_storage.module index dcbe476fdd01..3ccac54afe72 100644 --- a/core/modules/field_sql_storage/field_sql_storage.module +++ b/core/modules/field_sql_storage/field_sql_storage.module @@ -266,8 +266,8 @@ function field_sql_storage_field_create_field($field) { * Forbids any field update that changes column definitions if there is any * data. */ -function field_sql_storage_field_update_forbid($field, $prior_field, $has_data) { - if ($has_data && $field['columns'] != $prior_field['columns']) { +function field_sql_storage_field_update_forbid($field, $prior_field) { + if ($field->hasData() && $field['columns'] != $prior_field['columns']) { throw new FieldUpdateForbiddenException("field_sql_storage cannot change the schema for an existing field with data."); } } @@ -275,8 +275,8 @@ function field_sql_storage_field_update_forbid($field, $prior_field, $has_data) /** * Implements hook_field_storage_update_field(). */ -function field_sql_storage_field_storage_update_field($field, $prior_field, $has_data) { - if (! $has_data) { +function field_sql_storage_field_storage_update_field($field, $prior_field) { + if (!$field->hasData()) { // There is no data. Re-create the tables completely. if (Database::getConnection()->supportsTransactionalDDL()) { diff --git a/core/modules/field_ui/field_ui.api.php b/core/modules/field_ui/field_ui.api.php index 81a5f3bffd97..b3bf03ee1713 100644 --- a/core/modules/field_ui/field_ui.api.php +++ b/core/modules/field_ui/field_ui.api.php @@ -29,13 +29,11 @@ * The field structure being configured. * @param $instance * The instance structure being configured. - * @param $has_data - * TRUE if the field already has data, FALSE if not. * * @return * The form definition for the field settings. */ -function hook_field_settings_form($field, $instance, $has_data) { +function hook_field_settings_form($field, $instance) { $settings = $field['settings']; $form['max_length'] = array( '#type' => 'number', diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php index 556a73da018b..c2f0a45d84e9 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldEditForm.php @@ -82,8 +82,7 @@ class FieldEditForm implements FormInterface, ControllerInterface { // See if data already exists for this field. // If so, prevent changes to the field settings. - $has_data = field_has_data($field); - if ($has_data) { + if ($field->hasData()) { $form['field']['#prefix'] = '
' . $form['field']['#prefix']; } @@ -135,7 +134,7 @@ class FieldEditForm implements FormInterface, ControllerInterface { $form['field']['settings'] = array( '#weight' => 10, ); - $additions = \Drupal::moduleHandler()->invoke($field['module'], 'field_settings_form', array($field, $this->instance, $has_data)); + $additions = \Drupal::moduleHandler()->invoke($field['module'], 'field_settings_form', array($field, $this->instance)); if (is_array($additions)) { $form['field']['settings'] += $additions; } diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc index 5d28cdbe76b1..9a327c9cd548 100644 --- a/core/modules/file/file.field.inc +++ b/core/modules/file/file.field.inc @@ -37,7 +37,7 @@ function file_field_info() { /** * Implements hook_field_settings_form(). */ -function file_field_settings_form($field, $instance, $has_data) { +function file_field_settings_form($field, $instance) { $defaults = field_info_field_settings($field['type']); $settings = array_merge($defaults, $field['settings']); @@ -71,7 +71,7 @@ function file_field_settings_form($field, $instance, $has_data) { '#options' => $scheme_options, '#default_value' => $settings['uri_scheme'], '#description' => t('Select where the final files should be stored. Private file storage has significantly more overhead than public files, but allows restricted access to files within this field.'), - '#disabled' => $has_data, + '#disabled' => $field->hasData(), ); return $form; diff --git a/core/modules/image/image.module b/core/modules/image/image.module index e8dc3d4e3355..bdcb5e9f9ac1 100644 --- a/core/modules/image/image.module +++ b/core/modules/image/image.module @@ -364,7 +364,7 @@ function image_field_delete_field($field) { /** * Implements hook_field_update_field(). */ -function image_field_update_field($field, $prior_field, $has_data) { +function image_field_update_field($field, $prior_field) { if ($field['type'] != 'image') { return; } diff --git a/core/modules/number/number.module b/core/modules/number/number.module index 7610639589e9..1504e4a746e0 100644 --- a/core/modules/number/number.module +++ b/core/modules/number/number.module @@ -56,7 +56,7 @@ function number_field_info() { /** * Implements hook_field_settings_form(). */ -function number_field_settings_form($field, $instance, $has_data) { +function number_field_settings_form($field, $instance) { $settings = $field['settings']; $form = array(); @@ -67,7 +67,7 @@ function number_field_settings_form($field, $instance, $has_data) { '#options' => drupal_map_assoc(range(10, 32)), '#default_value' => $settings['precision'], '#description' => t('The total number of digits to store in the database, including those to the right of the decimal.'), - '#disabled' => $has_data, + '#disabled' => $field->hasData(), ); $form['scale'] = array( '#type' => 'select', @@ -75,7 +75,7 @@ function number_field_settings_form($field, $instance, $has_data) { '#options' => drupal_map_assoc(range(0, 10)), '#default_value' => $settings['scale'], '#description' => t('The number of digits to the right of the decimal.'), - '#disabled' => $has_data, + '#disabled' => $field->hasData(), ); } diff --git a/core/modules/options/options.module b/core/modules/options/options.module index b2230bc1f5c5..88a2b486b748 100644 --- a/core/modules/options/options.module +++ b/core/modules/options/options.module @@ -68,7 +68,7 @@ function options_field_info() { /** * Implements hook_field_settings_form(). */ -function options_field_settings_form($field, $instance, $has_data) { +function options_field_settings_form($field, $instance) { $settings = $field['settings']; switch ($field['type']) { @@ -81,7 +81,7 @@ function options_field_settings_form($field, $instance, $has_data) { '#default_value' => options_allowed_values_string($settings['allowed_values']), '#rows' => 10, '#element_validate' => array('options_field_settings_form_validate_allowed_values'), - '#field_has_data' => $has_data, + '#field_has_data' => $field->hasData(), '#field' => $field, '#field_type' => $field['type'], '#access' => empty($settings['allowed_values_function']), @@ -217,7 +217,7 @@ function options_field_settings_form_value_boolean_allowed_values($element, $inp /** * Implements hook_field_update_field(). */ -function options_field_update_field($field, $prior_field, $has_data) { +function options_field_update_field($field, $prior_field) { drupal_static_reset('options_allowed_values'); } @@ -368,8 +368,8 @@ function options_allowed_values_string($values) { /** * Implements hook_field_update_forbid(). */ -function options_field_update_forbid($field, $prior_field, $has_data) { - if ($field['module'] == 'options' && $has_data) { +function options_field_update_forbid($field, $prior_field) { + if ($field['module'] == 'options' && $field->hasData()) { // Forbid any update that removes allowed values with actual data. $lost_keys = array_diff(array_keys($prior_field['settings']['allowed_values']), array_keys($field['settings']['allowed_values'])); if (_options_values_in_use($field, $lost_keys)) { diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index a38bbc9f44ae..980ad002cd60 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -1053,7 +1053,7 @@ function taxonomy_autocomplete_validate($element, &$form_state) { /** * Implements hook_field_settings_form(). */ -function taxonomy_field_settings_form($field, $instance, $has_data) { +function taxonomy_field_settings_form($field, $instance) { // Get proper values for 'allowed_values_function', which is a core setting. $vocabularies = taxonomy_vocabulary_load_multiple(); $options = array(); @@ -1072,7 +1072,7 @@ function taxonomy_field_settings_form($field, $instance, $has_data) { '#options' => $options, '#required' => TRUE, '#description' => t('The vocabulary which supplies the options for this field.'), - '#disabled' => $has_data, + '#disabled' => $field->hasData(), ); $form['allowed_values'][$delta]['parent'] = array( '#type' => 'value', diff --git a/core/modules/text/text.module b/core/modules/text/text.module index 386945854921..4bc0f30edcd2 100644 --- a/core/modules/text/text.module +++ b/core/modules/text/text.module @@ -84,7 +84,7 @@ function text_field_info() { /** * Implements hook_field_settings_form(). */ -function text_field_settings_form($field, $instance, $has_data) { +function text_field_settings_form($field, $instance) { $settings = $field['settings']; $form = array(); @@ -99,7 +99,7 @@ function text_field_settings_form($field, $instance, $has_data) { '#min' => 1, // @todo: If $has_data, add a validate handler that only allows // max_length to increase. - '#disabled' => $has_data, + '#disabled' => $field->hasData(), ); } diff --git a/core/modules/translation_entity/translation_entity.admin.inc b/core/modules/translation_entity/translation_entity.admin.inc index 6a4c0da30647..d8cf6859a29b 100644 --- a/core/modules/translation_entity/translation_entity.admin.inc +++ b/core/modules/translation_entity/translation_entity.admin.inc @@ -346,7 +346,7 @@ function _translation_entity_update_field_translatability($settings) { $field_operations = array( array('translation_entity_translatable_switch', array($translatable, $field_name)), ); - if (field_has_data($field)) { + if ($field->hasData()) { $field_operations[] = array('translation_entity_translatable_batch', array($translatable, $field_name)); $field_operations = $translatable ? $field_operations : array_reverse($field_operations); } diff --git a/core/modules/translation_entity/translation_entity.module b/core/modules/translation_entity/translation_entity.module index 6f6c7405c689..9f78d890d527 100644 --- a/core/modules/translation_entity/translation_entity.module +++ b/core/modules/translation_entity/translation_entity.module @@ -810,7 +810,7 @@ function translation_entity_form_field_ui_field_edit_form_alter(array &$form, ar $translatable = $field['translatable']; $label = t('Field translation'); - if (field_has_data($field)) { + if ($field->hasData()) { $form['field']['translatable'] = array( '#type' => 'item', '#title' => $label,