diff --git a/core/lib/Drupal/Core/Entity/Field/FieldDefinitionInterface.php b/core/lib/Drupal/Core/Entity/Field/FieldDefinitionInterface.php new file mode 100644 index 0000000..56e23ff --- /dev/null +++ b/core/lib/Drupal/Core/Entity/Field/FieldDefinitionInterface.php @@ -0,0 +1,26 @@ +setTimeZone(timezone_open(drupal_get_user_timezone())); - if ($this->field['settings']['datetime_type'] == 'date') { + if ($this->getFieldSetting('datetime_type') == 'date') { // A date without time will pick up the current time, use the default. datetime_date_default_time($date); } diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimePlainFormatter.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimePlainFormatter.php index 45a85a2..e385c69 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimePlainFormatter.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimePlainFormatter.php @@ -28,7 +28,7 @@ class DateTimePlainFormatter extends FormatterBase { /** - * Implements Drupal\field\Plugin\Type\Formatter\FormatterInterface::viewElements(). + * {@inheritdoc} */ public function viewElements(EntityInterface $entity, $langcode, array $items) { @@ -43,7 +43,7 @@ public function viewElements(EntityInterface $entity, $langcode, array $items) { $date = $item['date']; $date->setTimeZone(timezone_open(drupal_get_user_timezone())); $format = DATETIME_DATETIME_STORAGE_FORMAT; - if ($this->field['settings']['datetime_type'] == 'date') { + if ($this->getFieldSetting('datetime_type') == 'date') { // A date without time will pick up the current time, use the default. datetime_date_default_time($date); $format = DATETIME_DATE_STORAGE_FORMAT; diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php index f0d60fe..610f6fd 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDatelistWidget.php @@ -11,8 +11,9 @@ use Drupal\field\Plugin\Type\Widget\WidgetBase; use Drupal\Component\Plugin\Discovery\DiscoveryInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; use Drupal\field\Plugin\PluginSettingsBase; -use Drupal\field\Plugin\Core\Entity\FieldInstance; +use Drupal\field\FieldInstanceInterface; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\datetime\DateHelper; @@ -38,10 +39,14 @@ class DateTimeDatelistWidget extends WidgetBase { /** * {@inheritdoc} */ - public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) { + public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) { // Identify the function used to set the default value. - $instance['default_value_function'] = $this->defaultValueFunction(); - parent::__construct($plugin_id, $plugin_definition, $instance, $settings); + // @todo Make this work for both configurable and nonconfigurable fields: + // https://drupal.org/node/1989468. + if ($field_definition instanceof FieldInstanceInterface) { + $field_definition->default_value_function = $this->defaultValueFunction(); + } + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings); } /** @@ -55,13 +60,9 @@ public function defaultValueFunction() { } /** - * Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement(). + * {@inheritdoc} */ public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { - - $field = $this->field; - $instance = $this->instance; - $date_order = $this->getSetting('date_order'); $time_type = $this->getSetting('time_type'); $increment = $this->getSetting('increment'); @@ -78,7 +79,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr $element['#element_validate'][] = 'datetime_datelist_widget_validate'; // Identify the type of date and time elements to use. - switch ($field['settings']['datetime_type']) { + switch ($this->getFieldSetting('datetime_type')) { case 'date': $storage_format = DATETIME_DATE_STORAGE_FORMAT; $type_type = 'none'; @@ -126,7 +127,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr ); // Set the storage and widget options so the validation can use them. The - // validator will not have access to field or instance settings. + // validator will not have access to the field definition. $element['value']['#date_storage_format'] = $storage_format; if (!empty($items[$delta]['date'])) { @@ -134,7 +135,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr // The date was created and verified during field_load(), so it is safe to // use without further inspection. $date->setTimezone( new \DateTimeZone($element['value']['#date_timezone'])); - if ($field['settings']['datetime_type'] == 'date') { + if ($this->getFieldSetting('datetime_type') == 'date') { // A date without time will pick up the current time, use the default // time. datetime_date_default_time($date); @@ -145,22 +146,11 @@ public function formElement(array $items, $delta, array $element, $langcode, arr } /** - * - * - * @param array $form - * The form definition as an array. - * @param array $form_state - * The current state of the form as an array. - * - * @return array - * + * {@inheritdoc} */ function settingsForm(array $form, array &$form_state) { $element = parent::settingsForm($form, $form_state); - $field = $this->field; - $instance = $this->instance; - $element['date_order'] = array( '#type' => 'select', '#title' => t('Date part order'), @@ -168,7 +158,7 @@ function settingsForm(array $form, array &$form_state) { '#options' => array('MDY' => t('Month/Day/Year'), 'DMY' => t('Day/Month/Year'), 'YMD' => t('Year/Month/Day')), ); - if ($field['settings']['datetime_type'] == 'datetime') { + if ($this->getFieldSetting('datetime_type') == 'datetime') { $element['time_type'] = array( '#type' => 'select', '#title' => t('Time type'), diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php index f0c45c0..79f12bc 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php @@ -11,8 +11,9 @@ use Drupal\field\Plugin\Type\Widget\WidgetBase; use Drupal\Component\Plugin\Discovery\DiscoveryInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; use Drupal\field\Plugin\PluginSettingsBase; -use Drupal\field\Plugin\Core\Entity\FieldInstance; +use Drupal\field\FieldInstanceInterface; use Drupal\Core\Datetime\DrupalDateTime; /** @@ -32,10 +33,14 @@ class DateTimeDefaultWidget extends WidgetBase { /** * {@inheritdoc} */ - public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) { + public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) { // Identify the function used to set the default value. - $instance['default_value_function'] = $this->defaultValueFunction(); - parent::__construct($plugin_id, $plugin_definition, $instance, $settings); + // @todo Make this work for both configurable and nonconfigurable fields: + // https://drupal.org/node/1989468. + if ($field_definition instanceof FieldInstanceInterface) { + $field_definition->default_value_function = $this->defaultValueFunction(); + } + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings); } /** @@ -49,13 +54,9 @@ public function defaultValueFunction() { } /** - * Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement(). - * + * {@inheritdoc} */ public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { - - $field = $this->field; - $instance = $this->instance; $format_type = datetime_default_format_type(); // We are nesting some sub-elements inside the parent, so we need a wrapper. @@ -69,7 +70,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr $element['#element_validate'][] = 'datetime_datetime_widget_validate'; // Identify the type of date and time elements to use. - switch ($field['settings']['datetime_type']) { + switch ($this->getFieldSetting('datetime_type')) { case 'date': $date_type = 'date'; $time_type = 'none'; @@ -104,7 +105,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr ); // Set the storage and widget options so the validation can use them. The - // validator will not have access to field or instance settings. + // validator will not have access to the field definition. $element['value']['#date_element_format'] = $element_format; $element['value']['#date_storage_format'] = $storage_format; @@ -113,7 +114,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr // The date was created and verified during field_load(), so it is safe to // use without further inspection. $date->setTimezone(new \DateTimeZone($element['value']['#date_timezone'])); - if ($field['settings']['datetime_type'] == 'date') { + if ($this->getFieldSetting('datetime_type') == 'date') { // A date without time will pick up the current time, use the default // time. datetime_date_default_time($date); diff --git a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php b/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php index f7f0c06..e139d0e 100644 --- a/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php +++ b/core/modules/edit/lib/Drupal/edit/Access/EditEntityFieldAccessCheck.php @@ -41,7 +41,7 @@ public function access(Route $route, Request $request) { * Implements EntityFieldAccessCheckInterface::accessEditEntityField(). */ public function accessEditEntityField(EntityInterface $entity, $field_name) { - return $entity->access('update') && field_access('edit', $field_name, $entity->entityType(), $entity); + return $entity->access('update') && ($field = field_info_field($field_name)) && field_access('edit', $field, $entity->entityType(), $entity); } /** diff --git a/core/modules/email/email.module b/core/modules/email/email.module index 73e427e..28b9b21 100644 --- a/core/modules/email/email.module +++ b/core/modules/email/email.module @@ -45,7 +45,7 @@ function email_field_info_alter(&$info) { /** * Implements hook_field_is_empty(). */ -function email_field_is_empty($item, $field) { +function email_field_is_empty($item, $field_type) { return !isset($item['value']) || $item['value'] === ''; } diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php index 6f4f20e..f8c3f5b 100644 --- a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php +++ b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityDisplay.php @@ -54,7 +54,7 @@ public function getFormatter($field_name) { if ($configuration = $this->getComponent($field_name)) { $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle); $formatter = $this->pluginManager->getInstance(array( - 'instance' => $instance, + 'field_definition' => $instance, 'view_mode' => $this->originalMode, // No need to prepare, defaults have been merged in setComponent(). 'prepare' => FALSE, diff --git a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php index 9f6425b..8c72986 100644 --- a/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php +++ b/core/modules/entity/lib/Drupal/entity/Plugin/Core/Entity/EntityFormDisplay.php @@ -54,7 +54,7 @@ public function getWidget($field_name) { if ($configuration = $this->getComponent($field_name)) { $instance = field_info_instance($this->targetEntityType, $field_name, $this->bundle); $widget = $this->pluginManager->getInstance(array( - 'instance' => $instance, + 'field_definition' => $instance, 'form_mode' => $this->originalMode, // No need to prepare, defaults have been merged in setComponent(). 'prepare' => FALSE, diff --git a/core/modules/entity_reference/entity_reference.module b/core/modules/entity_reference/entity_reference.module index 97e9db0..3841a70 100644 --- a/core/modules/entity_reference/entity_reference.module +++ b/core/modules/entity_reference/entity_reference.module @@ -8,6 +8,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Database\Query\AlterableInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; /** * Implements hook_field_info(). @@ -80,10 +81,9 @@ function entity_reference_field_widget_info_alter(&$info) { * * @return \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface */ -function entity_reference_get_selection_handler($field, $instance, EntityInterface $entity = NULL) { +function entity_reference_get_selection_handler(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) { $options = array( - 'field' => $field, - 'instance' => $instance, + 'field_definition' => $field_definition, 'entity' => $entity, ); return Drupal::service('plugin.manager.entity_reference.selection')->getInstance($options); @@ -92,7 +92,7 @@ function entity_reference_get_selection_handler($field, $instance, EntityInterfa /** * Implements hook_field_is_empty(). */ -function entity_reference_field_is_empty($item, $field) { +function entity_reference_field_is_empty($item, $field_type) { if (!empty($item['target_id']) && $item['target_id'] == 'auto_create') { // Allow auto-create entities. return FALSE; @@ -149,7 +149,7 @@ function entity_reference_field_validate(EntityInterface $entity = NULL, $field, } if ($ids) { - $valid_ids = entity_reference_get_selection_handler($field, $instance, $entity)->validateReferencableEntities(array_keys($ids)); + $valid_ids = entity_reference_get_selection_handler($instance, $entity)->validateReferencableEntities(array_keys($ids)); $invalid_entities = array_diff_key($ids, array_flip($valid_ids)); if ($invalid_entities) { @@ -290,7 +290,7 @@ function entity_reference_field_instance_settings_form($field, $instance, $form_ '#attributes' => array('class' => array('entity_reference-settings')), ); - $handler = entity_reference_get_selection_handler($field, $instance); + $handler = entity_reference_get_selection_handler($instance); $form['handler']['handler_settings'] += $handler->settingsForm($field, $instance); return $form; @@ -386,13 +386,13 @@ function entity_reference_settings_ajax_submit($form, &$form_state) { /** * Implements hook_options_list(). */ -function entity_reference_options_list($field, $instance, $entity_type = NULL, $entity = NULL) { - if (!$options = entity_reference_get_selection_handler($field, $instance, $entity)->getReferencableEntities()) { +function entity_reference_options_list(FieldDefinitionInterface $field_definition, EntityInterface $entity) { + if (!$options = entity_reference_get_selection_handler($field_definition, $entity)->getReferencableEntities()) { return array(); } // Rebuild the array by changing the bundle key into the bundle label. - $target_type = $field['settings']['target_type']; + $target_type = $field_definition->getFieldSetting('target_type'); $bundles = entity_get_bundles($target_type); $return = array(); diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php index 6168bea..6a42b57 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/EntityReferenceAutocomplete.php @@ -71,7 +71,7 @@ public function getMatches($field, $instance, $entity_type, $entity_id = '', $pr throw new AccessDeniedHttpException(); } } - $handler = entity_reference_get_selection_handler($field, $instance, $entity); + $handler = entity_reference_get_selection_handler($instance, $entity); if (isset($string)) { // Get an array of matching entities. diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Derivative/SelectionBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Derivative/SelectionBase.php index 9e191bf..55dfe97 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Derivative/SelectionBase.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Derivative/SelectionBase.php @@ -46,7 +46,7 @@ public function getDerivativeDefinitions(array $base_plugin_definition) { foreach (entity_get_info() as $entity_type => $info) { if (!in_array($entity_type, $supported_entities)) { $this->derivatives[$entity_type] = $base_plugin_definition; - $this->derivatives[$entity_type]['label'] = t('@enitty_type selection', array('@entity_type' => $info['label'])); + $this->derivatives[$entity_type]['label'] = t('@entity_type selection', array('@entity_type' => $info['label'])); } } return $this->derivatives; diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionBroken.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionBroken.php index 31c1cb1..d8a73b9 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionBroken.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/Selection/SelectionBroken.php @@ -15,14 +15,6 @@ class SelectionBroken implements SelectionInterface { /** - * Constructs a SelectionBroken object. - */ - public function __construct($field, $instance = NULL) { - $this->field = $field; - $this->instance = $instance; - } - - /** * Implements SelectionInterface::settingsForm(). */ public static function settingsForm(&$field, &$instance) { diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/SelectionPluginManager.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/SelectionPluginManager.php index f178242..d51544d 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/SelectionPluginManager.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/Type/SelectionPluginManager.php @@ -42,7 +42,7 @@ public function createInstance($plugin_id, array $configuration = array()) { return parent::createInstance($plugin_id, $configuration); } catch (PluginException $e) { - return new SelectionBroken($configuration['field'], $configuration['instance']); + return new SelectionBroken($configuration['field_definition']); } } @@ -50,8 +50,8 @@ public function createInstance($plugin_id, array $configuration = array()) { * Overrides \Drupal\Component\Plugin\PluginManagerBase::getInstance(). */ public function getInstance(array $options) { - $selection_handler = $options['instance']['settings']['handler']; - $target_entity_type = $options['field']['settings']['target_type']; + $selection_handler = $options['field_definition']->getFieldSetting('handler'); + $target_entity_type = $options['field_definition']->getFieldSetting('target_type'); // Get all available selection plugins for this entity type. $selection_handler_groups = $this->getSelectionGroups($target_entity_type); diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php index ab60905..97aeb6e 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/entity_reference/selection/SelectionBase.php @@ -12,6 +12,7 @@ use Drupal\Core\Database\Query\AlterableInterface; use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; use Drupal\Component\Utility\NestedArray; use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface; @@ -30,18 +31,11 @@ class SelectionBase implements SelectionInterface { /** - * The field array. + * The field definition. * - * @var array + * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface */ - protected $field; - - /** - * The instance array. - * - * @var array - */ - protected $instance; + protected $fieldDefinition; /** * The entity object, or NULL @@ -53,9 +47,8 @@ class SelectionBase implements SelectionInterface { /** * Constructs a SelectionBase object. */ - public function __construct($field, $instance, EntityInterface $entity = NULL) { - $this->field = $field; - $this->instance = $instance; + public function __construct(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) { + $this->fieldDefinition = $field_definition; $this->entity = $entity; } @@ -165,7 +158,7 @@ public static function settingsForm(&$field, &$instance) { * Implements SelectionInterface::getReferencableEntities(). */ public function getReferencableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) { - $target_type = $this->field['settings']['target_type']; + $target_type = $this->fieldDefinition->getFieldSetting('target_type'); $query = $this->buildEntityQuery($match, $match_operator); if ($limit > 0) { @@ -204,7 +197,7 @@ public function countReferencableEntities($match = NULL, $match_operator = 'CONT public function validateReferencableEntities(array $ids) { $result = array(); if ($ids) { - $target_type = $this->field['settings']['target_type']; + $target_type = $this->fieldDefinition->getFieldSetting('target_type'); $entity_info = entity_get_info($target_type); $query = $this->buildEntityQuery(); $result = $query @@ -264,7 +257,7 @@ public function validateAutocompleteInput($input, &$element, &$form_state, $form * it. */ public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') { - $target_type = $this->field['settings']['target_type']; + $target_type = $this->fieldDefinition->getFieldSetting('target_type'); $entity_info = entity_get_info($target_type); $query = \Drupal::entityQuery($target_type); @@ -277,17 +270,18 @@ public function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') { } // Add entity-access tag. - $query->addTag($this->field['settings']['target_type'] . '_access'); + $query->addTag($this->fieldDefinition->getFieldSetting('target_type') . '_access'); // Add the Selection handler for // entity_reference_query_entity_reference_alter(). $query->addTag('entity_reference'); - $query->addMetaData('field', $this->field); + $query->addMetaData('field_definition', $this->fieldDefinition); $query->addMetaData('entity_reference_selection_handler', $this); // Add the sort option. - if (!empty($this->instance['settings']['handler_settings']['sort'])) { - $sort_settings = $this->instance['settings']['handler_settings']['sort']; + $handler_settings = $this->fieldDefinition->getFieldSetting('handler_settings'); + if (!empty($handler_settings['sort'])) { + $sort_settings = $handler_settings['sort']; if ($sort_settings['field'] != '_none') { $query->sort($sort_settings['field'], $sort_settings['direction']); } diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceEntityFormatter.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceEntityFormatter.php index 647de08..e54bf32 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceEntityFormatter.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/formatter/EntityReferenceEntityFormatter.php @@ -36,7 +36,7 @@ class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase { * {@inheritdoc} */ public function settingsForm(array $form, array &$form_state) { - $view_modes = entity_get_view_modes($this->field['settings']['target_type']); + $view_modes = entity_get_view_modes($this->getFieldSetting('target_type')); $options = array(); foreach ($view_modes as $view_mode => $view_mode_settings) { $options[$view_mode] = $view_mode_settings['label']; @@ -65,7 +65,7 @@ public function settingsForm(array $form, array &$form_state) { public function settingsSummary() { $summary = array(); - $view_modes = entity_get_view_modes($this->field['settings']['target_type']); + $view_modes = entity_get_view_modes($this->getFieldSetting('target_type')); $view_mode = $this->getSetting('view_mode'); $summary[] = t('Rendered as @mode', array('@mode' => isset($view_modes[$view_mode]['label']) ? $view_modes[$view_mode]['label'] : $view_mode)); $summary[] = $this->getSetting('links') ? t('Display links') : t('Do not display links'); @@ -83,7 +83,7 @@ public function viewElements(EntityInterface $entity, $langcode, array $items) { $view_mode = $this->getSetting('view_mode'); $links = $this->getSetting('links'); - $target_type = $this->field['settings']['target_type']; + $target_type = $this->getFieldSetting('target_type'); $elements = array(); diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteTagsWidget.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteTagsWidget.php index a88f2ea..a7e0fba 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteTagsWidget.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteTagsWidget.php @@ -34,14 +34,14 @@ class AutocompleteTagsWidget extends AutocompleteWidgetBase { /** - * Overrides \Drupal\entity_reference\Plugin\field\widget\AutocompleteWidgetBase::elementValidate() + * {@inheritdoc} */ public function elementValidate($element, &$form_state, $form) { $value = array(); // If a value was entered into the autocomplete. - $handler = entity_reference_get_selection_handler($this->field, $this->instance); - $bundles = entity_get_bundles($this->field['settings']['target_type']); - $auto_create = isset($this->instance['settings']['handler_settings']['auto_create']) ? $this->instance['settings']['handler_settings']['auto_create'] : FALSE; + $handler = entity_reference_get_selection_handler($this->fieldDefinition); + $bundles = entity_get_bundles($this->getFieldSetting('target_type')); + $auto_create = $this->getSelectionHandlerSetting('auto_create'); if (!empty($element['#value'])) { $entities = drupal_explode_tags($element['#value']); @@ -62,7 +62,7 @@ public function elementValidate($element, &$form_state, $form) { if ($match) { $value[] = array('target_id' => $match); } - elseif ($auto_create && (count($this->instance['settings']['handler_settings']['target_bundles']) == 1 || count($bundles) == 1)) { + elseif ($auto_create && (count($this->getSelectionHandlerSetting('target_bundles')) == 1 || count($bundles) == 1)) { // Auto-create item. see entity_reference_field_presave(). $value[] = array('target_id' => 'auto_create', 'label' => $entity); } diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidget.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidget.php index 57c4b7b..98fc52a 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidget.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidget.php @@ -38,7 +38,7 @@ class AutocompleteWidget extends AutocompleteWidgetBase { /** - * Overrides \Drupal\entity_reference\Plugin\field\widget\AutocompleteWidgetBase::formElement(). + * {@inheritdoc} */ public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { // We let the Field API handles multiple values for us, only take care of @@ -54,10 +54,10 @@ public function formElement(array $items, $delta, array $element, $langcode, arr } /** - * Overrides \Drupal\entity_reference\Plugin\field\widget\AutocompleteWidgetBase::elementValidate() + * {@inheritdoc} */ public function elementValidate($element, &$form_state, $form) { - $auto_create = isset($this->instance['settings']['handler_settings']['auto_create']) ? $this->instance['settings']['handler_settings']['auto_create'] : FALSE; + $auto_create = $this->getSelectionHandlerSetting('auto_create'); // If a value was entered into the autocomplete. $value = ''; @@ -69,11 +69,11 @@ public function elementValidate($element, &$form_state, $form) { else { // Try to get a match from the input string when the user didn't use the // autocomplete but filled in a value manually. - $handler = entity_reference_get_selection_handler($this->field, $this->instance); + $handler = entity_reference_get_selection_handler($this->fieldDefinition); $value = $handler->validateAutocompleteInput($element['#value'], $element, $form_state, $form, !$auto_create); } - if (!$value && $auto_create && (count($this->instance['settings']['handler_settings']['target_bundles']) == 1)) { + if (!$value && $auto_create && (count($this->getSelectionHandlerSetting('target_bundles')) == 1)) { // Auto-create item. see entity_reference_field_presave(). $value = array( 'target_id' => 'auto_create', diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php index 6a8df6f..3d96e11 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Plugin/field/widget/AutocompleteWidgetBase.php @@ -17,7 +17,7 @@ abstract class AutocompleteWidgetBase extends WidgetBase { /** - * Overrides \Drupal\field\Plugin\Type\Widget\WidgetBase::settingsForm(). + * {@inheritdoc} */ public function settingsForm(array $form, array &$form_state) { $element['match_operator'] = array( @@ -50,24 +50,14 @@ public function settingsForm(array $form, array &$form_state) { } /** - * Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement(). + * {@inheritdoc} */ public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { - $instance = $this->instance; - $field = $this->field; - $entity = isset($element['#entity']) ? $element['#entity'] : NULL; + $entity = $element['#entity']; // Prepare the autocomplete path. $autocomplete_path = $this->getSetting('autocomplete_path'); - $autocomplete_path .= '/' . $field['field_name'] . '/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/'; - - // Use as a placeholder in the URL when we don't have an entity. - // Most web servers collapse two consecutive slashes. - $id = 'NULL'; - if ($entity && $entity_id = $entity->id()) { - $id = $entity_id; - } - $autocomplete_path .= $id; + $autocomplete_path .= '/' . $this->fieldDefinition->getFieldName() . '/' . $entity->entityType() . '/' . $entity->bundle() . '/' . $entity->id(); $element += array( '#type' => 'textfield', @@ -83,7 +73,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr } /** - * Overrides \Drupal\field\Plugin\Type\Widget\WidgetBase::errorElement(). + * {@inheritdoc} */ public function errorElement(array $element, array $error, array $form, array &$form_state) { return $element['target_id']; @@ -107,7 +97,7 @@ protected function getLabels(array $items) { } // Load those entities and loop through them to extract their labels. - $entities = entity_load_multiple($this->field['settings']['target_type'], $entity_ids); + $entities = entity_load_multiple($this->getFieldSetting('target_type'), $entity_ids); foreach ($entities as $entity_id => $entity_item) { $label = $entity_item->label(); @@ -120,4 +110,12 @@ protected function getLabels(array $items) { } return $entity_labels; } + + /** + * Returns the value of a setting for the entity reference selection handler. + */ + protected function getSelectionHandlerSetting($setting_name) { + $settings = $this->getFieldSetting('handler_settings'); + return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL; + } } diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php index 9ab172b..7bb53b7 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionAccessTest.php @@ -7,6 +7,7 @@ namespace Drupal\entity_reference\Tests; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; use Drupal\Core\Language\Language; use Drupal\simpletest\WebTestBase; @@ -32,8 +33,8 @@ function setUp() { $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); } - protected function assertReferencable($field, $instance, $tests, $handler_name) { - $handler = entity_reference_get_selection_handler($field, $instance); + protected function assertReferencable(FieldDefinitionInterface $field_definition, $tests, $handler_name) { + $handler = entity_reference_get_selection_handler($field_definition); foreach ($tests as $test) { foreach ($test['arguments'] as $arguments) { @@ -58,8 +59,8 @@ protected function assertReferencable($field, $instance, $tests, $handler_name) * Test the node-specific overrides of the entity handler. */ public function testNodeHandler() { - // Build a fake field instance. - $field = array( + // Create a field and instance. + $field = field_create_field(array( 'translatable' => FALSE, 'entity_types' => array(), 'settings' => array( @@ -68,15 +69,18 @@ public function testNodeHandler() { 'field_name' => 'test_field', 'type' => 'entity_reference', 'cardinality' => '1', - ); - $instance = array( + )); + $instance = field_create_instance(array( + 'field_name' => 'test_field', + 'entity_type' => 'test_entity', + 'bundle' => 'test_bundle', 'settings' => array( 'handler' => 'default', 'handler_settings' => array( 'target_bundles' => array(), ), ), - ); + )); // Build a set of test data. // Titles contain HTML-special characters to test escaping. @@ -160,7 +164,7 @@ public function testNodeHandler() { 'result' => array(), ), ); - $this->assertReferencable($field, $instance, $referencable_tests, 'Node handler'); + $this->assertReferencable($instance, $referencable_tests, 'Node handler'); // Test as an admin. $admin_user = $this->drupalCreateUser(array('access content', 'bypass node access')); @@ -189,15 +193,15 @@ public function testNodeHandler() { ), ), ); - $this->assertReferencable($field, $instance, $referencable_tests, 'Node handler (admin)'); + $this->assertReferencable($instance, $referencable_tests, 'Node handler (admin)'); } /** * Test the user-specific overrides of the entity handler. */ public function testUserHandler() { - // Build a fake field instance. - $field = array( + // Create a field and instance. + $field = field_create_field(array( 'translatable' => FALSE, 'entity_types' => array(), 'settings' => array( @@ -206,15 +210,18 @@ public function testUserHandler() { 'field_name' => 'test_field', 'type' => 'entity_reference', 'cardinality' => '1', - ); - $instance = array( + )); + $instance = field_create_instance(array( + 'field_name' => 'test_field', + 'entity_type' => 'test_entity', + 'bundle' => 'test_bundle', 'settings' => array( 'handler' => 'default', 'handler_settings' => array( 'target_bundles' => array(), ), ), - ); + )); // Build a set of test data. $user_values = array( @@ -290,7 +297,7 @@ public function testUserHandler() { 'result' => array(), ), ); - $this->assertReferencable($field, $instance, $referencable_tests, 'User handler'); + $this->assertReferencable($instance, $referencable_tests, 'User handler'); $GLOBALS['user'] = $users['admin']; $referencable_tests = array( @@ -329,15 +336,15 @@ public function testUserHandler() { ), ), ); - $this->assertReferencable($field, $instance, $referencable_tests, 'User handler (admin)'); + $this->assertReferencable($instance, $referencable_tests, 'User handler (admin)'); } /** * Test the comment-specific overrides of the entity handler. */ public function testCommentHandler() { - // Build a fake field instance. - $field = array( + // Create a field and instance. + $field = field_create_field(array( 'translatable' => FALSE, 'entity_types' => array(), 'settings' => array( @@ -346,15 +353,18 @@ public function testCommentHandler() { 'field_name' => 'test_field', 'type' => 'entity_reference', 'cardinality' => '1', - ); - $instance = array( + )); + $instance = field_create_instance(array( + 'field_name' => 'test_field', + 'entity_type' => 'test_entity', + 'bundle' => 'test_bundle', 'settings' => array( 'handler' => 'default', 'handler_settings' => array( 'target_bundles' => array(), ), ), - ); + )); // Build a set of test data. $node_values = array( @@ -454,7 +464,7 @@ public function testCommentHandler() { 'result' => array(), ), ); - $this->assertReferencable($field, $instance, $referencable_tests, 'Comment handler'); + $this->assertReferencable($instance, $referencable_tests, 'Comment handler'); // Test as a comment admin. $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments')); @@ -472,7 +482,7 @@ public function testCommentHandler() { ), ), ); - $this->assertReferencable($field, $instance, $referencable_tests, 'Comment handler (comment admin)'); + $this->assertReferencable($instance, $referencable_tests, 'Comment handler (comment admin)'); // Test as a node and comment admin. $admin_user = $this->drupalCreateUser(array('access content', 'access comments', 'administer comments', 'bypass node access')); @@ -491,6 +501,6 @@ public function testCommentHandler() { ), ), ); - $this->assertReferencable($field, $instance, $referencable_tests, 'Comment handler (comment + node admin)'); + $this->assertReferencable($instance, $referencable_tests, 'Comment handler (comment + node admin)'); } } diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php index d3245e0..726f924 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/EntityReferenceSelectionSortTest.php @@ -54,8 +54,8 @@ public function testSort() { field_create_instance($instance_info); - // Build a fake field instance. - $field = array( + // Create a field and instance. + $field = field_create_field(array( 'translatable' => FALSE, 'entity_types' => array(), 'settings' => array( @@ -64,9 +64,11 @@ public function testSort() { 'field_name' => 'test_field', 'type' => 'entity_reference', 'cardinality' => 1, - ); - - $instance = array( + )); + $instance = field_create_instance(array( + 'field_name' => 'test_field', + 'entity_type' => 'test_entity', + 'bundle' => 'test_bundle', 'settings' => array( 'handler' => 'default', 'handler_settings' => array( @@ -78,7 +80,7 @@ public function testSort() { ), ), ), - ); + )); // Build a set of test data. $node_values = array( @@ -119,7 +121,7 @@ public function testSort() { $normal_user = $this->drupalCreateUser(array('access content')); $GLOBALS['user'] = $normal_user; - $handler = entity_reference_get_selection_handler($field, $instance); + $handler = entity_reference_get_selection_handler($instance); // Not only assert the result, but make sure the keys are sorted as // expected. @@ -135,7 +137,7 @@ public function testSort() { 'field' => 'nid', 'direction' => 'ASC', ); - $handler = entity_reference_get_selection_handler($field, $instance); + $handler = entity_reference_get_selection_handler($instance); $result = $handler->getReferencableEntities(); $expected_result = array( $nodes['published1']->nid => $node_labels['published1'], diff --git a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php index 6998209..2f53baf 100644 --- a/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php +++ b/core/modules/entity_reference/lib/Drupal/entity_reference/Tests/Views/SelectionTest.php @@ -39,8 +39,8 @@ public function testSelectionHandler() { $nodes[$node->type][$node->nid] = $node->label(); } - // Build a fake field instance. - $field = array( + // Create a field and instance. + $field = field_create_field(array( 'translatable' => FALSE, 'entity_types' => array(), 'settings' => array( @@ -49,8 +49,11 @@ public function testSelectionHandler() { 'field_name' => 'test_field', 'type' => 'entity_reference', 'cardinality' => '1', - ); - $instance = array( + )); + $instance = field_create_instance(array( + 'field_name' => 'test_field', + 'entity_type' => 'test_entity', + 'bundle' => 'test_bundle', 'settings' => array( 'handler' => 'views', 'handler_settings' => array( @@ -62,10 +65,10 @@ public function testSelectionHandler() { ), ), ), - ); + )); // Get values from selection handler. - $handler = entity_reference_get_selection_handler($field, $instance); + $handler = entity_reference_get_selection_handler($instance); $result = $handler->getReferencableEntities(); $success = FALSE; diff --git a/core/modules/field/field.api.php b/core/modules/field/field.api.php index 75a99df..4fe4fe3 100644 --- a/core/modules/field/field.api.php +++ b/core/modules/field/field.api.php @@ -207,6 +207,16 @@ function hook_field_info_alter(&$info) { } /** + * Act on field_info_cache_clear(). + * + * This hook is invoked after the field module caches are cleared. + */ +function hook_field_info_cache_clear() { + // Reset the static value that keeps track of allowed values for list fields. + drupal_static_reset('options_allowed_values'); +} + +/** * Define the Field API schema for a field structure. * * This hook MUST be defined in .install for it to be detected during @@ -654,14 +664,14 @@ function hook_field_prepare_translation(\Drupal\Core\Entity\EntityInterface $ent * * @param $item * An item that may or may not be empty. - * @param $field - * The field to which $item belongs. + * @param $field_type + * The field type to which $item belongs. * * @return - * TRUE if $field's type considers $item not to contain any data; FALSE + * TRUE if the field type considers $item not to contain any data; FALSE * otherwise. */ -function hook_field_is_empty($item, $field) { +function hook_field_is_empty($item, $field_type) { if (empty($item['value']) && (string) $item['value'] !== '0') { return TRUE; } @@ -724,19 +734,19 @@ function hook_field_widget_info_alter(array &$info) { * @param $form_state * An associative array containing the current state of the form. * @param $context - * An associative array containing the following key-value pairs, matching the - * arguments received by hook_field_widget_form(): + * An associative array containing the following key-value pairs: * - form: The form structure to which widgets are being attached. This may be * a full form structure, or a sub-element of a larger form. - * - field: The field structure. - * - instance: The field instance structure. + * - widget: The widget plugin instance. + * - field_definition: The field definition. + * - entity: The entity. * - langcode: The language associated with $items. * - items: Array of default values for this field. * - delta: The order of this item in the array of subelements (0, 1, 2, etc). * - default: A boolean indicating whether the form is being shown as a dummy * form to set default values. * - * @see hook_field_widget_form() + * @see \Drupal\field\Plugin\Type\Widget\WidgetBase::formSingleElement() * @see hook_field_widget_WIDGET_TYPE_form_alter() */ function hook_field_widget_form_alter(&$element, &$form_state, $context) { @@ -759,20 +769,10 @@ function hook_field_widget_form_alter(&$element, &$form_state, $context) { * @param $form_state * An associative array containing the current state of the form. * @param $context - * An associative array containing the following key-value pairs, matching the - * arguments received by hook_field_widget_form(): - * - "form": The form structure where widgets are being attached to. This - * might be a full form structure, or a sub-element of a larger form. - * - "field": The field structure. - * - "instance": The field instance structure. - * - "langcode": The language associated with $items. - * - "items": Array of default values for this field. - * - "delta": The order of this item in the array of subelements (0, 1, 2, - * etc). - * - default: A boolean indicating whether the form is being shown as a dummy - * form to set default values. + * An associative array. See hook_field_widget_form_alter() for the structure + * and content of the array. * - * @see hook_field_widget_form() + * @see \Drupal\field\Plugin\Type\Widget\WidgetBase::formSingleElement() * @see hook_field_widget_form_alter() */ function hook_field_widget_WIDGET_TYPE_form_alter(&$element, &$form_state, $context) { @@ -1901,8 +1901,7 @@ function hook_field_update_forbid($field, $prior_field, $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'); + // @todo Needs function body. } /** @@ -2076,7 +2075,7 @@ function hook_field_storage_purge(\Drupal\Core\Entity\EntityInterface $entity, $ * * @param $op * The operation to be performed. Possible values: 'edit', 'view'. - * @param $field + * @param \Drupal\field\FieldInterface $field * The field on which the operation is to be performed. * @param $entity_type * The type of $entity; for example, 'node' or 'user'. @@ -2088,7 +2087,7 @@ function hook_field_storage_purge(\Drupal\Core\Entity\EntityInterface $entity, $ * @return * TRUE if the operation is allowed, and FALSE if the operation is denied. */ -function hook_field_access($op, $field, $entity_type, $entity, $account) { +function hook_field_access($op, \Drupal\field\FieldInterface $field, $entity_type, $entity, $account) { if ($field['field_name'] == 'field_of_interest' && $op == 'edit') { return user_access('edit field of interest', $account); } diff --git a/core/modules/field/field.attach.inc b/core/modules/field/field.attach.inc index baa7ff4..6a6faa3 100644 --- a/core/modules/field/field.attach.inc +++ b/core/modules/field/field.attach.inc @@ -779,7 +779,6 @@ function _field_invoke_widget_target($form_display) { * '#default_value' => The field value for delta 0, * '#required' => Whether the widget should be marked required, * '#delta' => 0, - * '#columns' => The array of field columns, * // The remaining elements in the sub-array depend on the widget. * '#type' => The type of the widget, * ... @@ -791,7 +790,6 @@ function _field_invoke_widget_target($form_display) { * // Only for multiple widgets: * '#entity_type' => The name of the entity type, * '#bundle' => $instance['bundle'], - * '#columns' => array_keys($field['columns']), * // The remaining elements in the sub-array depend on the widget. * '#type' => The type of the widget, * ... diff --git a/core/modules/field/field.default.inc b/core/modules/field/field.default.inc index ab6b10e..cc6a393 100644 --- a/core/modules/field/field.default.inc +++ b/core/modules/field/field.default.inc @@ -42,7 +42,7 @@ */ function field_default_validate(EntityInterface $entity, $field, $instance, $langcode, $items, &$errors) { // Filter out empty values. - $items = _field_filter_items($field, $items); + $items = _field_filter_items($field['type'], $items); // Check that the number of values doesn't exceed the field cardinality. // For form submitted values, this can only happen with 'multiple value' diff --git a/core/modules/field/field.form.inc b/core/modules/field/field.form.inc index 203a112..198aa47 100644 --- a/core/modules/field/field.form.inc +++ b/core/modules/field/field.form.inc @@ -152,14 +152,9 @@ function field_add_more_js($form, $form_state) { // Go one level up in the form, to the widgets container. $element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, -1)); - $field_name = $element['#field_name']; - $langcode = $element['#language']; - $parents = $element['#field_parents']; - $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state); - - $field = $field_state['field']; - if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED) { + // Ensure the widget allows adding additional items. + if ($element['#cardinality'] != FIELD_CARDINALITY_UNLIMITED) { return; } @@ -185,8 +180,6 @@ function field_add_more_js($form, $form_state) { * * @return * An array with the following key/data pairs: - * - field: The field definition array. - * - instance: The field instance definition array. * - items_count: The number of widgets to display for the field. * - array_parents: The location of the field's widgets within the $form * structure. This entry is populated at '#after_build' time. @@ -256,52 +249,3 @@ function _field_form_state_parents($parents, $field_name, $langcode) { return $form_state_parents; } -/** - * Retrieves the field definition for a widget's helper callbacks. - * - * Widget helper element callbacks (such as #process, #element_validate, - * #value_callback, ...) should use field_widget_field() and - * field_widget_instance() instead of field_info_field() and - * field_info_instance() when they need to access field or instance properties. - * See hook_field_widget_form() for more details. - * - * @param $element - * The structured array for the widget. - * @param $form_state - * The form state. - * - * @return - * The $field definition array for the current widget. - * - * @see field_widget_instance() - * @see hook_field_widget_form() - */ -function field_widget_field($element, $form_state) { - $field_state = field_form_get_state($element['#field_parents'], $element['#field_name'], $element['#language'], $form_state); - return $field_state['field']; -} - -/** - * Retrieves the instance definition array for a widget's helper callbacks. - * - * Widgets helper element callbacks (such as #process, #element_validate, - * #value_callback, ...) should use field_widget_field() and - * field_widget_instance() instead of field_info_field() and - * field_info_instance() when they need to access field or instance properties. - * See hook_field_widget_form() for more details. - * - * @param $element - * The structured array for the widget. - * @param $form_state - * The form state. - * - * @return - * The $instance definition array for the current widget. - * - * @see field_widget_field() - * @see hook_field_widget_form() - */ -function field_widget_instance($element, $form_state) { - $field_state = field_form_get_state($element['#field_parents'], $element['#field_name'], $element['#language'], $form_state); - return $field_state['instance']; -} diff --git a/core/modules/field/field.info.inc b/core/modules/field/field.info.inc index f69649d..b6b1b0a 100644 --- a/core/modules/field/field.info.inc +++ b/core/modules/field/field.info.inc @@ -39,6 +39,8 @@ function field_info_cache_clear() { _field_info_collate_types_reset(); Field::fieldInfo()->flush(); + + Drupal::moduleHandler()->invokeAll('field_info_cache_clear'); } /** diff --git a/core/modules/field/field.module b/core/modules/field/field.module index 798d604..7ff93f3 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Language\Language; use Drupal\Core\Template\Attribute; +use Drupal\field\FieldInterface; /* * Load all public Field API functions. Drupal currently has no @@ -501,8 +502,8 @@ function field_get_default_value(EntityInterface $entity, $field, $instance, $la /** * Filters out empty field values. * - * @param $field - * The field definition. + * @param $field_type + * The field type. * @param $items * The field values to filter. * @@ -510,11 +511,12 @@ function field_get_default_value(EntityInterface $entity, $field, $instance, $la * The array of items without empty field values. The function also renumbers * the array keys to ensure sequential deltas. */ -function _field_filter_items($field, $items) { - $function = $field['module'] . '_field_is_empty'; +function _field_filter_items($field_type, $items) { + $field_type_info = field_info_field_types($field_type); + $function = $field_type_info['module'] . '_field_is_empty'; foreach ((array) $items as $delta => $item) { // Explicitly break if the function is undefined. - if ($function($item, $field)) { + if ($function($item, $field_type)) { unset($items[$delta]); } } @@ -808,7 +810,7 @@ function field_view_field(EntityInterface $entity, $field_name, $display_options $formatter_manager = drupal_container()->get('plugin.manager.field.formatter'); $display_options = $formatter_manager->prepareConfiguration($field['type'], $display_options); $formatter = $formatter_manager->getInstance(array( - 'instance' => $instance, + 'field_definition' => $instance, 'view_mode' => $view_mode, 'prepare' => FALSE, 'configuration' => $display_options, @@ -927,9 +929,8 @@ function field_has_data($field) { * The operation to be performed. Possible values: * - edit * - view - * @param array $field - * The full field structure array for the field on which the operation is to - * be performed. See field_info_field(). + * @param \Drupal\field\FieldInterface $field + * The field on which the operation is to be performed. * @param $entity_type * The type of $entity; for example, 'node' or 'user'. * @param $entity @@ -940,7 +941,7 @@ function field_has_data($field) { * @return * TRUE if the operation is allowed; FALSE if the operation is denied. */ -function field_access($op, $field, $entity_type, $entity = NULL, $account = NULL) { +function field_access($op, FieldInterface $field, $entity_type, $entity = NULL, $account = NULL) { global $user; if (!isset($account)) { diff --git a/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php b/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php index c6b8ad6..d2a0b85 100644 --- a/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php +++ b/core/modules/field/lib/Drupal/field/FieldInstanceInterface.php @@ -8,11 +8,12 @@ namespace Drupal\field; use Drupal\Core\Config\Entity\ConfigEntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; /** * Provides an interface defining a field instance entity. */ -interface FieldInstanceInterface extends ConfigEntityInterface, \ArrayAccess, \Serializable { +interface FieldInstanceInterface extends ConfigEntityInterface, FieldDefinitionInterface, \ArrayAccess, \Serializable { /** * Returns the field entity for this instance. diff --git a/core/modules/field/lib/Drupal/field/FieldInterface.php b/core/modules/field/lib/Drupal/field/FieldInterface.php index 32673ff..83b3de7 100644 --- a/core/modules/field/lib/Drupal/field/FieldInterface.php +++ b/core/modules/field/lib/Drupal/field/FieldInterface.php @@ -8,11 +8,12 @@ namespace Drupal\field; use Drupal\Core\Config\Entity\ConfigEntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; /** * Provides an interface defining a field entity. */ -interface FieldInterface extends ConfigEntityInterface, \ArrayAccess, \Serializable { +interface FieldInterface extends ConfigEntityInterface, FieldDefinitionInterface, \ArrayAccess, \Serializable { /** * Returns the field schema. 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..3baed23 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 @@ -512,6 +512,78 @@ public function getBundles() { /** * {@inheritdoc} */ + public function getFieldName() { + return $this->id; + } + + /** + * {@inheritdoc} + */ + public function getFieldType() { + return $this->type; + } + + /** + * {@inheritdoc} + */ + public function getFieldSettings() { + return field_info_instance_settings($this->type) + $this->settings; + } + + /** + * {@inheritdoc} + */ + public function getFieldSetting($setting_name) { + $settings = $this->getFieldSettings(); + return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL; + } + + /** + * {@inheritdoc} + */ + public function getFieldPropertyNames() { + $schema = $this->getSchema(); + return array_keys($schema['columns']); + } + + /** + * {@inheritdoc} + */ + public function isFieldTranslatable() { + return $this->translatable; + } + + /** + * {@inheritdoc} + */ + public function getFieldLabel() { + return $this->label(); + } + + /** + * {@inheritdoc} + */ + public function getFieldDescription() { + return ''; + } + + /** + * {@inheritdoc} + */ + public function getFieldCardinality() { + return $this->cardinality; + } + + /** + * {@inheritdoc} + */ + public function isFieldRequired() { + return FALSE; + } + + /** + * {@inheritdoc} + */ public function offsetExists($offset) { return isset($this->{$offset}) || in_array($offset, array('columns', 'foreign keys', 'bundles', 'storage_details')); } 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..9f3e7a7 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 @@ -441,6 +441,78 @@ public function getField() { /** * {@inheritdoc} */ + public function getFieldName() { + return $this->field->id; + } + + /** + * {@inheritdoc} + */ + public function getFieldType() { + return $this->field->type; + } + + /** + * {@inheritdoc} + */ + public function getFieldSettings() { + return $this->settings + $this->field->settings; + } + + /** + * {@inheritdoc} + */ + public function getFieldSetting($setting_name) { + $settings = $this->getFieldSettings(); + return isset($settings[$setting_name]) ? $settings[$setting_name] : NULL; + } + + /** + * {@inheritdoc} + */ + public function getFieldPropertyNames() { + $schema = $this->field->getSchema(); + return array_keys($schema['columns']); + } + + /** + * {@inheritdoc} + */ + public function isFieldTranslatable() { + return $this->field->translatable; + } + + /** + * {@inheritdoc} + */ + public function getFieldLabel() { + return $this->label(); + } + + /** + * {@inheritdoc} + */ + public function getFieldDescription() { + return $this->description; + } + + /** + * {@inheritdoc} + */ + public function getFieldCardinality() { + return $this->field->cardinality; + } + + /** + * {@inheritdoc} + */ + public function isFieldRequired() { + return $this->required; + } + + /** + * {@inheritdoc} + */ public function allowBundleRename() { $this->bundle_rename_allowed = TRUE; } diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php index 6b316ae..08ea1e9 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php @@ -2,14 +2,15 @@ /** * @file - * Definition of Drupal\field\Plugin\Type\Formatter\FormatterBase. + * Contains \Drupal\field\Plugin\Type\Formatter\FormatterBase. */ namespace Drupal\field\Plugin\Type\Formatter; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; +use Drupal\field\FieldInstanceInterface; use Drupal\field\Plugin\PluginSettingsBase; -use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Base class for 'Field formatter' plugin implementations. @@ -19,16 +20,9 @@ /** * The field definition. * - * @var array - */ - protected $field; - - /** - * The field instance definition. - * - * @var \Drupal\field\Plugin\Core\Entity\FieldInstance + * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface */ - protected $instance; + protected $fieldDefinition; /** * The formatter settings. @@ -58,8 +52,8 @@ * The plugin_id for the formatter. * @param array $plugin_definition * The plugin implementation definition. - * @param \Drupal\field\Plugin\Core\Entity\FieldInstance $instance - * The field instance to which the formatter is associated. + * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition + * The definition of the field to which the formatter is associated. * @param array $settings * The formatter settings. * @param string $label @@ -67,11 +61,10 @@ * @param string $view_mode * The view mode. */ - public function __construct($plugin_id, array $plugin_definition, $instance, array $settings, $label, $view_mode) { + public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode) { parent::__construct(array(), $plugin_id, $plugin_definition); - $this->instance = $instance; - $this->field = field_info_field($instance['field_name']); + $this->fieldDefinition = $field_definition; $this->settings = $settings; $this->label = $label; $this->viewMode = $view_mode; @@ -81,9 +74,6 @@ public function __construct($plugin_id, array $plugin_definition, $instance, arr * {@inheritdoc} */ public function view(EntityInterface $entity, $langcode, array $items) { - $field = $this->field; - $instance = $this->instance; - $addition = array(); $elements = $this->viewElements($entity, $langcode, $items); @@ -91,14 +81,14 @@ public function view(EntityInterface $entity, $langcode, array $items) { $entity_type = $entity->entityType(); $info = array( '#theme' => 'field', - '#title' => $instance['label'], - '#access' => field_access('view', $field, $entity->entityType(), $entity), + '#title' => $this->fieldDefinition->getFieldLabel(), + '#access' => $this->checkFieldAccess('view', $entity), '#label_display' => $this->label, '#view_mode' => $this->viewMode, '#language' => $langcode, - '#field_name' => $field['field_name'], - '#field_type' => $field['type'], - '#field_translatable' => $field['translatable'], + '#field_name' => $this->fieldDefinition->getFieldName(), + '#field_type' => $this->fieldDefinition->getFieldType(), + '#field_translatable' => $this->fieldDefinition->isFieldTranslatable(), '#entity_type' => $entity_type, '#bundle' => $entity->bundle(), '#object' => $entity, @@ -106,7 +96,7 @@ public function view(EntityInterface $entity, $langcode, array $items) { '#formatter' => $this->getPluginId(), ); - $addition[$field['field_name']] = array_merge($info, $elements); + $addition[$this->fieldDefinition->getFieldName()] = array_merge($info, $elements); } return $addition; @@ -131,4 +121,26 @@ public function settingsSummary() { */ public function prepareView(array $entities, $langcode, array &$items) { } + /** + * Returns whether the currently logged in user has access to the field. + * + * @todo Remove this once Field API access is unified with entity field + * access: http://drupal.org/node/1994140. + */ + protected function checkFieldAccess($op, $entity) { + if ($this->fieldDefinition instanceof FieldInstanceInterface) { + $field = $this->fieldDefinition->getField(); + return field_access($op, $field, $entity->entityType(), $entity); + } + else { + return FALSE; + } + } + + /** + * Returns the value of a field setting. + */ + protected function getFieldSetting($setting_name) { + return $this->fieldDefinition->getFieldSetting($setting_name); + } } diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php index 0df5b97..1e41001 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\field\Plugin\Type\Formatter\FormatterFactory. + * Contains \Drupal\field\Plugin\Type\Formatter\FormatterFactory. */ namespace Drupal\field\Plugin\Type\Formatter; @@ -15,11 +15,11 @@ class FormatterFactory extends DefaultFactory { /** - * Overrides Drupal\Component\Plugin\Factory\DefaultFactory::createInstance(). + * {@inheritdoc} */ public function createInstance($plugin_id, array $configuration) { $plugin_definition = $this->discovery->getDefinition($plugin_id); $plugin_class = static::getPluginClass($plugin_id, $plugin_definition); - return new $plugin_class($plugin_id, $plugin_definition, $configuration['instance'], $configuration['settings'], $configuration['label'], $configuration['view_mode']); + return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode']); } } diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php index ab5f207..0b04387 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php @@ -55,7 +55,7 @@ public function __construct(\Traversable $namespaces) { * * @param array $options * An array with the following key/value pairs: - * - instance: (FieldInstance) The field instance. + * - field_definition: (FieldDefinitionInterface) The field definition. * - view_mode: (string) The view mode. * - prepare: (bool, optional) Whether default values should get merged in * the 'configuration' array. Defaults to TRUE. @@ -77,12 +77,12 @@ public function __construct(\Traversable $namespaces) { */ public function getInstance(array $options) { $configuration = $options['configuration']; - $instance = $options['instance']; - $field = field_info_field($instance['field_name']); + $field_definition = $options['field_definition']; + $field_type = $field_definition->getFieldType(); // Fill in default configuration if needed. if (!isset($options['prepare']) || $options['prepare'] == TRUE) { - $configuration = $this->prepareConfiguration($field['type'], $configuration); + $configuration = $this->prepareConfiguration($field_type, $configuration); } $plugin_id = $configuration['type']; @@ -91,14 +91,14 @@ public function getInstance(array $options) { // - $type_info doesn't exist (the widget type is unknown), // - the field type is not allowed for the widget. $definition = $this->getDefinition($configuration['type']); - if (!isset($definition['class']) || !in_array($field['type'], $definition['field_types'])) { + if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) { // Grab the default widget for the field type. - $field_type_definition = field_info_field_types($field['type']); + $field_type_definition = field_info_field_types($field_type); $plugin_id = $field_type_definition['default_formatter']; } $configuration += array( - 'instance' => $instance, + 'field_definition' => $field_definition, 'view_mode' => $options['view_mode'], ); return $this->createInstance($plugin_id, $configuration); diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php index 89c212a..4d7a7b7 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php @@ -2,15 +2,16 @@ /** * @file - * Definition of Drupal\field\Plugin\Type\Widget\WidgetBase. + * Contains \Drupal\field\Plugin\Type\Widget\WidgetBase. */ namespace Drupal\field\Plugin\Type\Widget; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; +use Drupal\field\FieldInstanceInterface; use Drupal\field\Plugin\PluginSettingsBase; -use Drupal\field\Plugin\Core\Entity\FieldInstance; /** * Base class for 'Field widget' plugin implementations. @@ -20,16 +21,9 @@ /** * The field definition. * - * @var array - */ - protected $field; - - /** - * The field instance definition. - * - * @var \Drupal\field\Plugin\Core\Entity\FieldInstance + * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface */ - protected $instance; + protected $fieldDefinition; /** * The widget settings. @@ -45,26 +39,23 @@ * The plugin_id for the widget. * @param array $plugin_definition * The plugin implementation definition. - * @param \Drupal\field\Plugin\Core\Entity\FieldInstance $instance - * The field instance to which the widget is associated. + * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition + * The definition of the field to which the widget is associated. * @param array $settings * The widget settings. */ - public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) { + public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) { parent::__construct(array(), $plugin_id, $plugin_definition); - $this->instance = $instance; - $this->field = field_info_field($instance['field_name']); + $this->fieldDefinition = $field_definition; $this->settings = $settings; } /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::form(). + * {@inheritdoc} */ public function form(EntityInterface $entity, $langcode, array $items, array &$form, array &$form_state, $get_delta = NULL) { - $field = $this->field; - $instance = $this->instance; - $field_name = $field['field_name']; + $field_name = $this->fieldDefinition->getFieldName(); $parents = $form['#parents']; @@ -75,11 +66,9 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f // Store field information in $form_state. if (!field_form_get_state($parents, $field_name, $langcode, $form_state)) { $field_state = array( - 'field' => $field, - 'instance' => $instance, - 'items_count' => count($items), - 'array_parents' => array(), - 'errors' => array(), + 'items_count' => count($items), + 'array_parents' => array(), + 'errors' => array(), ); field_form_set_state($parents, $field_name, $langcode, $form_state, $field_state); } @@ -94,8 +83,8 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f if (isset($get_delta) || $definition['multiple_values']) { $delta = isset($get_delta) ? $get_delta : 0; $element = array( - '#title' => check_plain($instance['label']), - '#description' => field_filter_xss(\Drupal::token()->replace($instance['description'])), + '#title' => check_plain($this->fieldDefinition->getFieldLabel()), + '#description' => field_filter_xss(\Drupal::token()->replace($this->fieldDefinition->getFieldDescription())), ); $element = $this->formSingleElement($entity, $items, $delta, $langcode, $element, $form, $form_state); @@ -125,7 +114,7 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f '#type' => 'container', '#attributes' => array( 'class' => array( - 'field-type-' . drupal_html_class($field['type']), + 'field-type-' . drupal_html_class($this->fieldDefinition->getFieldType()), 'field-name-' . drupal_html_class($field_name), 'field-widget-' . drupal_html_class($this->getPluginId()), ), @@ -146,7 +135,7 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f // when $langcode is unknown. '#language' => $langcode, $langcode => $elements, - '#access' => field_access('edit', $field, $entity->entityType(), $entity), + '#access' => $this->checkFieldAccess('edit', $entity), ); return $addition; @@ -161,14 +150,12 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f * - table display and drag-n-drop value reordering */ protected function formMultipleElements(EntityInterface $entity, array $items, $langcode, array &$form, array &$form_state) { - $field = $this->field; - $instance = $this->instance; - $field_name = $field['field_name']; - + $field_name = $this->fieldDefinition->getFieldName(); $parents = $form['#parents']; // Determine the number of widgets to display. - switch ($field['cardinality']) { + $cardinality = $this->fieldDefinition->getFieldCardinality(); + switch ($cardinality) { case FIELD_CARDINALITY_UNLIMITED: $field_state = field_form_get_state($parents, $field_name, $langcode, $form_state); $max = $field_state['items_count']; @@ -176,16 +163,16 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $ break; default: - $max = $field['cardinality'] - 1; - $is_multiple = ($field['cardinality'] > 1); + $max = $cardinality - 1; + $is_multiple = ($cardinality > 1); break; } $id_prefix = implode('-', array_merge($parents, array($field_name))); $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper'); - $title = check_plain($instance['label']); - $description = field_filter_xss(\Drupal::token()->replace($instance['description'])); + $title = check_plain($this->fieldDefinition->getFieldLabel()); + $description = field_filter_xss(\Drupal::token()->replace($this->fieldDefinition->getFieldDescription())); $elements = array(); @@ -221,9 +208,9 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $ if ($elements) { $elements += array( '#theme' => 'field_multiple_value_form', - '#field_name' => $field['field_name'], - '#cardinality' => $field['cardinality'], - '#required' => $instance['required'], + '#field_name' => $this->fieldDefinition->getFieldName(), + '#cardinality' => $this->fieldDefinition->getFieldCardinality(), + '#required' => $this->fieldDefinition->isFieldRequired(), '#title' => $title, '#description' => $description, '#prefix' => '
', @@ -232,7 +219,7 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $ ); // Add 'add more' button, if not working with a programmed form. - if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED && empty($form_state['programmed'])) { + if ($this->fieldDefinition->getFieldCardinality() == FIELD_CARDINALITY_UNLIMITED && empty($form_state['programmed'])) { $elements['add_more'] = array( '#type' => 'submit', '#name' => strtr($id_prefix, '-', '_') . '_add_more', @@ -256,19 +243,15 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $ * Generates the form element for a single copy of the widget. */ protected function formSingleElement(EntityInterface $entity, array $items, $delta, $langcode, array $element, array &$form, array &$form_state) { - $instance = $this->instance; - $field = $this->field; - $element += array( '#entity_type' => $entity->entityType(), '#bundle' => $entity->bundle(), '#entity' => $entity, - '#field_name' => $field['field_name'], + '#field_name' => $this->fieldDefinition->getFieldName(), '#language' => $langcode, '#field_parents' => $form['#parents'], - '#columns' => array_keys($field['columns']), // Only the first widget should be required. - '#required' => $delta == 0 && $instance['required'], + '#required' => $delta == 0 && $this->fieldDefinition->isFieldRequired(), '#delta' => $delta, '#weight' => $delta, ); @@ -279,8 +262,9 @@ protected function formSingleElement(EntityInterface $entity, array $items, $del // Allow modules to alter the field widget form element. $context = array( 'form' => $form, - 'field' => $field, - 'instance' => $instance, + 'widget' => $this, + 'field_definition' => $this->fieldDefinition, + 'entity' => $entity, 'langcode' => $langcode, 'items' => $items, 'delta' => $delta, @@ -293,10 +277,10 @@ protected function formSingleElement(EntityInterface $entity, array $items, $del } /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::extractFormValues(). + * {@inheritdoc} */ public function extractFormValues(EntityInterface $entity, $langcode, array &$items, array $form, array &$form_state) { - $field_name = $this->field['field_name']; + $field_name = $this->fieldDefinition->getFieldName(); // Extract the values from $form_state['values']. $path = array_merge($form['#parents'], array($field_name, $langcode)); @@ -331,7 +315,7 @@ public function extractFormValues(EntityInterface $entity, $langcode, array &$it $this->sortItems($items); // Remove empty values. - $items = _field_filter_items($this->field, $items); + $items = _field_filter_items($this->fieldDefinition->getFieldType(), $items); // Put delta mapping in $form_state, so that flagErrors() can use it. $field_state = field_form_get_state($form['#parents'], $field_name, $langcode, $form_state); @@ -344,10 +328,10 @@ public function extractFormValues(EntityInterface $entity, $langcode, array &$it } /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::flagErrors(). + * {@inheritdoc} */ public function flagErrors(EntityInterface $entity, $langcode, array $items, array $form, array &$form_state) { - $field_name = $this->field['field_name']; + $field_name = $this->fieldDefinition->getFieldName(); $field_state = field_form_get_state($form['#parents'], $field_name, $langcode, $form_state); @@ -410,7 +394,8 @@ public function massageFormValues(array $values, array $form, array &$form_state * The field values. */ protected function sortItems(array &$items) { - $is_multiple = ($this->field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) || ($this->field['cardinality'] > 1); + $cardinality = $this->fieldDefinition->getFieldCardinality(); + $is_multiple = ($cardinality == FIELD_CARDINALITY_UNLIMITED) || ($cardinality > 1); if ($is_multiple && isset($items[0]['_weight'])) { usort($items, function ($a, $b) { $a_weight = (is_array($a) ? $a['_weight'] : 0); @@ -426,4 +411,26 @@ protected function sortItems(array &$items) { } } + /** + * Returns whether the currently logged in user has access to the field. + * + * @todo Remove this once Field API access is unified with entity field + * access: http://drupal.org/node/1994140. + */ + protected function checkFieldAccess($op, $entity) { + if ($this->fieldDefinition instanceof FieldInstanceInterface) { + $field = $this->fieldDefinition->getField(); + return field_access($op, $field, $entity->entityType(), $entity); + } + else { + return FALSE; + } + } + + /** + * Returns the value of a field setting. + */ + protected function getFieldSetting($setting_name) { + return $this->fieldDefinition->getFieldSetting($setting_name); + } } diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php index 9b14e85..4b7cb6b 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetFactory.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\field\Plugin\WidgetFactory. + * Contains \Drupal\field\Plugin\WidgetFactory. */ namespace Drupal\field\Plugin\Type\Widget; @@ -15,11 +15,11 @@ class WidgetFactory extends DefaultFactory { /** - * Overrides Drupal\Component\Plugin\Factory\DefaultFactory::createInstance(). + * {@inheritdoc} */ public function createInstance($plugin_id, array $configuration) { $plugin_definition = $this->discovery->getDefinition($plugin_id); $plugin_class = static::getPluginClass($plugin_id, $plugin_definition); - return new $plugin_class($plugin_id, $plugin_definition, $configuration['instance'], $configuration['settings']); + return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings']); } } diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php index eb82844..e00005b 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetInterface.php @@ -48,26 +48,18 @@ public function settingsForm(array $form, array &$form_state); * each form element. If there are multiple values for this field, the * formElement() method will be called as many times as needed. * - * Note that, depending on the context in which the widget is being included - * (regular entity form, field configuration form, advanced search form...), - * the values for $field and $instance might be different from the "official" - * definitions returned by field_info_field() and field_info_instance(). - * Examples: mono-value widget even if the field is multi-valued, non-required - * widget even if the field is 'required'... - * - * Therefore, the FAPI element callbacks (such as #process, #element_validate, - * #value_callback...) used by the widget cannot use the field_info_field() - * or field_info_instance() functions to retrieve the $field or $instance - * definitions they should operate on. The field_widget_field() and - * field_widget_instance() functions should be used instead to fetch the - * current working definitions from $form_state, where Field API stores them. - * - * Alternatively, hook_field_widget_form() can extract the needed specific - * properties from $field and $instance and set them as ad-hoc - * $element['#custom'] properties, for later use by its element callbacks. - * * Other modules may alter the form element provided by this function using - * hook_field_widget_form_alter(). + * hook_field_widget_form_alter() or + * hook_field_widget_WIDGET_TYPE_form_alter(). + * + * The FAPI element callbacks (such as #process, #element_validate, + * #value_callback...) used by the widget do not have access to the original + * $field_definition passed to the widget's constructor. Therefore, if any + * information is needed from that definition by those callbacks, the widget + * implementing this method, or a hook_field_widget[_WIDGET_TYPE]_form_alter() + * implementation, must extract the needed properties from the field + * definition and set them as ad-hoc $element['#custom'] properties, for later + * use by its element callbacks. * * @param array $items * Array of default values for this field. @@ -86,7 +78,6 @@ public function settingsForm(array $form, array &$form_state); * $form_state['values'], and is used to access processing information * for the field through the field_form_get_state() and * field_form_set_state() functions. - * - #columns: A list of field storage columns of the field. * - #title: The sanitized element label for the field instance, ready for * output. * - #description: The sanitized element description for the field instance, @@ -107,8 +98,6 @@ public function settingsForm(array $form, array &$form_state); * @return array * The form elements for a single widget for this field. * - * @see field_widget_field() - * @see field_widget_instance() * @see hook_field_widget_form_alter() * @see hook_field_widget_WIDGET_TYPE_form_alter() */ diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php index f5807be..eb9cc87 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php +++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetPluginManager.php @@ -56,7 +56,7 @@ public function __construct(\Traversable $namespaces) { * * @param array $options * An array with the following key/value pairs: - * - instance: (FieldInstance) The field instance. + * - field_definition: (FieldDefinitionInterface) The field definition. * - form_mode: (string) The form mode. * - prepare: (bool, optional) Whether default values should get merged in * the 'configuration' array. Defaults to TRUE. @@ -75,12 +75,12 @@ public function __construct(\Traversable $namespaces) { */ public function getInstance(array $options) { $configuration = $options['configuration']; - $instance = $options['instance']; - $field = field_info_field($instance['field_name']); + $field_definition = $options['field_definition']; + $field_type = $field_definition->getFieldType(); // Fill in default configuration if needed. if (!isset($options['prepare']) || $options['prepare'] == TRUE) { - $configuration = $this->prepareConfiguration($field['type'], $configuration); + $configuration = $this->prepareConfiguration($field_type, $configuration); } $plugin_id = $configuration['type']; @@ -89,14 +89,14 @@ public function getInstance(array $options) { // - $type_info doesn't exist (the widget type is unknown), // - the field type is not allowed for the widget. $definition = $this->getDefinition($configuration['type']); - if (!isset($definition['class']) || !in_array($field['type'], $definition['field_types'])) { + if (!isset($definition['class']) || !in_array($field_type, $definition['field_types'])) { // Grab the default widget for the field type. - $field_type_definition = field_info_field_types($field['type']); + $field_type_definition = field_info_field_types($field_type); $plugin_id = $field_type_definition['default_widget']; } $configuration += array( - 'instance' => $instance, + 'field_definition' => $field_definition, ); return $this->createInstance($plugin_id, $configuration); } diff --git a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php index c29c031..02cf9a9 100644 --- a/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php +++ b/core/modules/field/lib/Drupal/field/Plugin/views/field/Field.php @@ -32,11 +32,11 @@ class Field extends FieldPluginBase { public $items = array(); /** - * Store the field information. + * The field information as returned by field_info_field(). * - * @var array + * @var \Drupal\field\FieldInterface */ - public $field_info = array(); + public $field_info; /** @@ -61,13 +61,6 @@ class Field extends FieldPluginBase { public $base_table; /** - * Store the field instance. - * - * @var array - */ - public $instance; - - /** * An array of formatter options. * * @var array @@ -393,11 +386,8 @@ public function buildOptionsForm(&$form, &$form_state) { $settings = $this->options['settings'] + field_info_formatter_settings($format); - // Provide an instance array for hook_field_formatter_settings_form(). - $this->instance = $this->fakeFieldInstance($format, $settings); - $options = array( - 'instance' => $this->instance, + 'field_definition' => $field, 'configuration' => array( 'type' => $format, 'settings' => $settings, @@ -416,42 +406,6 @@ public function buildOptionsForm(&$form, &$form_state) { } /** - * Provides a fake field instance. - * - * @param string $formatter - * The machine name of the formatter to use. - * @param array $formatter_settings - * An associative array of settings for the formatter. - * - * @return array - * An associative array of instance date for the fake field. - * - * @see field_info_instance() - */ - function fakeFieldInstance($formatter, $formatter_settings) { - $field_name = $this->definition['field_name']; - $field = field_read_field($field_name); - - $field_type = field_info_field_types($field['type']); - - return array( - // Build a fake entity type and bundle. - 'field_name' => $field_name, - 'entity_type' => 'views_fake', - 'bundle' => 'views_fake', - - // Use the default field settings. - 'settings' => field_info_instance_settings($field['type']), - - // Set the other fields to their default values. - 'required' => FALSE, - 'label' => $field_name, - 'description' => '', - 'deleted' => FALSE, - ); - } - - /** * Provide options for multiple value fields. */ function multiple_options_form(&$form, &$form_state) { 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 d2f4a94..23ae814 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 @@ -7,6 +7,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\field\FieldException; +use Drupal\field\FieldInterface; /** * Implements hook_field_info(). @@ -137,7 +138,7 @@ function field_test_field_validate(EntityInterface $entity = NULL, $field, $inst /** * Implements hook_field_is_empty(). */ -function field_test_field_is_empty($item, $field) { +function field_test_field_is_empty($item, $field_type) { return empty($item['value']); } @@ -197,7 +198,7 @@ function field_test_default_value(EntityInterface $entity, $field, $instance) { /** * Implements hook_field_access(). */ -function field_test_field_access($op, $field, $entity_type, $entity, $account) { +function field_test_field_access($op, FieldInterface $field, $entity_type, $entity, $account) { if ($field['field_name'] == "field_no_{$op}_access") { return FALSE; } 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..5c28609 100644 --- a/core/modules/field/tests/modules/field_test/field_test.module +++ b/core/modules/field/tests/modules/field_test/field_test.module @@ -203,15 +203,13 @@ function field_test_field_attach_view_alter(&$output, $context) { * Implements hook_field_widget_form_alter(). */ function field_test_field_widget_form_alter(&$element, &$form_state, $context) { - $instance = $context['instance']; - $entity_form_display = entity_get_form_display($instance['entity_type'], $instance['bundle'], 'default'); - switch ($context['field']['field_name']) { + switch ($context['field_definition']->getFieldName()) { case 'alter_test_text': - drupal_set_message('Field size: ' . $entity_form_display->getWidget($context['field']['field_name'])->getSetting('size')); + drupal_set_message('Field size: ' . $context['widget']->getSetting('size')); break; case 'alter_test_options': - drupal_set_message('Widget type: ' . $entity_form_display->getWidget($context['field']['field_name'])->getPluginId()); + drupal_set_message('Widget type: ' . $context['widget']->getPluginId()); break; } // Set a message if this is for the form displayed to set default value for diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php index 40902f1..5b8675f 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php @@ -210,7 +210,7 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL, // Get the corresponding formatter object. if ($display_options && $display_options['type'] != 'hidden') { $formatter = $this->formatterManager->getInstance(array( - 'instance' => $instance, + 'field_definition' => $instance, 'view_mode' => $this->mode, 'configuration' => $display_options )); diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php index 408b778..393997a 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Form/FieldInstanceEditForm.php @@ -136,6 +136,7 @@ public function validateForm(array &$form, array &$form_state) { $field_name = $this->instance['field_name']; $entity = $form['#entity']; $entity_form_display = $form['#entity_form_display']; + $field = $this->instance->getField(); if (isset($form['instance']['default_value_widget'])) { $element = $form['instance']['default_value_widget']; @@ -144,9 +145,8 @@ public function validateForm(array &$form, array &$form_state) { $items = array(); $entity_form_display->getWidget($this->instance->getField()->id)->extractFormValues($entity, Language::LANGCODE_NOT_SPECIFIED, $items, $element, $form_state); - // Grab the field definition from $form_state. + // Get the field state. $field_state = field_form_get_state($element['#parents'], $field_name, Language::LANGCODE_NOT_SPECIFIED, $form_state); - $field = $field_state['field']; // Validate the value. $errors = array(); diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc index d8da611..746778f 100644 --- a/core/modules/file/file.field.inc +++ b/core/modules/file/file.field.inc @@ -292,7 +292,7 @@ function file_field_delete_revision(EntityInterface $entity, $field, $instance, /** * Implements hook_field_is_empty(). */ -function file_field_is_empty($item, $field) { +function file_field_is_empty($item, $field_type) { return empty($item['fid']); } @@ -317,18 +317,18 @@ function file_field_displayed($item, $field) { /** * Retrieves the upload validators for a file field. * - * @param $field - * A field array. + * @param array $field_settings + * The field settings. * * @return * An array suitable for passing to file_save_upload() or the file field * element's '#upload_validators' property. */ -function file_field_widget_upload_validators($field, $instance) { +function file_field_widget_upload_validators(array $field_settings) { // Cap the upload size according to the PHP limit. $max_filesize = parse_size(file_upload_max_size()); - if (!empty($instance['settings']['max_filesize']) && parse_size($instance['settings']['max_filesize']) < $max_filesize) { - $max_filesize = parse_size($instance['settings']['max_filesize']); + if (!empty($field_settings['max_filesize']) && parse_size($field_settings['max_filesize']) < $max_filesize) { + $max_filesize = parse_size($field_settings['max_filesize']); } $validators = array(); @@ -337,20 +337,18 @@ function file_field_widget_upload_validators($field, $instance) { $validators['file_validate_size'] = array($max_filesize); // Add the extension check if necessary. - if (!empty($instance['settings']['file_extensions'])) { - $validators['file_validate_extensions'] = array($instance['settings']['file_extensions']); + if (!empty($field_settings['file_extensions'])) { + $validators['file_validate_extensions'] = array($field_settings['file_extensions']); } return $validators; } /** - * Determines the URI for a file field instance. + * Determines the URI for a file field. * - * @param $field - * A field array. - * @param $instance - * A field instance array. + * @param array $field_settings + * The field settings. * @param $data * An array of token objects to pass to * \Drupal\Core\Utility\Token::replace(). @@ -360,13 +358,13 @@ function file_field_widget_upload_validators($field, $instance) { * * @see \Drupal\Core\Utility\Token::replace() */ -function file_field_widget_uri($field, $instance, $data = array()) { - $destination = trim($instance['settings']['file_directory'], '/'); +function file_field_widget_uri(array $field_settings, $data = array()) { + $destination = trim($field_settings['file_directory'], '/'); // Replace tokens. $destination = Drupal::token()->replace($destination, $data); - return $field['settings']['uri_scheme'] . '://' . $destination; + return $field_settings['uri_scheme'] . '://' . $destination; } /** @@ -378,9 +376,8 @@ function file_field_widget_value($element, $input = FALSE, $form_state) { if ($input) { // Checkboxes lose their value when empty. // If the display field is present make sure its unchecked value is saved. - $field = field_widget_field($element, $form_state); if (empty($input['display'])) { - $input['display'] = $field['settings']['display_field'] ? 0 : 1; + $input['display'] = $element['#display_field'] ? 0 : 1; } } @@ -449,17 +446,14 @@ function file_field_widget_process($element, &$form_state, $form) { $item = $element['#value']; $item['fids'] = $element['fids']['#value']; - $field = field_widget_field($element, $form_state); - $instance = field_widget_instance($element, $form_state); - $element['#theme'] = 'file_widget'; // Add the display field if enabled. - if (!empty($field['settings']['display_field']) && $item['fids']) { + if ($element['#display_field'] && $item['fids']) { $element['display'] = array( '#type' => empty($item['fids']) ? 'hidden' : 'checkbox', '#title' => t('Include file in display'), - '#value' => isset($item['display']) ? $item['display'] : $field['settings']['display_default'], + '#value' => isset($item['display']) ? $item['display'] : $element['#display_default'], '#attributes' => array('class' => array('file-display')), ); } @@ -471,7 +465,7 @@ function file_field_widget_process($element, &$form_state, $form) { } // Add the description field if enabled. - if (!empty($instance['settings']['description_field']) && $item['fids']) { + if ($element['#description_field'] && $item['fids']) { $config = config('file.settings'); $element['description'] = array( '#type' => $config->get('description.type'), @@ -484,7 +478,7 @@ function file_field_widget_process($element, &$form_state, $form) { // Adjust the Ajax settings so that on upload and remove of any individual // file, the entire group of file fields is updated together. - if ($field['cardinality'] != 1) { + if ($element['#cardinality'] != 1) { $parents = array_slice($element['#array_parents'], 0, -1); $new_path = 'file/ajax/' . implode('/', $parents) . '/' . $form['form_build_id']['#value']; $field_element = NestedArray::getValue($form, $parents); diff --git a/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php b/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php index 4eebf6c..0d9455f 100644 --- a/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php +++ b/core/modules/file/lib/Drupal/file/Plugin/field/widget/FileWidget.php @@ -31,7 +31,7 @@ class FileWidget extends WidgetBase { /** - * Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm(). + * {@inheritdoc} */ public function settingsForm(array $form, array &$form_state) { $element['progress_indicator'] = array( @@ -50,14 +50,12 @@ public function settingsForm(array $form, array &$form_state) { } /** - * Overrides \Drupal\field\Plugin\Type\Widget\WidgetBase::formMultipleElements(). + * {@inheritdoc} * * Special handling for draggable multiple widgets and 'add more' button. */ protected function formMultipleElements(EntityInterface $entity, array $items, $langcode, array &$form, array &$form_state) { - $field = $this->field; - $instance = $this->instance; - $field_name = $field['field_name']; + $field_name = $this->fieldDefinition->getFieldName(); $parents = $form['#parents']; @@ -70,23 +68,24 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $ } // Determine the number of widgets to display. - switch ($field['cardinality']) { + $cardinality = $this->fieldDefinition->getFieldCardinality(); + switch ($cardinality) { case FIELD_CARDINALITY_UNLIMITED: $max = count($items); $is_multiple = TRUE; break; default: - $max = $field['cardinality'] - 1; - $is_multiple = ($field['cardinality'] > 1); + $max = $cardinality - 1; + $is_multiple = ($cardinality > 1); break; } $id_prefix = implode('-', array_merge($parents, array($field_name))); $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper'); - $title = check_plain($instance['label']); - $description = field_filter_xss($instance['description']); + $title = check_plain($this->fieldDefinition->getFieldLabel()); + $description = field_filter_xss($this->fieldDefinition->getFieldDescription()); $elements = array(); @@ -120,8 +119,8 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $ } } - $empty_single_allowed = ($this->field['cardinality'] == 1 && $delta == 0); - $empty_multiple_allowed = ($this->field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $this->field['cardinality']) && empty($form_state['programmed']); + $empty_single_allowed = ($cardinality == 1 && $delta == 0); + $empty_multiple_allowed = ($cardinality == FIELD_CARDINALITY_UNLIMITED || $delta < $cardinality) && empty($form_state['programmed']); // Add one more empty row for new uploads except when this is a programmed // multiple form as it is not necessary. @@ -150,25 +149,25 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $ $elements['#description'] = $description; $elements['#field_name'] = $element['#field_name']; $elements['#language'] = $element['#language']; - $elements['#display_field'] = !empty($this->field['settings']['display_field']); + $elements['#display_field'] = (bool) $this->getFieldSetting('display_field'); // Add some properties that will eventually be added to the file upload // field. These are added here so that they may be referenced easily // through a hook_form_alter(). $elements['#file_upload_title'] = t('Add a new file'); - $elements['#file_upload_description'] = theme('file_upload_help', array('description' => '', 'upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $this->field['cardinality'])); + $elements['#file_upload_description'] = theme('file_upload_help', array('description' => '', 'upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $cardinality)); } return $elements; } /** - * Implements \Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement(). + * {@inheritdoc} */ public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { $defaults = array( 'fids' => array(), - 'display' => !empty($this->field['settings']['display_default']), + 'display' => (bool) $this->getFieldSetting('display_default'), 'description' => '', ); @@ -177,13 +176,19 @@ public function formElement(array $items, $delta, array $element, $langcode, arr $element_info = element_info('managed_file'); $element += array( '#type' => 'managed_file', - '#upload_location' => file_field_widget_uri($this->field, $this->instance), - '#upload_validators' => file_field_widget_upload_validators($this->field, $this->instance), + '#upload_location' => file_field_widget_uri($this->fieldDefinition->getFieldSettings()), + '#upload_validators' => file_field_widget_upload_validators($this->fieldDefinition->getFieldSettings()), '#value_callback' => 'file_field_widget_value', '#process' => array_merge($element_info['#process'], array('file_field_widget_process')), '#progress_indicator' => $this->getSetting('progress_indicator'), // Allows this field to return an array instead of a single value. '#extended' => TRUE, + // Add properties needed by file_field_widget_value() and + // file_field_widget_process(). + '#display_field' => (bool) $this->getFieldSetting('display_field'), + '#display_default' => $this->getFieldSetting('display_default'), + '#description_field' => $this->getFieldSetting('description_field'), + '#cardinality' => $this->fieldDefinition->getFieldCardinality(), ); $element['#weight'] = $delta; @@ -197,7 +202,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr $default_fids = $element['#extended'] ? $element['#default_value']['fids'] : $element['#default_value']; if (empty($default_fids)) { - $cardinality = isset($this->field['cardinality']) ? $this->field['cardinality'] : 1; + $cardinality = $this->fieldDefinition->getFieldCardinality(); $element['#description'] = theme('file_upload_help', array('description' => $element['#description'], 'upload_validators' => $element['#upload_validators'], 'cardinality' => $cardinality)); $element['#multiple'] = $cardinality != 1 ? TRUE : FALSE; if ($cardinality != 1 && $cardinality != -1) { @@ -209,7 +214,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr } /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::massageFormValues(). + * {@inheritdoc} */ public function massageFormValues(array $values, array $form, array &$form_state) { // Since file upload widget now supports uploads of more than one file at a diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc index 705bcf3..524005b 100644 --- a/core/modules/image/image.field.inc +++ b/core/modules/image/image.field.inc @@ -302,8 +302,8 @@ function image_field_delete_revision(EntityInterface $entity, $field, $instance, /** * Implements hook_field_is_empty(). */ -function image_field_is_empty($item, $field) { - return file_field_is_empty($item, $field); +function image_field_is_empty($item, $field_type) { + return file_field_is_empty($item, $field_type); } /** @@ -360,10 +360,6 @@ function image_field_widget_process($element, &$form_state, $form) { ); } - // Get field settings. - $instance = field_widget_instance($element, $form_state); - $settings = $instance['settings']; - // Add the additional alt and title fields. $element['alt'] = array( '#title' => t('Alternate text'), @@ -374,7 +370,7 @@ function image_field_widget_process($element, &$form_state, $form) { '#maxlength' => 512, '#weight' => -2, '#access' => (bool) $item['fids'] && $element['#alt_field'], - '#element_validate' => $settings['alt_field_required'] == 1 ? array('_image_field_required_fields_validate') : array(), + '#element_validate' => $element['#alt_field_required'] == 1 ? array('_image_field_required_fields_validate') : array(), ); $element['title'] = array( '#type' => 'textfield', @@ -384,7 +380,7 @@ function image_field_widget_process($element, &$form_state, $form) { '#maxlength' => 1024, '#weight' => -1, '#access' => (bool) $item['fids'] && $element['#title_field'], - '#element_validate' => $settings['alt_field_required'] == 1 ? array('_image_field_required_fields_validate') : array(), + '#element_validate' => $element['#alt_field_required'] == 1 ? array('_image_field_required_fields_validate') : array(), ); return $element; diff --git a/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php b/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php index 8062ff6..2011e06 100644 --- a/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php +++ b/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php @@ -52,37 +52,38 @@ public function settingsForm(array $form, array &$form_state) { } /** - * Overrides \Drupal\file\Plugin\field\widget\FileWidget::formMultipleElements(). + * {@inheritdoc} * * Special handling for draggable multiple widgets and 'add more' button. */ protected function formMultipleElements(EntityInterface $entity, array $items, $langcode, array &$form, array &$form_state) { $elements = parent::formMultipleElements($entity, $items, $langcode, $form, $form_state); - if ($this->field['cardinality'] == 1) { + $cardinality = $this->fieldDefinition->getFieldCardinality(); + if ($cardinality == 1) { // If there's only one field, return it as delta 0. if (empty($elements[0]['#default_value']['fids'])) { - $elements[0]['#description'] = theme('file_upload_help', array('description' => $this->instance['description'], 'upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $this->field['cardinality'])); + $elements[0]['#description'] = theme('file_upload_help', array('description' => $this->fieldDefinition->getFieldDescription(), 'upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $cardinality)); } } else { - $elements['#file_upload_description'] = theme('file_upload_help', array('upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $this->field['cardinality'])); + $elements['#file_upload_description'] = theme('file_upload_help', array('upload_validators' => $elements[0]['#upload_validators'], 'cardinality' => $cardinality)); } return $elements; } /** - * Overrides \Drupal\file\Plugin\field\widget\FileWidget::formElement(). + * {@inheritdoc} */ public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { $element = parent::formElement($items, $delta, $element, $langcode, $form, $form_state); - $settings = $this->instance['settings']; + $field_settings = $this->fieldDefinition->getFieldSettings(); // Add upload resolution validation. - if ($settings['max_resolution'] || $settings['min_resolution']) { - $element['#upload_validators']['file_validate_image_resolution'] = array($settings['max_resolution'], $settings['min_resolution']); + if ($field_settings['max_resolution'] || $field_settings['min_resolution']) { + $element['#upload_validators']['file_validate_image_resolution'] = array($field_settings['max_resolution'], $field_settings['min_resolution']); } // If not using custom extension validation, ensure this is an image. @@ -95,8 +96,9 @@ public function formElement(array $items, $delta, array $element, $langcode, arr $element['#process'][] = 'image_field_widget_process'; // Add properties needed by image_field_widget_process(). $element['#preview_image_style'] = $this->getSetting('preview_image_style'); - $element['#title_field'] = $settings['title_field']; - $element['#alt_field'] = $settings['alt_field']; + $element['#title_field'] = $field_settings['title_field']; + $element['#alt_field'] = $field_settings['alt_field']; + $element['#alt_field_required'] = $field_settings['alt_field_required']; return $element; } diff --git a/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php b/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php index 0784cae..f960613 100644 --- a/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php +++ b/core/modules/link/lib/Drupal/link/Plugin/field/widget/LinkWidget.php @@ -33,8 +33,6 @@ class LinkWidget extends WidgetBase { * {@inheritdoc} */ public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { - $instance = $this->instance; - $element['url'] = array( '#type' => 'url', '#title' => t('URL'), @@ -49,13 +47,13 @@ public function formElement(array $items, $delta, array $element, $langcode, arr '#placeholder' => $this->getSetting('placeholder_title'), '#default_value' => isset($items[$delta]['title']) ? $items[$delta]['title'] : NULL, '#maxlength' => 255, - '#access' => $instance['settings']['title'] != DRUPAL_DISABLED, + '#access' => $this->getFieldSetting('title') != DRUPAL_DISABLED, ); // Post-process the title field to make it conditionally required if URL is // non-empty. Omit the validation on the field edit form, since the field // settings cannot be saved otherwise. $is_field_edit_form = ($element['#entity'] === NULL); - if (!$is_field_edit_form && $instance['settings']['title'] == DRUPAL_REQUIRED) { + if (!$is_field_edit_form && $this->getFieldSetting('title') == DRUPAL_REQUIRED) { $element['#element_validate'] = array(array($this, 'validateTitle')); } @@ -70,7 +68,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr // If cardinality is 1, ensure a label is output for the field by wrapping it // in a details element. - if ($this->field['cardinality'] == 1) { + if ($this->fieldDefinition->getFieldCardinality() == 1) { $element += array( '#type' => 'fieldset', ); diff --git a/core/modules/link/link.module b/core/modules/link/link.module index 16091f1..bfd6ebf 100644 --- a/core/modules/link/link.module +++ b/core/modules/link/link.module @@ -75,7 +75,7 @@ function link_field_load($entity_type, $entities, $field, $instances, $langcode, /** * Implements hook_field_is_empty(). */ -function link_field_is_empty($item, $field) { +function link_field_is_empty($item, $field_type) { return !isset($item['url']) || $item['url'] === ''; } diff --git a/core/modules/number/lib/Drupal/number/Plugin/field/widget/NumberWidget.php b/core/modules/number/lib/Drupal/number/Plugin/field/widget/NumberWidget.php index 37c857f..95c2f1e 100644 --- a/core/modules/number/lib/Drupal/number/Plugin/field/widget/NumberWidget.php +++ b/core/modules/number/lib/Drupal/number/Plugin/field/widget/NumberWidget.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\number\Plugin\field\widget\NumberWidget. + * Contains \Drupal\number\Plugin\field\widget\NumberWidget. */ namespace Drupal\number\Plugin\field\widget; @@ -31,7 +31,7 @@ class NumberWidget extends WidgetBase { /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm(). + * {@inheritdoc} */ public function settingsForm(array $form, array &$form_state) { $element['placeholder'] = array( @@ -44,12 +44,9 @@ public function settingsForm(array $form, array &$form_state) { } /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement(). + * {@inheritdoc} */ public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { - $field = $this->field; - $instance = $this->instance; - $value = isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL; $element += array( @@ -59,9 +56,9 @@ public function formElement(array $items, $delta, array $element, $langcode, arr ); // Set the step for floating point and decimal numbers. - switch ($field['type']) { + switch ($this->fieldDefinition->getFieldType()) { case 'number_decimal': - $element['#step'] = pow(0.1, $field['settings']['scale']); + $element['#step'] = pow(0.1, $this->getFieldSetting('scale')); break; case 'number_float': @@ -70,20 +67,20 @@ public function formElement(array $items, $delta, array $element, $langcode, arr } // Set minimum and maximum. - if (is_numeric($instance['settings']['min'])) { - $element['#min'] = $instance['settings']['min']; + if (is_numeric($this->getFieldSetting('min'))) { + $element['#min'] = $this->getFieldSetting('min'); } - if (is_numeric($instance['settings']['max'])) { - $element['#max'] = $instance['settings']['max']; + if (is_numeric($this->getFieldSetting('max'))) { + $element['#max'] = $this->getFieldSetting('max'); } // Add prefix and suffix. - if (!empty($instance['settings']['prefix'])) { - $prefixes = explode('|', $instance['settings']['prefix']); + if ($this->getFieldSetting('prefix')) { + $prefixes = explode('|', $this->getFieldSetting('prefix')); $element['#field_prefix'] = field_filter_xss(array_pop($prefixes)); } - if (!empty($instance['settings']['suffix'])) { - $suffixes = explode('|', $instance['settings']['suffix']); + if ($this->getFieldSetting('suffix')) { + $suffixes = explode('|', $this->getFieldSetting('suffix')); $element['#field_suffix'] = field_filter_xss(array_pop($suffixes)); } @@ -91,7 +88,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr } /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::errorElement(). + * {@inheritdoc} */ public function errorElement(array $element, array $error, array $form, array &$form_state) { return $element['value']; diff --git a/core/modules/number/number.module b/core/modules/number/number.module index 4615519..7610639 100644 --- a/core/modules/number/number.module +++ b/core/modules/number/number.module @@ -164,7 +164,7 @@ function number_field_presave(EntityInterface $entity, $field, $instance, $langc /** * Implements hook_field_is_empty(). */ -function number_field_is_empty($item, $field) { +function number_field_is_empty($item, $field_type) { if (empty($item['value']) && (string) $item['value'] !== '0') { return TRUE; } diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsDefaultFormatter.php b/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsDefaultFormatter.php index 01b4efb..3b9c57c 100644 --- a/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsDefaultFormatter.php +++ b/core/modules/options/lib/Drupal/options/Plugin/field/formatter/OptionsDefaultFormatter.php @@ -35,7 +35,7 @@ class OptionsDefaultFormatter extends FormatterBase { public function viewElements(EntityInterface $entity, $langcode, array $items) { $elements = array(); - $allowed_values = options_allowed_values($this->field, $this->instance, $entity); + $allowed_values = options_allowed_values($this->fieldDefinition, $entity); foreach ($items as $delta => $item) { if (isset($allowed_values[$item['value']])) { diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OnOffWidget.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OnOffWidget.php index 7e6b4a5..fd0d230 100644 --- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OnOffWidget.php +++ b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OnOffWidget.php @@ -57,7 +57,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr // Override the title from the incoming $element. if ($this->getSetting('display_label')) { - $element['#title'] = $this->instance['label']; + $element['#title'] = $this->fieldDefinition->getFieldLabel(); } else { $element['#title'] = isset($options[1]) ? $options[1] : ''; diff --git a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php index 6986231..f6801c0 100644 --- a/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php +++ b/core/modules/options/lib/Drupal/options/Plugin/field/widget/OptionsWidgetBase.php @@ -7,7 +7,7 @@ namespace Drupal\options\Plugin\field\widget; -use Drupal\field\Plugin\Core\Entity\FieldInstance; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; use Drupal\field\Plugin\Type\Widget\WidgetBase; /** @@ -36,12 +36,10 @@ /** * {@inheritdoc} */ - public function __construct($plugin_id, array $plugin_definition, FieldInstance $instance, array $settings) { - parent::__construct($plugin_id, $plugin_definition, $instance, $settings); - - // Reset internal pointer since we're dealing with objects now. - reset($this->field['columns']); - $this->column = key($this->field['columns']); + public function __construct($plugin_id, array $plugin_definition, FieldDefinitionInterface $field_definition, array $settings) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings); + $property_names = $this->fieldDefinition->getFieldPropertyNames(); + $this->column = $property_names[0]; } /** @@ -52,7 +50,8 @@ public function formElement(array $items, $delta, array $element, $langcode, arr // element. $this->entity = $element['#entity']; $this->required = $element['#required']; - $this->multiple = ($this->field['cardinality'] == FIELD_CARDINALITY_UNLIMITED) || ($this->field['cardinality'] > 1); + $cardinality = $this->fieldDefinition->getFieldCardinality(); + $this->multiple = ($cardinality == FIELD_CARDINALITY_UNLIMITED) || ($cardinality > 1); $this->has_value = isset($items[0][$this->column]); // Add our custom validator. @@ -115,7 +114,9 @@ protected function getOptions() { $module_handler = \Drupal::moduleHandler(); // Get the list of options from the field type module, and sanitize them. - $options = (array) $module_handler->invoke($this->field['module'], 'options_list', array($this->field, $this->instance, $this->entity)); + $field_type_info = field_info_field_types($this->fieldDefinition->getFieldType()); + $module = $field_type_info['module']; + $options = (array) $module_handler->invoke($module, 'options_list', array($this->fieldDefinition, $this->entity)); // Add an empty option if the widget needs one. if ($empty_option = $this->getEmptyOption()) { @@ -133,8 +134,7 @@ protected function getOptions() { } $context = array( - 'field' => $this->field, - 'instance' => $this->instance, + 'fieldDefinition' => $this->fieldDefinition, 'entity' => $this->entity, ); $module_handler->alter('options_list', $options, $context); diff --git a/core/modules/options/options.api.php b/core/modules/options/options.api.php index a026898..5e8c694 100644 --- a/core/modules/options/options.api.php +++ b/core/modules/options/options.api.php @@ -13,12 +13,8 @@ * implement this hook to specify the list of options to display in the * widgets. * - * @param $field + * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition * The field definition. - * @param $instance - * The instance definition. It is recommended to only use instance level - * properties to filter out values from a list defined by field level - * properties. * @param \Drupal\Core\Entity\EntityInterface $entity * The entity object the field is attached to. * @@ -31,7 +27,7 @@ * widget. The HTML tags defined in _field_filter_xss_allowed_tags() are * allowed, other tags will be filtered. */ -function hook_options_list($field, $instance, $entity) { +function hook_options_list(\Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition, \Drupal\Core\Entity\EntityInterface $entity) { // Sample structure. $options = array( 0 => t('Zero'), @@ -57,7 +53,7 @@ function hook_options_list($field, $instance, $entity) { // In actual implementations, the array of options will most probably depend // on properties of the field. Example from taxonomy.module: $options = array(); - foreach ($field['settings']['allowed_values'] as $tree) { + foreach ($field_definition->getFieldSetting('allowed_values') as $tree) { $terms = taxonomy_get_tree($tree['vid'], $tree['parent'], NULL, TRUE); if ($terms) { foreach ($terms as $term) { @@ -81,10 +77,8 @@ function hook_options_list($field, $instance, $entity) { * * @param array $context * An associative array containing: - * - field: The field definition (\Drupal\field\Plugin\Core\Entity\Field). - * - instance: The instance definition. It is recommended to only use instance - * level properties to filter out values from a list defined by field level - * properties (Drupal\field\Plugin\Core\Entity\FieldInstance). + * - field_definition: The field definition + * (\Drupal\Core\Entity\Field\FieldDefinitionInterface). * - entity: The entity object the field is attached to * (\Drupal\Core\Entity\EntityInterface). * diff --git a/core/modules/options/options.module b/core/modules/options/options.module index 0d8ec00..366433d 100644 --- a/core/modules/options/options.module +++ b/core/modules/options/options.module @@ -7,6 +7,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; use Drupal\field\FieldUpdateForbiddenException; use Drupal\options\Plugin\field\widget\OptionsWidgetBase; @@ -213,9 +214,9 @@ function options_field_settings_form_value_boolean_allowed_values($element, $inp } /** - * Implements hook_field_update_field(). + * Implements hook_field_info_cache_clear(). */ -function options_field_update_field($field, $prior_field, $has_data) { +function options_field_info_cache_clear() { drupal_static_reset('options_allowed_values'); } @@ -225,42 +226,41 @@ function options_field_update_field($field, $prior_field, $has_data) { * The strings are not safe for output. Keys and values of the array should be * sanitized through field_filter_xss() before being displayed. * - * @param $field + * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition * The field definition. - * @param $instance - * (optional) A field instance array. Defaults to NULL. * @param \Drupal\Core\Entity\EntityInterface $entity - * (optional) The entity object. Defaults to NULL. + * 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($field, $instance = NULL, EntityInterface $entity = NULL) { +function options_allowed_values(FieldDefinitionInterface $field_definition, EntityInterface $entity) { $allowed_values = &drupal_static(__FUNCTION__, array()); - if (!isset($allowed_values[$field['uuid']])) { - $function = $field['settings']['allowed_values_function']; + $cache_id = implode(':', array($entity->entityType(), $entity->bundle(), $field_definition->getFieldName())); + if (!isset($allowed_values[$cache_id])) { + $function = $field_definition->getFieldSetting('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, $instance, $entity, $cacheable); + $values = $function($field_definition, $entity, $cacheable); } else { - $values = $field['settings']['allowed_values']; + $values = $field_definition->getFieldSetting('allowed_values'); } if ($cacheable) { - $allowed_values[$field['uuid']] = $values; + $allowed_values[$cache_id] = $values; } else { return $values; } } - return $allowed_values[$field['uuid']]; + return $allowed_values[$cache_id]; } /** @@ -400,7 +400,16 @@ function _options_values_in_use($field, $values) { * - 'list_illegal_value': The value is not part of the list of allowed values. */ function options_field_validate(EntityInterface $entity = NULL, $field, $instance, $langcode, $items, &$errors) { - $allowed_values = options_allowed_values($field, $instance, $entity); + // When configuring a field instance, the default value is validated without + // an entity, but options_allowed_values() and the callback it invokes + // require an entity, because the result can depend on entity type, bundle, + // and other entity data. + if (!isset($entity)) { + $ids = (object) array('entity_type' => $instance->entity_type, 'bundle' => $instance->bundle, 'entity_id' => NULL); + $entity = _field_create_entity_from_ids($ids); + } + + $allowed_values = options_allowed_values($instance, $entity); foreach ($items as $delta => $item) { if (!empty($item['value'])) { if (!empty($allowed_values) && !isset($allowed_values[$item['value']])) { @@ -416,7 +425,7 @@ function options_field_validate(EntityInterface $entity = NULL, $field, $instanc /** * Implements hook_field_is_empty(). */ -function options_field_is_empty($item, $field) { +function options_field_is_empty($item, $field_type) { if (empty($item['value']) && (string) $item['value'] !== '0') { return TRUE; } @@ -426,7 +435,7 @@ function options_field_is_empty($item, $field) { /** * Implements hook_options_list(). */ -function options_options_list($field, $instance, $entity) { - return options_allowed_values($field, $instance, $entity); +function options_options_list(FieldDefinitionInterface $field_definition, EntityInterface $entity) { + return options_allowed_values($field_definition, $entity); } diff --git a/core/modules/options/tests/options_test.module b/core/modules/options/tests/options_test.module index 4ece85c..9346cf0 100644 --- a/core/modules/options/tests/options_test.module +++ b/core/modules/options/tests/options_test.module @@ -6,11 +6,12 @@ */ use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; /** * Allowed values callback. */ -function options_test_allowed_values_callback($field, $instance, $entity) { +function options_test_allowed_values_callback(FieldDefinitionInterface $field_definition, EntityInterface $entity) { $values = array( 'Group 1' => array( 0 => 'Zero', @@ -27,7 +28,7 @@ function options_test_allowed_values_callback($field, $instance, $entity) { /** * An entity-bound allowed values callback. */ -function options_test_dynamic_values_callback($field, $instance, EntityInterface $entity, &$cacheable) { +function options_test_dynamic_values_callback(FieldDefinitionInterface $field_definition, EntityInterface $entity, &$cacheable) { $cacheable = FALSE; // We need the values of the entity as keys. $uri = $entity->uri(); diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php index 01a01fa..c0ef1f6 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Plugin/field/widget/TaxonomyAutocompleteWidget.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\taxonomy\Plugin\field\widget\TaxonomyAutocompleteWidget. + * Contains \Drupal\taxonomy\Plugin\field\widget\TaxonomyAutocompleteWidget. */ namespace Drupal\taxonomy\Plugin\field\widget; @@ -32,7 +32,7 @@ class TaxonomyAutocompleteWidget extends WidgetBase { /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm(). + * {@inheritdoc} */ public function settingsForm(array $form, array &$form_state) { $element['placeholder'] = array( @@ -45,11 +45,9 @@ public function settingsForm(array $form, array &$form_state) { } /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement(). + * {@inheritdoc} */ public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { - $field = $this->field; - $tags = array(); foreach ($items as $item) { $tags[$item['tid']] = isset($item['taxonomy_term']) ? $item['taxonomy_term'] : taxonomy_term_load($item['tid']); @@ -57,7 +55,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr $element += array( '#type' => 'textfield', '#default_value' => taxonomy_implode_tags($tags), - '#autocomplete_path' => $this->getSetting('autocomplete_path') . '/' . $field['field_name'], + '#autocomplete_path' => $this->getSetting('autocomplete_path') . '/' . $this->fieldDefinition->getFieldName(), '#size' => $this->getSetting('size'), '#placeholder' => $this->getSetting('placeholder'), '#maxlength' => 1024, @@ -68,16 +66,15 @@ public function formElement(array $items, $delta, array $element, $langcode, arr } /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::massageFormValues() + * {@inheritdoc} */ public function massageFormValues(array $values, array $form, array &$form_state) { // Autocomplete widgets do not send their tids in the form, so we must detect // them here and process them independently. $items = array(); - $field = $this->field; // Collect candidate vocabularies. - foreach ($field['settings']['allowed_values'] as $tree) { + foreach ($this->getFieldSetting('allowed_values') as $tree) { if ($vocabulary = entity_load('taxonomy_vocabulary', $tree['vocabulary'])) { $vocabularies[$vocabulary->id()] = $vocabulary; } diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index 6ed67a1..eea62ad 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -9,6 +9,7 @@ use Drupal\taxonomy\Plugin\Core\Entity\Term; use Drupal\taxonomy\Plugin\Core\Entity\Vocabulary; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; /** * Denotes that no term in the vocabulary has a parent. @@ -926,9 +927,9 @@ function taxonomy_field_widget_info_alter(&$info) { /** * Implements hook_options_list(). */ -function taxonomy_options_list($field, $instance, $entity) { - $function = !empty($field['settings']['options_list_callback']) ? $field['settings']['options_list_callback'] : 'taxonomy_allowed_values'; - return $function($field, $instance, $entity); +function taxonomy_options_list(FieldDefinitionInterface $field_definition, EntityInterface $entity) { + $function = $field_definition->getFieldSetting('options_list_callback') ?: 'taxonomy_allowed_values'; + return $function($field_definition, $entity); } /** @@ -993,28 +994,24 @@ function taxonomy_field_validate(EntityInterface $entity = NULL, $field, $instan /** * Implements hook_field_is_empty(). */ -function taxonomy_field_is_empty($item, $field) { +function taxonomy_field_is_empty($item, $field_type) { return !is_array($item) || (empty($item['tid']) && empty($item['entity'])); } /** * Returns the set of valid terms for a taxonomy field. * - * @param $field + * @param \Drupal\Core\Entity\Field\FieldDefinitionInterface $field_definition * The field definition. - * @param $instance - * The instance definition. It is recommended to only use instance level - * properties to filter out values from a list defined by field level - * properties. * @param \Drupal\Core\Entity\EntityInterface $entity * The entity object the field is attached to. * * @return * The array of valid terms for this field, keyed by term id. */ -function taxonomy_allowed_values($field, $instance, EntityInterface $entity) { +function taxonomy_allowed_values(FieldDefinitionInterface $field_definition, EntityInterface $entity) { $options = array(); - foreach ($field['settings']['allowed_values'] as $tree) { + foreach ($field_definition->getFieldSetting('allowed_values') as $tree) { if ($vocabulary = taxonomy_vocabulary_load($tree['vocabulary'])) { if ($terms = taxonomy_get_tree($vocabulary->id(), $tree['parent'], NULL, TRUE)) { foreach ($terms as $term) { diff --git a/core/modules/telephone/telephone.module b/core/modules/telephone/telephone.module index 61a39f4..5033bbc 100644 --- a/core/modules/telephone/telephone.module +++ b/core/modules/telephone/telephone.module @@ -32,7 +32,7 @@ function telephone_field_info_alter(&$info) { /** * Implements hook_field_is_empty(). */ -function telephone_field_is_empty($item, $field) { +function telephone_field_is_empty($item, $field_type) { return !isset($item['value']) || $item['value'] === ''; } diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php index 4a96cc3..0d76811 100644 --- a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php +++ b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextDefaultFormatter.php @@ -38,7 +38,7 @@ public function viewElements(EntityInterface $entity, $langcode, array $items) { $elements = array(); foreach ($items as $delta => $item) { - $output = text_sanitize($this->instance['settings']['text_processing'], $langcode, $item, 'value'); + $output = text_sanitize($this->getFieldSetting('text_processing'), $langcode, $item, 'value'); $elements[$delta] = array('#markup' => $output); } diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextTrimmedFormatter.php b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextTrimmedFormatter.php index 4be366d..fa33b74 100644 --- a/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextTrimmedFormatter.php +++ b/core/modules/text/lib/Drupal/text/Plugin/field/formatter/TextTrimmedFormatter.php @@ -70,11 +70,11 @@ public function viewElements(EntityInterface $entity, $langcode, array $items) { foreach ($items as $delta => $item) { if ($this->getPluginId() == 'text_summary_or_trimmed' && !empty($item['summary'])) { - $output = text_sanitize($this->instance['settings']['text_processing'], $langcode, $item, 'summary'); + $output = text_sanitize($this->getFieldSetting('text_processing'), $langcode, $item, 'summary'); } else { - $output = text_sanitize($this->instance['settings']['text_processing'], $langcode, $item, 'value'); - $output = text_summary($output, $this->instance['settings']['text_processing'] ? $item['format'] : NULL, $this->getSetting('trim_length')); + $output = text_sanitize($this->getFieldSetting('text_processing'), $langcode, $item, 'value'); + $output = text_summary($output, $this->getFieldSetting('text_processing') ? $item['format'] : NULL, $this->getSetting('trim_length')); } $elements[$delta] = array('#markup' => $output); } diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWidget.php b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWidget.php index 496ea12..2fe37a0 100644 --- a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWidget.php +++ b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWidget.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\text\Plugin\field\widget\TextareaWidget. + * Contains \Drupal\text\Plugin\field\widget\TextareaWidget. */ namespace Drupal\text\Plugin\field\widget; @@ -30,7 +30,7 @@ class TextareaWidget extends WidgetBase { /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm(). + * {@inheritdoc} */ public function settingsForm(array $form, array &$form_state) { $element['rows'] = array( @@ -50,7 +50,7 @@ public function settingsForm(array $form, array &$form_state) { } /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement(). + * {@inheritdoc} */ public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { $main_widget = $element + array( @@ -61,7 +61,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr '#attributes' => array('class' => array('text-full')), ); - if ($this->instance['settings']['text_processing']) { + if ($this->getFieldSetting('text_processing')) { $element = $main_widget; $element['#type'] = 'text_format'; $element['#format'] = isset($items[$delta]['format']) ? $items[$delta]['format'] : NULL; diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWithSummaryWidget.php b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWithSummaryWidget.php index b3a68ac..b98ce32 100644 --- a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWithSummaryWidget.php +++ b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextareaWithSummaryWidget.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\text\Plugin\field\widget\TextareaWithSummaryWidget. + * Contains \Drupal\text\Plugin\field\widget\TextareaWithSummaryWidget. */ namespace Drupal\text\Plugin\field\widget; @@ -30,12 +30,12 @@ class TextareaWithSummaryWidget extends TextareaWidget { /** - * Overrides TextareaWidget::formElement(). + * {@inheritdoc} */ function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { $element = parent::formElement($items, $delta, $element, $langcode, $form, $form_state); - $display_summary = !empty($items[$delta]['summary']) || $this->instance['settings']['display_summary']; + $display_summary = !empty($items[$delta]['summary']) || $this->getFieldSetting('display_summary'); $element['summary'] = array( '#type' => $display_summary ? 'textarea' : 'value', '#default_value' => isset($items[$delta]['summary']) ? $items[$delta]['summary'] : NULL, @@ -55,7 +55,7 @@ function formElement(array $items, $delta, array $element, $langcode, array &$fo } /** - * Overrides TextareaWidget::errorElement(). + * {@inheritdoc} */ public function errorElement(array $element, array $error, array $form, array &$form_state) { switch ($error['error']) { diff --git a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextfieldWidget.php b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextfieldWidget.php index a6e26b7..7012c75 100644 --- a/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextfieldWidget.php +++ b/core/modules/text/lib/Drupal/text/Plugin/field/widget/TextfieldWidget.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\text\Plugin\field\widget\TextfieldWidget. + * Contains \Drupal\text\Plugin\field\widget\TextfieldWidget. */ namespace Drupal\text\Plugin\field\widget; @@ -30,7 +30,7 @@ class TextfieldWidget extends WidgetBase { /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::settingsForm(). + * {@inheritdoc} */ public function settingsForm(array $form, array &$form_state) { $element['size'] = array( @@ -50,7 +50,7 @@ public function settingsForm(array $form, array &$form_state) { } /** - * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement(). + * {@inheritdoc} */ public function formElement(array $items, $delta, array $element, $langcode, array &$form, array &$form_state) { $main_widget = $element + array( @@ -58,11 +58,11 @@ public function formElement(array $items, $delta, array $element, $langcode, arr '#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL, '#size' => $this->getSetting('size'), '#placeholder' => $this->getSetting('placeholder'), - '#maxlength' => $this->field['settings']['max_length'], + '#maxlength' => $this->getFieldSetting('max_length'), '#attributes' => array('class' => array('text-full')), ); - if ($this->instance['settings']['text_processing']) { + if ($this->getFieldSetting('text_processing')) { $element = $main_widget; $element['#type'] = 'text_format'; $element['#format'] = isset($items[$delta]['format']) ? $items[$delta]['format'] : NULL; diff --git a/core/modules/text/text.module b/core/modules/text/text.module index 4fe2115..3869458 100644 --- a/core/modules/text/text.module +++ b/core/modules/text/text.module @@ -191,7 +191,7 @@ function text_field_load($entity_type, $entities, $field, $instances, $langcode, /** * Implements hook_field_is_empty(). */ -function text_field_is_empty($item, $field) { +function text_field_is_empty($item, $field_type) { if (!isset($item['value']) || $item['value'] === '') { return !isset($item['summary']) || $item['summary'] === ''; } diff --git a/core/modules/translation_entity/translation_entity.admin.inc b/core/modules/translation_entity/translation_entity.admin.inc index dd7874c..6a4c0da 100644 --- a/core/modules/translation_entity/translation_entity.admin.inc +++ b/core/modules/translation_entity/translation_entity.admin.inc @@ -593,7 +593,7 @@ function _translation_entity_update_field($entity_type, EntityInterface $entity, // Ensure that we are trying to store only valid data. foreach ($entity->{$field_name} as $langcode => $items) { - $entity->{$field_name}[$langcode] = _field_filter_items($field, $entity->{$field_name}[$langcode]); + $entity->{$field_name}[$langcode] = _field_filter_items($field['type'], $entity->{$field_name}[$langcode]); $empty += empty($entity->{$field_name}[$langcode]); } diff --git a/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php b/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php index f872f7d..575c000 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php +++ b/core/modules/views/lib/Drupal/views/Plugin/entity_reference/selection/ViewsSelection.php @@ -11,6 +11,7 @@ use Drupal\Core\Annotation\Translation; use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\Field\FieldDefinitionInterface; use Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface; /** @@ -27,6 +28,20 @@ class ViewsSelection implements SelectionInterface { /** + * The field definition. + * + * @var \Drupal\Core\Entity\Field\FieldDefinitionInterface + */ + protected $fieldDefinition; + + /** + * The entity object, or NULL + * + * @var NULL|EntityInterface + */ + protected $entity; + + /** * The loaded View object. * * @var \Drupal\views\ViewExecutable; @@ -36,9 +51,8 @@ class ViewsSelection implements SelectionInterface { /** * Constructs a View selection handler. */ - public function __construct($field, $instance = NULL, EntityInterface $entity = NULL) { - $this->field = $field; - $this->instance = $instance; + public function __construct(FieldDefinitionInterface $field_definition, EntityInterface $entity = NULL) { + $this->fieldDefinition = $field_definition; $this->entity = $entity; } @@ -117,13 +131,14 @@ public static function settingsForm(&$field, &$instance) { * Return TRUE if the view was initialized, FALSE otherwise. */ protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $limit = 0, $ids = NULL) { - $view_name = $this->instance['settings']['handler_settings']['view']['view_name']; - $display_name = $this->instance['settings']['handler_settings']['view']['display_name']; + $handler_settings = $this->fieldDefinition->getFieldSetting('handler_settings'); + $view_name = $handler_settings['view']['view_name']; + $display_name = $handler_settings['view']['display_name']; // Check that the view is valid and the display still exists. $this->view = views_get_view($view_name); if (!$this->view || !$this->view->access($display_name)) { - drupal_set_message(t('The reference view %view_name used in the %field_name field cannot be found.', array('%view_name' => $view_name, '%field_name' => $this->instance['label'])), 'warning'); + drupal_set_message(t('The reference view %view_name used in the %field_name field cannot be found.', array('%view_name' => $view_name, '%field_name' => $this->fieldDefinition->getFieldLabel())), 'warning'); return FALSE; } $this->view->setDisplay($display_name); @@ -143,8 +158,9 @@ protected function initializeView($match = NULL, $match_operator = 'CONTAINS', $ * Implements \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface::getReferencableEntities(). */ public function getReferencableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) { - $display_name = $this->instance['settings']['handler_settings']['view']['display_name']; - $arguments = $this->instance['settings']['handler_settings']['view']['arguments']; + $handler_settings = $this->fieldDefinition->getFieldSetting('handler_settings'); + $display_name = $handler_settings['view']['display_name']; + $arguments = $handler_settings['view']['arguments']; $result = array(); if ($this->initializeView($match, $match_operator, $limit)) { // Get the results. @@ -173,8 +189,9 @@ public function countReferencableEntities($match = NULL, $match_operator = 'CONT * Implements \Drupal\entity_reference\Plugin\Type\Selection\SelectionInterface::validateReferencableEntities(). */ public function validateReferencableEntities(array $ids) { - $display_name = $this->instance['settings']['handler_settings']['view']['display_name']; - $arguments = $this->instance['settings']['handler_settings']['view']['arguments']; + $handler_settings = $this->fieldDefinition->getFieldSetting('handler_settings'); + $display_name = $handler_settings['view']['display_name']; + $arguments = $handler_settings['view']['arguments']; $result = array(); if ($this->initializeView(NULL, 'CONTAINS', 0, $ids)) { // Get the results.