View source
<?php
namespace Drupal\Core\Field;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\Plugin\DataType\ItemList;
class FieldItemList extends ItemList implements FieldItemListInterface {
protected $list = [];
protected $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
protected function createItem($offset = 0, $value = NULL) {
return \Drupal::service('plugin.manager.field.field_type')
->createFieldItem($this, $offset, $value);
}
public function getEntity() {
return $this
->getParent()
->getValue();
}
public function setLangcode($langcode) {
$this->langcode = $langcode;
}
public function getLangcode() {
return $this->langcode;
}
public function getFieldDefinition() {
return $this->definition;
}
public function getSettings() {
return $this->definition
->getSettings();
}
public function getSetting($setting_name) {
return $this->definition
->getSetting($setting_name);
}
public function filterEmptyItems() {
$this
->filter(function ($item) {
return !$item
->isEmpty();
});
return $this;
}
public function setValue($values, $notify = TRUE) {
if (isset($values) && (!is_array($values) || !empty($values) && !is_numeric(current(array_keys($values))))) {
$values = [
0 => $values,
];
}
parent::setValue($values, $notify);
}
public function __get($property_name) {
if ($item = $this
->first()) {
return $item
->__get($property_name);
}
}
public function __set($property_name, $value) {
$item = $this
->first() ?: $this
->appendItem();
$item
->__set($property_name, $value);
}
public function __isset($property_name) {
if ($item = $this
->first()) {
return $item
->__isset($property_name);
}
return FALSE;
}
public function __unset($property_name) {
if ($item = $this
->first()) {
$item
->__unset($property_name);
}
}
public function access($operation = 'view', AccountInterface $account = NULL, $return_as_object = FALSE) {
$access_control_handler = \Drupal::entityTypeManager()
->getAccessControlHandler($this
->getEntity()
->getEntityTypeId());
return $access_control_handler
->fieldAccess($operation, $this
->getFieldDefinition(), $account, $this, $return_as_object);
}
public function defaultAccess($operation = 'view', AccountInterface $account = NULL) {
return AccessResult::allowed();
}
public function applyDefaultValue($notify = TRUE) {
if ($value = $this
->getFieldDefinition()
->getDefaultValue($this
->getEntity())) {
$this
->setValue($value, $notify);
}
else {
$item = $this
->first() ?: $this
->appendItem();
$item
->applyDefaultValue(FALSE);
$this
->filterEmptyItems();
}
return $this;
}
public function preSave() {
$this
->filterEmptyItems();
$this
->delegateMethod('preSave');
}
public function postSave($update) {
$result = $this
->delegateMethod('postSave', $update);
return (bool) array_filter($result);
}
public function delete() {
$this
->delegateMethod('delete');
}
public function deleteRevision() {
$this
->delegateMethod('deleteRevision');
}
protected function delegateMethod($method) {
$result = [];
$args = array_slice(func_get_args(), 1);
foreach ($this->list as $delta => $item) {
$result[$delta] = $args ? call_user_func_array([
$item,
$method,
], $args) : $item
->{$method}();
}
return $result;
}
public function view($display_options = []) {
$view_builder = \Drupal::entityTypeManager()
->getViewBuilder($this
->getEntity()
->getEntityTypeId());
return $view_builder
->viewField($this, $display_options);
}
public function generateSampleItems($count = 1) {
$field_definition = $this
->getFieldDefinition();
$field_type_class = $field_definition
->getItemDefinition()
->getClass();
for ($delta = 0; $delta < $count; $delta++) {
$values[$delta] = $field_type_class::generateSampleValue($field_definition);
}
$this
->setValue($values);
}
public function getConstraints() {
$constraints = parent::getConstraints();
$cardinality = $this
->getFieldDefinition()
->getFieldStorageDefinition()
->getCardinality();
if ($cardinality != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
$constraints[] = $this
->getTypedDataManager()
->getValidationConstraintManager()
->create('Count', [
'max' => $cardinality,
'maxMessage' => t('%name: this field cannot hold more than @count values.', [
'%name' => $this
->getFieldDefinition()
->getLabel(),
'@count' => $cardinality,
]),
]);
}
return $constraints;
}
public function defaultValuesForm(array &$form, FormStateInterface $form_state) {
if (empty($this
->getFieldDefinition()
->getDefaultValueCallback())) {
if ($widget = $this
->defaultValueWidget($form_state)) {
$element = [
'#parents' => [
'default_value_input',
],
];
$element += $widget
->form($this, $element, $form_state);
return $element;
}
else {
return [
'#markup' => $this
->t('No widget available for: %type.', [
'%type' => $this
->getFieldDefinition()
->getType(),
]),
];
}
}
}
public function defaultValuesFormValidate(array $element, array &$form, FormStateInterface $form_state) {
if ($widget = $this
->defaultValueWidget($form_state)) {
$widget
->extractFormValues($this, $element, $form_state);
$this
->getFieldDefinition()
->setRequired(FALSE);
$violations = $this
->validate();
if (count($violations)) {
$widget
->flagErrors($this, $violations, $element, $form_state);
}
}
}
public function defaultValuesFormSubmit(array $element, array &$form, FormStateInterface $form_state) {
if ($widget = $this
->defaultValueWidget($form_state)) {
$widget
->extractFormValues($this, $element, $form_state);
return $this
->getValue();
}
return [];
}
public static function processDefaultValue($default_value, FieldableEntityInterface $entity, FieldDefinitionInterface $definition) {
return $default_value;
}
protected function defaultValueWidget(FormStateInterface $form_state) {
if (!$form_state
->has('default_value_widget')) {
$entity = $this
->getEntity();
$definition = $this
->getFieldDefinition();
$definition
->setRequired(FALSE);
$definition
->setDescription('');
$entity_form_display = \Drupal::service('entity_display.repository')
->getFormDisplay($entity
->getEntityTypeId(), $entity
->bundle());
$widget = $entity_form_display
->getRenderer($this
->getFieldDefinition()
->getName());
if (!$widget) {
$widget = \Drupal::service('plugin.manager.field.widget')
->getInstance([
'field_definition' => $this
->getFieldDefinition(),
]);
}
$form_state
->set('default_value_widget', $widget);
}
return $form_state
->get('default_value_widget');
}
public function equals(FieldItemListInterface $list_to_compare) {
$count1 = count($this);
$count2 = count($list_to_compare);
if ($count1 === 0 && $count2 === 0) {
return TRUE;
}
if ($count1 !== $count2) {
return FALSE;
}
$value1 = $this
->getValue();
$value2 = $list_to_compare
->getValue();
if ($value1 === $value2) {
return TRUE;
}
$property_definitions = $this
->getFieldDefinition()
->getFieldStorageDefinition()
->getPropertyDefinitions();
$non_computed_properties = array_filter($property_definitions, function (DataDefinitionInterface $property) {
return !$property
->isComputed();
});
$callback = function (&$value) use ($non_computed_properties) {
if (is_array($value)) {
$value = array_intersect_key($value, $non_computed_properties);
$value = array_filter($value, function ($property) {
return $property !== NULL;
});
ksort($value);
}
};
array_walk($value1, $callback);
array_walk($value2, $callback);
return $value1 == $value2;
}
public function hasAffectingChanges(FieldItemListInterface $original_items, $langcode) {
return !$this
->equals($original_items);
}
}