Issue #2018731 by swentel: Move field_has_data() to Field::hasData().
parent
cf8f023c02
commit
30f6062a18
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\field\FieldUpdateForbiddenException.
|
||||
* Contains \Drupal\field\FieldUpdateForbiddenException.
|
||||
*/
|
||||
|
||||
namespace Drupal\field;
|
||||
|
|
|
|||
|
|
@ -420,17 +420,15 @@ class Field extends ConfigEntityBase implements FieldInterface {
|
|||
// objects.
|
||||
$this->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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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'] = '<div class="messages messages--error">' . t('There is data for this field in the database. The field settings can no longer be changed.') . '</div>' . $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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in New Issue