drupal/core/modules/options/options.module

127 lines
4.2 KiB
Plaintext

<?php
/**
* @file
* Defines selection, check box and radio button widgets for text and numeric fields.
*/
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\field\FieldInterface;
use Drupal\field\FieldUpdateForbiddenException;
/**
* Implements hook_help().
*/
function options_help($path, $arg) {
switch ($path) {
case 'admin/help#options':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Options module defines various fields for storing a list of items, for use with the Field module. Usually these items are entered through a select list, checkboxes, or radio buttons. See the <a href="@field-help">Field module help page</a> for more information about fields.', array('@field-help' => url('admin/help/field'))) . '</p>';
return $output;
}
}
/**
* Form element #value_callback: assembles the allowed values for 'boolean' fields.
*/
function options_field_settings_form_value_boolean_allowed_values($element, $input, $form_state) {
$on = NestedArray::getValue($form_state['input'], $element['#on_parents']);
$off = NestedArray::getValue($form_state['input'], $element['#off_parents']);
return array($off, $on);
}
/**
* Implements hook_ENTITY_TYPE_update() for 'field_entity'.
*/
function options_field_entity_update(FieldInterface $field) {
drupal_static_reset('options_allowed_values');
}
/**
* Implements hook_ENTITY_TYPE_delete() for 'field_entity'.
*/
function options_field_entity_delete(FieldInterface $field) {
drupal_static_reset('options_allowed_values');
}
/**
* Returns the array of allowed values for a list field.
*
* The strings are not safe for output. Keys and values of the array should be
* sanitized through field_filter_xss() before being displayed.
*
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The field definition.
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity object.
*
* @return
* The array of allowed values. Keys of the array are the raw stored values
* (number or text), values of the array are the display labels.
*/
function options_allowed_values(FieldDefinitionInterface $field_definition, EntityInterface $entity) {
$allowed_values = &drupal_static(__FUNCTION__, array());
$cache_id = implode(':', array($entity->entityType(), $entity->bundle(), $field_definition->getName()));
if (!isset($allowed_values[$cache_id])) {
$function = $field_definition->getSetting('allowed_values_function');
// If $cacheable is FALSE, then the allowed values are not statically
// cached. See options_test_dynamic_values_callback() for an example of
// generating dynamic and uncached values.
$cacheable = TRUE;
if (!empty($function)) {
$values = $function($field_definition, $entity, $cacheable);
}
else {
$values = $field_definition->getSetting('allowed_values');
}
if ($cacheable) {
$allowed_values[$cache_id] = $values;
}
else {
return $values;
}
}
return $allowed_values[$cache_id];
}
/**
* Implements hook_field_update_forbid().
*/
function options_field_update_forbid($field, $prior_field) {
if ($field->module == 'options' && $field->hasData()) {
// Forbid any update that removes allowed values with actual data.
$allowed_values = $field->getSetting('allowed_values');
$prior_allowed_values = $prior_field->getSetting('allowed_values');
$lost_keys = array_diff(array_keys($prior_allowed_values), array_keys($allowed_values));
if (_options_values_in_use($field->entity_type, $field->getName(), $lost_keys)) {
throw new FieldUpdateForbiddenException(t('A list field (@field_name) with existing data cannot have its keys changed.', array('@field_name' => $field->getName())));
}
}
}
/**
* Checks if a list of values are being used in actual field values.
*/
function _options_values_in_use($entity_type, $field_name, $values) {
if ($values) {
$factory = \Drupal::service('entity.query');
$result = $factory->get($entity_type)
->condition($field_name . '.value', $values)
->count()
->accessCheck(FALSE)
->range(0, 1)
->execute();
if ($result) {
return TRUE;
}
}
return FALSE;
}