/** * Forbid a field storage update from occurring. * * Any module may forbid any update for any reason. For example, the * field's storage module might forbid an update if it would change * the storage schema while data for the field exists. A field type * module might forbid an update if it would change existing data's * semantics, or if there are external dependencies on field settings * that cannot be updated. * * To forbid the update from occurring, throw a * \Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException. * * @param \Drupal\field\FieldStorageConfigInterface $field_storage * The field storage as it will be post-update. * @param \Drupal\field\FieldStorageConfigInterface $prior_field_storage * The field storage as it is pre-update. * * @see entity_crud */ function hook_field_storage_config_update_forbid(\Drupal\field\FieldStorageConfigInterface $field_storage, \Drupal\field\FieldStorageConfigInterface $prior_field_storage) { if ($field_storage->module == 'options' && $field_storage->hasData()) { // Forbid any update that removes allowed values with actual data. $allowed_values = $field_storage->getSetting('allowed_values'); $prior_allowed_values = $prior_field_storage->getSetting('allowed_values'); $lost_keys = array_keys(array_diff_key($prior_allowed_values, $allowed_values)); if (_options_values_in_use($field_storage->getTargetEntityTypeId(), $field_storage->getName(), $lost_keys)) { throw new \Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException(t('A list field (@field_name) with existing data cannot have its keys changed.', array('@field_name' => $field_storage->getName()))); } } }
/** * #element_validate callback for options field allowed values. * * @param $element * An associative array containing the properties and children of the * generic form element. * @param $form_state * The current state of the form for the form this element belongs to. * * @see form_process_pattern() */ public static function validateAllowedValues($element, FormStateInterface $form_state) { $values = static::extractAllowedValues($element['#value'], $element['#field_has_data']); if (!is_array($values)) { $form_state->setError($element, t('Allowed values list: invalid input.')); } else { // Check that keys are valid for the field type. foreach ($values as $key => $value) { if ($error = static::validateAllowedValue($key)) { $form_state->setError($element, $error); break; } } // Prevent removing values currently in use. if ($element['#field_has_data']) { $lost_keys = array_diff(array_keys($element['#allowed_values']), array_keys($values)); if (_options_values_in_use($element['#entity_type'], $element['#field_name'], $lost_keys)) { $form_state->setError($element, t('Allowed values list: some values are being removed while currently in use.')); } } $form_state->setValueForElement($element, $values); } }