Update to drupal 8.0.0-rc1. For more information, see https://www.drupal.org/node/2582663
This commit is contained in:
parent
eb34d130a8
commit
f32e58e4b1
8476 changed files with 211648 additions and 170042 deletions
|
@ -10,9 +10,9 @@ namespace Drupal\Core\Field;
|
|||
* Useful methods when dealing with displaying allowed tags.
|
||||
*
|
||||
* @deprecated in Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
|
||||
* \Drupal\Core\Field\FieldFilteredString instead.
|
||||
* \Drupal\Core\Field\FieldFilteredMarkup instead.
|
||||
*
|
||||
* @see \Drupal\Core\Field\FieldFilteredString
|
||||
* @see \Drupal\Core\Field\FieldFilteredMarkup
|
||||
*/
|
||||
trait AllowedTagsXssTrait {
|
||||
|
||||
|
@ -24,7 +24,7 @@ trait AllowedTagsXssTrait {
|
|||
*
|
||||
* Used for items entered by administrators, like field descriptions, allowed
|
||||
* values, where some (mainly inline) mark-up may be desired (so
|
||||
* \Drupal\Component\Utility\SafeMarkup::checkPlain() is not acceptable).
|
||||
* \Drupal\Component\Utility\Html::escape() is not acceptable).
|
||||
*
|
||||
* @param string $string
|
||||
* The string with raw HTML in it.
|
||||
|
@ -34,21 +34,21 @@ trait AllowedTagsXssTrait {
|
|||
* valid UTF-8.
|
||||
*/
|
||||
public function fieldFilterXss($string) {
|
||||
return FieldFilteredString::create($string);
|
||||
return FieldFilteredMarkup::create($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of tags allowed by AllowedTagsXssTrait::fieldFilterXss().
|
||||
*/
|
||||
public function allowedTags() {
|
||||
return FieldFilteredString::allowedTags();
|
||||
return FieldFilteredMarkup::allowedTags();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable list of allowed tags for display in help texts.
|
||||
*/
|
||||
public function displayAllowedTags() {
|
||||
return FieldFilteredString::displayAllowedTags();
|
||||
return FieldFilteredMarkup::displayAllowedTags();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -146,16 +146,36 @@ class BaseFieldDefinition extends ListDataDefinition implements FieldDefinitionI
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets field settings.
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param array $settings
|
||||
* The value to set.
|
||||
* Note that the method does not unset existing settings not specified in the
|
||||
* incoming $settings array.
|
||||
*
|
||||
* @return static
|
||||
* The object itself for chaining.
|
||||
* For example:
|
||||
* @code
|
||||
* // Given these are the default settings.
|
||||
* $field_definition->getSettings() === [
|
||||
* 'fruit' => 'apple',
|
||||
* 'season' => 'summer',
|
||||
* ];
|
||||
* // Change only the 'fruit' setting.
|
||||
* $field_definition->setSettings(['fruit' => 'banana']);
|
||||
* // The 'season' setting persists unchanged.
|
||||
* $field_definition->getSettings() === [
|
||||
* 'fruit' => 'banana',
|
||||
* 'season' => 'summer',
|
||||
* ];
|
||||
* @endcode
|
||||
*
|
||||
* For clarity, it is preferred to use setSetting() if not all available
|
||||
* settings are supplied.
|
||||
*/
|
||||
public function setSettings(array $settings) {
|
||||
$this->getItemDefinition()->setSettings($settings);
|
||||
// Assign settings individiually, in order to keep the current values
|
||||
// of settings not specified in $settings.
|
||||
foreach ($settings as $setting_name => $setting) {
|
||||
$this->getItemDefinition()->setSetting($setting_name, $setting);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -167,15 +187,7 @@ class BaseFieldDefinition extends ListDataDefinition implements FieldDefinitionI
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets a field setting.
|
||||
*
|
||||
* @param string $setting_name
|
||||
* The field setting to set.
|
||||
* @param mixed $value
|
||||
* The value to set.
|
||||
*
|
||||
* @return static
|
||||
* The object itself for chaining.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSetting($setting_name, $value) {
|
||||
$this->getItemDefinition()->setSetting($setting_name, $value);
|
||||
|
@ -427,16 +439,30 @@ class BaseFieldDefinition extends ListDataDefinition implements FieldDefinitionI
|
|||
return isset($this->definition['display'][$display_context]['configurable']) ? $this->definition['display'][$display_context]['configurable'] : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefaultValueLiteral() {
|
||||
return isset($this->definition['default_value']) ? $this->definition['default_value'] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefaultValueCallback() {
|
||||
return isset($this->definition['default_value_callback']) ? $this->definition['default_value_callback'] : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefaultValue(FieldableEntityInterface $entity) {
|
||||
// Allow custom default values function.
|
||||
if (!empty($this->definition['default_value_callback'])) {
|
||||
$value = call_user_func($this->definition['default_value_callback'], $entity, $this);
|
||||
if ($callback = $this->getDefaultValueCallback()) {
|
||||
$value = call_user_func($callback, $entity, $this);
|
||||
}
|
||||
else {
|
||||
$value = isset($this->definition['default_value']) ? $this->definition['default_value'] : NULL;
|
||||
$value = $this->getDefaultValueLiteral();
|
||||
}
|
||||
// Normalize into the "array keyed by delta" format.
|
||||
if (isset($value) && !is_array($value)) {
|
||||
|
@ -452,22 +478,27 @@ class BaseFieldDefinition extends ListDataDefinition implements FieldDefinitionI
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets a custom default value callback.
|
||||
*
|
||||
* If set, the callback overrides any set default value.
|
||||
*
|
||||
* @param string|null $callback
|
||||
* The callback to invoke for getting the default value (pass NULL to unset
|
||||
* a previously set callback). The callback will be invoked with the
|
||||
* following arguments:
|
||||
* - \Drupal\Core\Entity\FieldableEntityInterface $entity
|
||||
* The entity being created.
|
||||
* - \Drupal\Core\Field\FieldDefinitionInterface $definition
|
||||
* The field definition.
|
||||
* It should return the default value in the format accepted by the
|
||||
* setDefaultValue() method.
|
||||
*
|
||||
* @return $this
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDefaultValue($value) {
|
||||
if ($value === NULL) {
|
||||
$value = [];
|
||||
}
|
||||
// Unless the value is an empty array, we may need to transform it.
|
||||
if (!is_array($value) || !empty($value)) {
|
||||
if (!is_array($value)) {
|
||||
$value = array(array($this->getMainPropertyName() => $value));
|
||||
}
|
||||
elseif (is_array($value) && !is_numeric(array_keys($value)[0])) {
|
||||
$value = array(0 => $value);
|
||||
}
|
||||
}
|
||||
$this->definition['default_value'] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDefaultValueCallback($callback) {
|
||||
if (isset($callback) && !is_string($callback)) {
|
||||
|
@ -477,38 +508,6 @@ class BaseFieldDefinition extends ListDataDefinition implements FieldDefinitionI
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a default value.
|
||||
*
|
||||
* Note that if a default value callback is set, it will take precedence over
|
||||
* any value set here.
|
||||
*
|
||||
* @param mixed $value
|
||||
* The default value for the field. This can be either:
|
||||
* - a literal, in which case it will be assigned to the first property of
|
||||
* the first item.
|
||||
* - a numerically indexed array of items, each item being a property/value
|
||||
* array.
|
||||
* - a non-numerically indexed array, in which case the array is assumed to
|
||||
* be a property/value array and used as the first item
|
||||
* - NULL or array() for no default value.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultValue($value) {
|
||||
// Unless the value is NULL or an empty array, we may need to transform it.
|
||||
if (!(is_null($value) || (is_array($value) && empty($value)))) {
|
||||
if (!is_array($value)) {
|
||||
$value = array(array($this->getMainPropertyName() => $value));
|
||||
}
|
||||
elseif (!is_numeric(array_keys($value)[0])) {
|
||||
$value = array(0 => $value);
|
||||
}
|
||||
}
|
||||
$this->definition['default_value'] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -163,8 +163,7 @@ class BaseFieldOverride extends FieldConfigBase {
|
|||
* {@inheritdoc}
|
||||
*
|
||||
* @throws \Drupal\Core\Field\FieldException
|
||||
* If the bundle is being changed and
|
||||
* BaseFieldOverride::allowBundleRename() has not been called.
|
||||
* If the bundle is being changed.
|
||||
*/
|
||||
public function preSave(EntityStorageInterface $storage) {
|
||||
// Filter out unknown settings and make sure all settings are present, so
|
||||
|
@ -189,7 +188,7 @@ class BaseFieldOverride extends FieldConfigBase {
|
|||
if ($this->entity_type != $this->original->entity_type) {
|
||||
throw new FieldException("Cannot change the entity_type of an existing base field bundle override (entity type:{$this->entity_type}, bundle:{$this->original->bundle}, field name: {$this->field_name})");
|
||||
}
|
||||
if ($this->bundle != $this->original->bundle && empty($this->bundleRenameAllowed)) {
|
||||
if ($this->bundle != $this->original->bundle) {
|
||||
throw new FieldException("Cannot change the bundle of an existing base field bundle override (entity type:{$this->entity_type}, bundle:{$this->original->bundle}, field name: {$this->field_name})");
|
||||
}
|
||||
$previous_definition = $this->original;
|
||||
|
|
|
@ -27,12 +27,12 @@ class EntityReferenceFieldItemList extends FieldItemList implements EntityRefere
|
|||
// "autocreate" entities that are already populated in $item->entity.
|
||||
$target_entities = $ids = array();
|
||||
foreach ($this->list as $delta => $item) {
|
||||
if ($item->hasNewEntity()) {
|
||||
$target_entities[$delta] = $item->entity;
|
||||
}
|
||||
elseif ($item->target_id !== NULL) {
|
||||
if ($item->target_id !== NULL) {
|
||||
$ids[$delta] = $item->target_id;
|
||||
}
|
||||
elseif ($item->hasNewEntity()) {
|
||||
$target_entities[$delta] = $item->entity;
|
||||
}
|
||||
}
|
||||
|
||||
// Load and add the existing entities.
|
||||
|
@ -104,7 +104,13 @@ class EntityReferenceFieldItemList extends FieldItemList implements EntityRefere
|
|||
// Convert numeric IDs to UUIDs to ensure config deployability.
|
||||
$ids = array();
|
||||
foreach ($default_value as $delta => $properties) {
|
||||
$ids[] = $properties['target_id'];
|
||||
if (isset($properties['entity']) && $properties['entity']->isNew()) {
|
||||
// This may be a newly created term.
|
||||
$properties['entity']->save();
|
||||
$default_value[$delta]['target_id'] = $properties['entity']->id();
|
||||
unset($default_value[$delta]['entity']);
|
||||
}
|
||||
$ids[] = $default_value[$delta]['target_id'];
|
||||
}
|
||||
$entities = \Drupal::entityManager()
|
||||
->getStorage($this->getSetting('target_type'))
|
||||
|
|
|
@ -145,7 +145,7 @@ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigIn
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public $default_value = array();
|
||||
protected $default_value = array();
|
||||
|
||||
/**
|
||||
* The name of a callback function that returns default values.
|
||||
|
@ -179,13 +179,6 @@ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigIn
|
|||
*/
|
||||
protected $itemDefinition;
|
||||
|
||||
/**
|
||||
* Flag indicating whether the bundle name can be renamed or not.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $bundleRenameAllowed = FALSE;
|
||||
|
||||
/**
|
||||
* Array of constraint options keyed by constraint plugin ID.
|
||||
*
|
||||
|
@ -252,7 +245,7 @@ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigIn
|
|||
$bundle_config_dependency = $this->entityManager()->getDefinition($this->entity_type)->getBundleConfigDependency($this->bundle);
|
||||
$this->addDependency($bundle_config_dependency['type'], $bundle_config_dependency['name']);
|
||||
|
||||
return $this->dependencies;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -350,7 +343,7 @@ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigIn
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSettings(array $settings) {
|
||||
$this->settings = $settings;
|
||||
$this->settings = $settings + $this->settings;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -393,25 +386,58 @@ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigIn
|
|||
*/
|
||||
public function getDefaultValue(FieldableEntityInterface $entity) {
|
||||
// Allow custom default values function.
|
||||
if ($callback = $this->default_value_callback) {
|
||||
if ($callback = $this->getDefaultValueCallback()) {
|
||||
$value = call_user_func($callback, $entity, $this);
|
||||
}
|
||||
else {
|
||||
$value = $this->default_value;
|
||||
}
|
||||
// Normalize into the "array keyed by delta" format.
|
||||
if (isset($value) && !is_array($value)) {
|
||||
$properties = $this->getFieldStorageDefinition()->getPropertyNames();
|
||||
$property = reset($properties);
|
||||
$value = array(
|
||||
array($property => $value),
|
||||
);
|
||||
$value = $this->getDefaultValueLiteral();
|
||||
}
|
||||
// Allow the field type to process default values.
|
||||
$field_item_list_class = $this->getClass();
|
||||
return $field_item_list_class::processDefaultValue($value, $entity, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefaultValueLiteral() {
|
||||
return $this->default_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDefaultValue($value) {
|
||||
if (!is_array($value)) {
|
||||
if ($value === NULL) {
|
||||
$value = [];
|
||||
}
|
||||
$key = $this->getFieldStorageDefinition()->getPropertyNames()[0];
|
||||
// Convert to the multi value format to support fields with a cardinality
|
||||
// greater than 1.
|
||||
$value = array(
|
||||
array($key => $value),
|
||||
);
|
||||
}
|
||||
$this->default_value = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefaultValueCallback() {
|
||||
return $this->default_value_callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDefaultValueCallback($callback) {
|
||||
$this->default_value_callback = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the magic __sleep() method.
|
||||
*
|
||||
|
@ -423,7 +449,7 @@ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigIn
|
|||
// Only serialize necessary properties, excluding those that can be
|
||||
// recalculated.
|
||||
$properties = get_object_vars($this);
|
||||
unset($properties['fieldStorage'], $properties['itemDefinition'], $properties['bundleRenameAllowed'], $properties['original']);
|
||||
unset($properties['fieldStorage'], $properties['itemDefinition'], $properties['original']);
|
||||
return array_keys($properties);
|
||||
}
|
||||
|
||||
|
@ -495,29 +521,6 @@ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigIn
|
|||
return $this->itemDefinition;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDefaultValue($value) {
|
||||
if (!is_array($value)) {
|
||||
$key = $this->getFieldStorageDefinition()->getPropertyNames()[0];
|
||||
// Convert to the multi value format to support fields with a cardinality
|
||||
// greater than 1.
|
||||
$value = array(
|
||||
array($key => $value),
|
||||
);
|
||||
}
|
||||
$this->default_value = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function allowBundleRename() {
|
||||
$this->bundleRenameAllowed = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -55,7 +55,29 @@ interface FieldConfigInterface extends FieldDefinitionInterface, ConfigEntityInt
|
|||
public function setTranslatable($translatable);
|
||||
|
||||
/**
|
||||
* Sets field settings (overwrites existing settings).
|
||||
* Sets field settings.
|
||||
*
|
||||
* Note that the method does not unset existing settings not specified in the
|
||||
* incoming $settings array.
|
||||
*
|
||||
* For example:
|
||||
* @code
|
||||
* // Given these are the default settings.
|
||||
* $field_definition->getSettings() === [
|
||||
* 'fruit' => 'apple',
|
||||
* 'season' => 'summer',
|
||||
* ];
|
||||
* // Change only the 'fruit' setting.
|
||||
* $field_definition->setSettings(['fruit' => 'banana']);
|
||||
* // The 'season' setting persists unchanged.
|
||||
* $field_definition->getSettings() === [
|
||||
* 'fruit' => 'banana',
|
||||
* 'season' => 'summer',
|
||||
* ];
|
||||
* @endcode
|
||||
*
|
||||
* For clarity, it is preferred to use setSetting() if not all available
|
||||
* settings are supplied.
|
||||
*
|
||||
* @param array $settings
|
||||
* The array of field settings.
|
||||
|
@ -100,13 +122,39 @@ interface FieldConfigInterface extends FieldDefinitionInterface, ConfigEntityInt
|
|||
* any value set here.
|
||||
*
|
||||
* @param mixed $value
|
||||
* The default value in the format as returned by
|
||||
* \Drupal\Core\Field\FieldDefinitionInterface::getDefaultValue().
|
||||
* The default value for the field. This can be either:
|
||||
* - a literal, in which case it will be assigned to the first property of
|
||||
* the first item.
|
||||
* - a numerically indexed array of items, each item being a property/value
|
||||
* array.
|
||||
* - a non-numerically indexed array, in which case the array is assumed to
|
||||
* be a property/value array and used as the first item
|
||||
* - NULL or array() for no default value.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultValue($value);
|
||||
|
||||
/**
|
||||
* Sets a custom default value callback.
|
||||
*
|
||||
* If set, the callback overrides any set default value.
|
||||
*
|
||||
* @param string|null $callback
|
||||
* The callback to invoke for getting the default value (pass NULL to unset
|
||||
* a previously set callback). The callback will be invoked with the
|
||||
* following arguments:
|
||||
* - \Drupal\Core\Entity\FieldableEntityInterface $entity
|
||||
* The entity being created.
|
||||
* - \Drupal\Core\Field\FieldDefinitionInterface $definition
|
||||
* The field definition.
|
||||
* It should return the default value in the format accepted by the
|
||||
* setDefaultValue() method.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDefaultValueCallback($callback);
|
||||
|
||||
/**
|
||||
* Sets constraints for a given field item property.
|
||||
*
|
||||
|
@ -178,7 +226,7 @@ interface FieldConfigInterface extends FieldDefinitionInterface, ConfigEntityInt
|
|||
* @code
|
||||
* // Add a constraint to the 'field_username' FieldItemList.
|
||||
* // e.g. $node->field_username
|
||||
* $fields['field_username']->addConstraint('UserNameUnique', []);
|
||||
* $fields['field_username']->addConstraint('UniqueField');
|
||||
* @endcode
|
||||
*
|
||||
* If you wish to apply a constraint to a \Drupal\Core\Field\FieldItem instead
|
||||
|
@ -234,13 +282,4 @@ interface FieldConfigInterface extends FieldDefinitionInterface, ConfigEntityInt
|
|||
*/
|
||||
public function setConstraints(array $constraints);
|
||||
|
||||
/**
|
||||
* Allows a bundle to be renamed.
|
||||
*
|
||||
* Renaming a bundle on the instance is allowed when an entity's bundle
|
||||
* is renamed and when field_entity_bundle_rename() does internal
|
||||
* housekeeping.
|
||||
*/
|
||||
public function allowBundleRename();
|
||||
|
||||
}
|
||||
|
|
|
@ -178,15 +178,54 @@ interface FieldDefinitionInterface extends ListDataDefinitionInterface, Cacheabl
|
|||
*/
|
||||
public function isRequired();
|
||||
|
||||
/**
|
||||
* Returns the default value literal for the field.
|
||||
*
|
||||
* This method retrieves the raw property assigned to the field definition.
|
||||
* When computing the runtime default value for a field in a given entity,
|
||||
* ::getDefaultValue() should be used instead.
|
||||
*
|
||||
* @return array
|
||||
* The default value for the field, as a numerically indexed array of items,
|
||||
* each item being a property/value array (array() for no default value).
|
||||
*
|
||||
* @see FieldDefinitionInterface::getDefaultValue()
|
||||
* @see FieldDefinitionInterface::getDefaultValueCallback()
|
||||
*/
|
||||
public function getDefaultValueLiteral();
|
||||
|
||||
/**
|
||||
* Returns the default value callback for the field.
|
||||
*
|
||||
* This method retrieves the raw property assigned to the field definition.
|
||||
* When computing the runtime default value for a field in a given entity,
|
||||
* ::getDefaultValue() should be used instead.
|
||||
*
|
||||
* @return string|null
|
||||
* The default value callback for the field.
|
||||
*
|
||||
* @see FieldDefinitionInterface::getDefaultValue()
|
||||
* @see FieldDefinitionInterface::getDefaultValueLiteral()
|
||||
*/
|
||||
public function getDefaultValueCallback();
|
||||
|
||||
/**
|
||||
* Returns the default value for the field in a newly created entity.
|
||||
*
|
||||
* This method computes the runtime default value for a field in a given
|
||||
* entity. To access the raw properties assigned to the field definition,
|
||||
* ::getDefaultValueLiteral() or ::getDefaultValueCallback() should be used
|
||||
* instead.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\FieldableEntityInterface $entity
|
||||
* The entity for which the default value is generated.
|
||||
*
|
||||
* @return array
|
||||
* The default value for the field, as a numerically indexed array of items,
|
||||
* each item being a property/value array (array() for no default value).
|
||||
*
|
||||
* @see FieldDefinitionInterface::getDefaultValueLiteral()
|
||||
* @see FieldDefinitionInterface::getDefaultValueCallback()
|
||||
*/
|
||||
public function getDefaultValue(FieldableEntityInterface $entity);
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\Field\FieldFilteredString.
|
||||
* Contains \Drupal\Core\Field\FieldFilteredMarkup.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Field;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\SafeStringInterface;
|
||||
use Drupal\Component\Utility\SafeStringTrait;
|
||||
use Drupal\Component\Render\MarkupInterface;
|
||||
use Drupal\Component\Render\MarkupTrait;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Component\Utility\Xss;
|
||||
|
||||
|
@ -23,18 +23,18 @@ use Drupal\Component\Utility\Xss;
|
|||
* This object is marked as internal because it should only be used by the
|
||||
* Field module and field-related plugins.
|
||||
*
|
||||
* @see \Drupal\Core\Render\SafeString
|
||||
* @see \Drupal\Core\Render\Markup
|
||||
*/
|
||||
final class FieldFilteredString implements SafeStringInterface, \Countable {
|
||||
use SafeStringTrait;
|
||||
final class FieldFilteredMarkup implements MarkupInterface, \Countable {
|
||||
use MarkupTrait;
|
||||
|
||||
/**
|
||||
* Overrides \Drupal\Component\Utility\SafeStringTrait::create().
|
||||
* Overrides \Drupal\Component\Render\MarkupTrait::create().
|
||||
*
|
||||
* @return string|\Drupal\Component\Utility\SafeStringInterface
|
||||
* @return string|\Drupal\Component\Render\MarkupInterface
|
||||
* A safe string filtered with the allowed tag list and normalized.
|
||||
*
|
||||
* @see \Drupal\Core\Field\FieldFilteredString::allowedTags()
|
||||
* @see \Drupal\Core\Field\FieldFilteredMarkup::allowedTags()
|
||||
* @see \Drupal\Component\Utility\Xss::filter()
|
||||
* @see \Drupal\Component\Utility\Html::normalize()
|
||||
*/
|
|
@ -267,6 +267,13 @@ abstract class FieldItemBase extends Map implements FieldItemInterface {
|
|||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function calculateStorageDependencies(FieldStorageDefinitionInterface $field_definition) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -418,6 +418,39 @@ interface FieldItemInterface extends ComplexDataInterface {
|
|||
*/
|
||||
public static function calculateDependencies(FieldDefinitionInterface $field_definition);
|
||||
|
||||
/**
|
||||
* Calculates dependencies for field items on the storage level.
|
||||
*
|
||||
* Dependencies are saved in the field storage configuration entity and are
|
||||
* used to determine configuration synchronization order. For example, if the
|
||||
* field type storage depends on a particular entity type, this method should
|
||||
* return an array of dependencies listing the module that provides the entity
|
||||
* type.
|
||||
*
|
||||
* Dependencies returned from this method are stored in field storage
|
||||
* configuration and are always considered hard dependencies. If the
|
||||
* dependency is removed the field storage configuration must be deleted.
|
||||
*
|
||||
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $field_storage_definition
|
||||
* The field storage definition.
|
||||
*
|
||||
* @return array
|
||||
* An array of dependencies grouped by type (config, content, module,
|
||||
* theme). For example:
|
||||
* @code
|
||||
* [
|
||||
* 'config' => ['user.role.anonymous', 'user.role.authenticated'],
|
||||
* 'content' => ['node:article:f0a189e6-55fb-47fb-8005-5bef81c44d6d'],
|
||||
* 'module' => ['node', 'user'],
|
||||
* 'theme' => ['seven'],
|
||||
* ];
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\Core\Config\Entity\ConfigDependencyManager
|
||||
* @see \Drupal\Core\Config\Entity\ConfigEntityInterface::getConfigDependencyName()
|
||||
*/
|
||||
public static function calculateStorageDependencies(FieldStorageDefinitionInterface $field_storage_definition);
|
||||
|
||||
/**
|
||||
* Informs the plugin that a dependency of the field will be deleted.
|
||||
*
|
||||
|
|
|
@ -281,7 +281,7 @@ class FieldItemList extends ItemList implements FieldItemListInterface {
|
|||
// widgets.
|
||||
$cardinality = $this->getFieldDefinition()->getFieldStorageDefinition()->getCardinality();
|
||||
if ($cardinality != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
|
||||
$constraints[] = \Drupal::typedDataManager()
|
||||
$constraints[] = $this->getTypedDataManager()
|
||||
->getValidationConstraintManager()
|
||||
->create('Count', array(
|
||||
'max' => $cardinality,
|
||||
|
@ -296,14 +296,17 @@ class FieldItemList extends ItemList implements FieldItemListInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultValuesForm(array &$form, FormStateInterface $form_state) {
|
||||
if (empty($this->getFieldDefinition()->default_value_callback)) {
|
||||
// Place the input in a separate place in the submitted values tree.
|
||||
$widget = $this->defaultValueWidget($form_state);
|
||||
if (empty($this->getFieldDefinition()->getDefaultValueCallback())) {
|
||||
if ($widget = $this->defaultValueWidget($form_state)) {
|
||||
// Place the input in a separate place in the submitted values tree.
|
||||
$element = array('#parents' => array('default_value_input'));
|
||||
$element += $widget->form($this, $element, $form_state);
|
||||
|
||||
$element = array('#parents' => array('default_value_input'));
|
||||
$element += $widget->form($this, $element, $form_state);
|
||||
|
||||
return $element;
|
||||
return $element;
|
||||
}
|
||||
else {
|
||||
return ['#markup' => $this->t('No widget available for: %type.', ['%type' => $this->getFieldDefinition()->getType()])];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,16 +315,17 @@ class FieldItemList extends ItemList implements FieldItemListInterface {
|
|||
*/
|
||||
public function defaultValuesFormValidate(array $element, array &$form, FormStateInterface $form_state) {
|
||||
// Extract the submitted value, and validate it.
|
||||
$widget = $this->defaultValueWidget($form_state);
|
||||
$widget->extractFormValues($this, $element, $form_state);
|
||||
// Force a non-required field definition.
|
||||
// @see self::defaultValueWidget().
|
||||
$this->getFieldDefinition()->setRequired(FALSE);
|
||||
$violations = $this->validate();
|
||||
if ($widget = $this->defaultValueWidget($form_state)) {
|
||||
$widget->extractFormValues($this, $element, $form_state);
|
||||
// Force a non-required field definition.
|
||||
// @see self::defaultValueWidget().
|
||||
$this->getFieldDefinition()->setRequired(FALSE);
|
||||
$violations = $this->validate();
|
||||
|
||||
// Assign reported errors to the correct form element.
|
||||
if (count($violations)) {
|
||||
$widget->flagErrors($this, $violations, $element, $form_state);
|
||||
// Assign reported errors to the correct form element.
|
||||
if (count($violations)) {
|
||||
$widget->flagErrors($this, $violations, $element, $form_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,9 +334,10 @@ class FieldItemList extends ItemList implements FieldItemListInterface {
|
|||
*/
|
||||
public function defaultValuesFormSubmit(array $element, array &$form, FormStateInterface $form_state) {
|
||||
// Extract the submitted value, and return it as an array.
|
||||
$widget = $this->defaultValueWidget($form_state);
|
||||
$widget->extractFormValues($this, $element, $form_state);
|
||||
return $this->getValue();
|
||||
if ($widget = $this->defaultValueWidget($form_state)) {
|
||||
$widget->extractFormValues($this, $element, $form_state);
|
||||
return $this->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -348,8 +353,8 @@ class FieldItemList extends ItemList implements FieldItemListInterface {
|
|||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The form state of the (entire) configuration form.
|
||||
*
|
||||
* @return \Drupal\Core\Field\WidgetInterface
|
||||
* A Widget object.
|
||||
* @return \Drupal\Core\Field\WidgetInterface|null
|
||||
* A Widget object or NULL if no widget is available.
|
||||
*/
|
||||
protected function defaultValueWidget(FormStateInterface $form_state) {
|
||||
if (!$form_state->has('default_value_widget')) {
|
||||
|
|
|
@ -57,19 +57,23 @@ interface FieldStorageDefinitionInterface extends CacheableDependencyInterface {
|
|||
public function getType();
|
||||
|
||||
/**
|
||||
* Returns the field settings.
|
||||
* Returns the storage settings.
|
||||
*
|
||||
* Each field type defines the settings that are meaningful for that type.
|
||||
* For example, a text field can define a 'max_length' setting, and an image
|
||||
* field can define a 'alt_field_required' setting.
|
||||
*
|
||||
* The method always returns an array of all available settings for this field
|
||||
* type, possibly with the default values merged in if values have not been
|
||||
* provided for all available settings.
|
||||
*
|
||||
* @return mixed[]
|
||||
* An array of key/value pairs.
|
||||
*/
|
||||
public function getSettings();
|
||||
|
||||
/**
|
||||
* Returns the value of a given field setting.
|
||||
* Returns the value of a given storage setting.
|
||||
*
|
||||
* @param string $setting_name
|
||||
* The setting name.
|
||||
|
|
|
@ -13,7 +13,7 @@ use Drupal\Core\Entity\FieldableEntityInterface;
|
|||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Plugin\CategorizingPluginManagerTrait;
|
||||
use Drupal\Core\Plugin\DefaultPluginManager;
|
||||
use Drupal\Core\TypedData\TypedDataManager;
|
||||
use Drupal\Core\TypedData\TypedDataManagerInterface;
|
||||
|
||||
/**
|
||||
* Plugin manager for 'field type' plugins.
|
||||
|
@ -27,7 +27,7 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl
|
|||
/**
|
||||
* The typed data manager.
|
||||
*
|
||||
* @var \Drupal\Core\TypedData\TypedDataManager
|
||||
* @var \Drupal\Core\TypedData\TypedDataManagerInterface
|
||||
*/
|
||||
protected $typedDataManager;
|
||||
|
||||
|
@ -41,10 +41,10 @@ class FieldTypePluginManager extends DefaultPluginManager implements FieldTypePl
|
|||
* Cache backend instance to use.
|
||||
* @param \Drupal\Core\Extension\ModuleHandlerInterface
|
||||
* The module handler.
|
||||
* @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
|
||||
* @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager
|
||||
* The typed data manager.
|
||||
*/
|
||||
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, TypedDataManager $typed_data_manager) {
|
||||
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, TypedDataManagerInterface $typed_data_manager) {
|
||||
parent::__construct('Plugin/Field/FieldType', $namespaces, $module_handler, 'Drupal\Core\Field\FieldItemInterface', 'Drupal\Core\Field\Annotation\FieldType');
|
||||
$this->alterInfo('field_info');
|
||||
$this->setCacheBackend($cache_backend, 'field_types_plugins');
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\Core\Field;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Render\Element;
|
||||
|
||||
/**
|
||||
|
@ -76,8 +77,12 @@ abstract class FormatterBase extends PluginSettingsBase implements FormatterInte
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function view(FieldItemListInterface $items) {
|
||||
$elements = $this->viewElements($items);
|
||||
public function view(FieldItemListInterface $items, $langcode = NULL) {
|
||||
// Default the language to the current content language.
|
||||
if (empty($langcode)) {
|
||||
$langcode = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
|
||||
}
|
||||
$elements = $this->viewElements($items, $langcode);
|
||||
|
||||
// If there are actual renderable children, use #theme => field, otherwise,
|
||||
// let access cacheability metadata pass through for correct bubbling.
|
||||
|
@ -99,6 +104,7 @@ abstract class FormatterBase extends PluginSettingsBase implements FormatterInte
|
|||
'#object' => $entity,
|
||||
'#items' => $items,
|
||||
'#formatter' => $this->getPluginId(),
|
||||
'#is_multiple' => $this->fieldDefinition->getFieldStorageDefinition()->isMultiple(),
|
||||
);
|
||||
|
||||
$elements = array_merge($info, $elements);
|
||||
|
|
|
@ -69,23 +69,28 @@ interface FormatterInterface extends PluginSettingsInterface {
|
|||
*
|
||||
* @param \Drupal\Core\Field\FieldItemListInterface $items
|
||||
* The field values to be rendered.
|
||||
* @param string $langcode
|
||||
* (optional) The language that should be used to render the field. Defaults
|
||||
* to the current content language.
|
||||
*
|
||||
* @return array
|
||||
* A renderable array for a themed field with its label and all its values.
|
||||
*/
|
||||
public function view(FieldItemListInterface $items);
|
||||
public function view(FieldItemListInterface $items, $langcode = NULL);
|
||||
|
||||
/**
|
||||
* Builds a renderable array for a field value.
|
||||
*
|
||||
* @param \Drupal\Core\Field\FieldItemListInterface $items
|
||||
* The field values to be rendered.
|
||||
* @param string $langcode
|
||||
* The language that should be used to render the field.
|
||||
*
|
||||
* @return array
|
||||
* A renderable array for $items, as an array of child elements keyed by
|
||||
* consecutive numeric indexes starting from 0.
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items);
|
||||
public function viewElements(FieldItemListInterface $items, $langcode);
|
||||
|
||||
/**
|
||||
* Returns if the formatter can be used for the provided field.
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
|
||||
|
@ -31,13 +30,17 @@ class BasicStringFormatter extends FormatterBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
$elements = array();
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = [];
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
// The text value has no text format assigned to it, so the user input
|
||||
// should equal the output, including newlines.
|
||||
$elements[$delta] = array('#markup' => nl2br(Html::escape($item->value)));
|
||||
$elements[$delta] = [
|
||||
'#type' => 'inline_template',
|
||||
'#template' => '{{ value|nl2br }}',
|
||||
'#context' => ['value' => $item->value],
|
||||
];
|
||||
}
|
||||
|
||||
return $elements;
|
||||
|
|
|
@ -116,7 +116,7 @@ class BooleanFormatter extends FormatterBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = [];
|
||||
|
||||
$formats = $this->getOutputFormats();
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
|
|||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
@ -119,11 +120,11 @@ class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase implem
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$view_mode = $this->getSetting('view_mode');
|
||||
$elements = array();
|
||||
|
||||
foreach ($this->getEntitiesToView($items) as $delta => $entity) {
|
||||
foreach ($this->getEntitiesToView($items, $langcode) as $delta => $entity) {
|
||||
// Protect ourselves from recursive rendering.
|
||||
static $depth = 0;
|
||||
$depth++;
|
||||
|
|
|
@ -36,24 +36,25 @@ abstract class EntityReferenceFormatterBase extends FormatterBase {
|
|||
*
|
||||
* @param \Drupal\Core\Field\EntityReferenceFieldItemListInterface $items
|
||||
* The item list.
|
||||
* @param string $langcode
|
||||
* The language code of the referenced entities to display.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityInterface[]
|
||||
* The array of referenced entities to display, keyed by delta.
|
||||
*
|
||||
* @see ::prepareView()
|
||||
*/
|
||||
protected function getEntitiesToView(EntityReferenceFieldItemListInterface $items) {
|
||||
protected function getEntitiesToView(EntityReferenceFieldItemListInterface $items, $langcode) {
|
||||
$entities = array();
|
||||
|
||||
$parent_entity_langcode = $items->getEntity()->language()->getId();
|
||||
foreach ($items as $delta => $item) {
|
||||
// Ignore items where no entity could be loaded in prepareView().
|
||||
if (!empty($item->_loaded)) {
|
||||
$entity = $item->entity;
|
||||
|
||||
// Set the entity in the correct language for display.
|
||||
if ($entity instanceof TranslatableInterface && $entity->hasTranslation($parent_entity_langcode)) {
|
||||
$entity = $entity->getTranslation($parent_entity_langcode);
|
||||
if ($entity instanceof TranslatableInterface) {
|
||||
$entity = \Drupal::entityManager()->getTranslationFromContext($entity, $langcode);
|
||||
}
|
||||
|
||||
$access = $this->checkAccess($entity);
|
||||
|
@ -76,8 +77,8 @@ abstract class EntityReferenceFormatterBase extends FormatterBase {
|
|||
* @see ::prepareView()
|
||||
* @see ::getEntitiestoView()
|
||||
*/
|
||||
public function view(FieldItemListInterface $items) {
|
||||
$elements = parent::view($items);
|
||||
public function view(FieldItemListInterface $items, $langcode = NULL) {
|
||||
$elements = parent::view($items, $langcode);
|
||||
|
||||
$field_level_access_cacheability = new CacheableMetadata();
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
|
||||
/**
|
||||
* Plugin implementation of the 'entity reference ID' formatter.
|
||||
|
@ -26,10 +27,10 @@ class EntityReferenceIdFormatter extends EntityReferenceFormatterBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
foreach ($this->getEntitiesToView($items) as $delta => $entity) {
|
||||
foreach ($this->getEntitiesToView($items, $langcode) as $delta => $entity) {
|
||||
if ($entity->id()) {
|
||||
$elements[$delta] = array(
|
||||
'#plain_text' => $entity->id(),
|
||||
|
|
|
@ -59,11 +59,11 @@ class EntityReferenceLabelFormatter extends EntityReferenceFormatterBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
$output_as_link = $this->getSetting('link');
|
||||
|
||||
foreach ($this->getEntitiesToView($items) as $delta => $entity) {
|
||||
foreach ($this->getEntitiesToView($items, $langcode) as $delta => $entity) {
|
||||
$label = $entity->label();
|
||||
// If the link is to be displayed and the entity has a uri, display a
|
||||
// link.
|
||||
|
|
|
@ -27,7 +27,7 @@ class MailToFormatter extends FormatterBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
|
|
|
@ -66,7 +66,7 @@ abstract class NumericFormatterBase extends FormatterBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
$settings = $this->getFieldSettings();
|
||||
|
||||
|
@ -75,15 +75,15 @@ abstract class NumericFormatterBase extends FormatterBase {
|
|||
|
||||
// Account for prefix and suffix.
|
||||
if ($this->getSetting('prefix_suffix')) {
|
||||
$prefixes = isset($settings['prefix']) ? array_map(array('Drupal\Core\Field\FieldFilteredString', 'create'), explode('|', $settings['prefix'])) : array('');
|
||||
$suffixes = isset($settings['suffix']) ? array_map(array('Drupal\Core\Field\FieldFilteredString', 'create'), explode('|', $settings['suffix'])) : array('');
|
||||
$prefixes = isset($settings['prefix']) ? array_map(array('Drupal\Core\Field\FieldFilteredMarkup', 'create'), explode('|', $settings['prefix'])) : array('');
|
||||
$suffixes = isset($settings['suffix']) ? array_map(array('Drupal\Core\Field\FieldFilteredMarkup', 'create'), explode('|', $settings['suffix'])) : array('');
|
||||
$prefix = (count($prefixes) > 1) ? $this->formatPlural($item->value, $prefixes[0], $prefixes[1]) : $prefixes[0];
|
||||
$suffix = (count($suffixes) > 1) ? $this->formatPlural($item->value, $suffixes[0], $suffixes[1]) : $suffixes[0];
|
||||
$output = $prefix . $output . $suffix;
|
||||
}
|
||||
// Output the raw value in a content attribute if the text of the HTML
|
||||
// element differs from the raw value (for example when a prefix is used).
|
||||
if (!empty($item->_attributes) && $item->value != $output) {
|
||||
if (isset($item->_attributes) && $item->value != $output) {
|
||||
$item->_attributes += array('content' => $item->value);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class NumericUnformattedFormatter extends FormatterBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
|
|
|
@ -7,9 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Core\Entity\EntityManagerInterface;
|
||||
use Drupal\Core\Entity\RevisionableInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemInterface;
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
|
@ -119,7 +117,7 @@ class StringFormatter extends FormatterBase implements ContainerFactoryPluginInt
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
$url = NULL;
|
||||
if ($this->getSetting('link_to_entity')) {
|
||||
|
@ -137,7 +135,7 @@ class StringFormatter extends FormatterBase implements ContainerFactoryPluginInt
|
|||
];
|
||||
}
|
||||
else {
|
||||
$elements[$delta] = is_array($view_value) ? $view_value : ['#markup' => $view_value];
|
||||
$elements[$delta] = $view_value;
|
||||
}
|
||||
}
|
||||
return $elements;
|
||||
|
@ -156,7 +154,9 @@ class StringFormatter extends FormatterBase implements ContainerFactoryPluginInt
|
|||
// The text value has no text format assigned to it, so the user input
|
||||
// should equal the output, including newlines.
|
||||
return [
|
||||
'#markup' => nl2br(Html::escape($item->value))
|
||||
'#type' => 'inline_template',
|
||||
'#template' => '{{ value|nl2br }}',
|
||||
'#context' => ['value' => $item->value],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Core\Datetime\DateFormatter;
|
||||
use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\FormatterBase;
|
||||
|
@ -35,7 +35,7 @@ class TimestampAgoFormatter extends FormatterBase implements ContainerFactoryPlu
|
|||
/**
|
||||
* The date formatter service.
|
||||
*
|
||||
* @var \Drupal\Core\Datetime\DateFormatter
|
||||
* @var \Drupal\Core\Datetime\DateFormatterInterface
|
||||
*/
|
||||
protected $dateFormatter;
|
||||
|
||||
|
@ -63,12 +63,12 @@ class TimestampAgoFormatter extends FormatterBase implements ContainerFactoryPlu
|
|||
* The view mode.
|
||||
* @param array $third_party_settings
|
||||
* Any third party settings.
|
||||
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
|
||||
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
|
||||
* The date formatter service.
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The current request.
|
||||
*/
|
||||
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatter $date_formatter, Request $request) {
|
||||
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatterInterface $date_formatter, Request $request) {
|
||||
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
|
||||
|
||||
$this->dateFormatter = $date_formatter;
|
||||
|
@ -153,7 +153,7 @@ class TimestampAgoFormatter extends FormatterBase implements ContainerFactoryPlu
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
|
||||
|
||||
use Drupal\Core\Datetime\DateFormatter;
|
||||
use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
|
@ -34,7 +34,7 @@ class TimestampFormatter extends FormatterBase implements ContainerFactoryPlugin
|
|||
/**
|
||||
* The date formatter service.
|
||||
*
|
||||
* @var \Drupal\Core\Datetime\DateFormatter
|
||||
* @var \Drupal\Core\Datetime\DateFormatterInterface
|
||||
*/
|
||||
protected $dateFormatter;
|
||||
|
||||
|
@ -62,12 +62,12 @@ class TimestampFormatter extends FormatterBase implements ContainerFactoryPlugin
|
|||
* The view mode.
|
||||
* @param array $third_party_settings
|
||||
* Third party settings.
|
||||
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
|
||||
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
|
||||
* The date formatter service.
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $date_format_storage
|
||||
* The date format storage.
|
||||
*/
|
||||
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatter $date_formatter, EntityStorageInterface $date_format_storage) {
|
||||
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatterInterface $date_formatter, EntityStorageInterface $date_format_storage) {
|
||||
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
|
||||
|
||||
$this->dateFormatter = $date_formatter;
|
||||
|
@ -126,7 +126,7 @@ class TimestampFormatter extends FormatterBase implements ContainerFactoryPlugin
|
|||
$elements['custom_date_format'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Custom date format'),
|
||||
'#description' => $this->t('See <a href="@url" target="_blank">the documentation for PHP date formats</a>.', ['@url' => 'http://php.net/manual/function.date.php']),
|
||||
'#description' => $this->t('See <a href=":url" target="_blank">the documentation for PHP date formats</a>.', [':url' => 'http://php.net/manual/function.date.php']),
|
||||
'#default_value' => $this->getSetting('custom_date_format') ?: '',
|
||||
);
|
||||
|
||||
|
@ -165,7 +165,7 @@ class TimestampFormatter extends FormatterBase implements ContainerFactoryPlugin
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
$date_format = $this->getSetting('date_format');
|
||||
|
|
|
@ -27,7 +27,7 @@ class UriLinkFormatter extends FormatterBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function viewElements(FieldItemListInterface $items) {
|
||||
public function viewElements(FieldItemListInterface $items, $langcode) {
|
||||
$elements = array();
|
||||
|
||||
foreach ($items as $delta => $item) {
|
||||
|
|
|
@ -12,6 +12,7 @@ use Drupal\Core\Field\FieldItemBase;
|
|||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
use Drupal\Core\TypedData\OptionsProviderInterface;
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
|
||||
|
@ -33,8 +34,8 @@ class BooleanItem extends FieldItemBase implements OptionsProviderInterface {
|
|||
*/
|
||||
public static function defaultFieldSettings() {
|
||||
return array(
|
||||
'on_label' => t('On'),
|
||||
'off_label' => t('Off'),
|
||||
'on_label' => new TranslatableMarkup('On'),
|
||||
'off_label' => new TranslatableMarkup('Off'),
|
||||
) + parent::defaultFieldSettings();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ namespace Drupal\Core\Field\Plugin\Field\FieldType;
|
|||
* label = @Translation("Last changed"),
|
||||
* description = @Translation("An entity field containing a UNIX timestamp of when the entity has been last updated."),
|
||||
* no_ui = TRUE,
|
||||
* default_widget = "datetime_default",
|
||||
* default_formatter = "timestamp",
|
||||
* list_class = "\Drupal\Core\Field\ChangedFieldItemList"
|
||||
* )
|
||||
*
|
||||
|
|
|
@ -15,7 +15,8 @@ namespace Drupal\Core\Field\Plugin\Field\FieldType;
|
|||
* label = @Translation("Created"),
|
||||
* description = @Translation("An entity field containing a UNIX timestamp of when the entity has been created."),
|
||||
* no_ui = TRUE,
|
||||
* default_formatter = "timestamp",
|
||||
* default_widget = "datetime_default",
|
||||
* default_formatter = "timestamp"
|
||||
* )
|
||||
*/
|
||||
class CreatedItem extends TimestampItem {
|
||||
|
|
|
@ -38,7 +38,6 @@ class DecimalItem extends NumericItemBase {
|
|||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
||||
*/
|
||||
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
|
||||
$properties['value'] = DataDefinition::create('string')
|
||||
|
@ -92,6 +91,25 @@ class DecimalItem extends NumericItemBase {
|
|||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConstraints() {
|
||||
$constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
|
||||
$constraints = parent::getConstraints();
|
||||
|
||||
$constraints[] = $constraint_manager->create('ComplexData', array(
|
||||
'value' => array(
|
||||
'Regex' => array(
|
||||
'pattern' => '/^[+-]?((\d+(\.\d*)?)|(\.\d+))$/i',
|
||||
)
|
||||
),
|
||||
));
|
||||
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -32,7 +32,7 @@ class EmailItem extends FieldItemBase {
|
|||
*/
|
||||
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
|
||||
$properties['value'] = DataDefinition::create('email')
|
||||
->setLabel(t('E-mail'))
|
||||
->setLabel(t('Email'))
|
||||
->setRequired(TRUE);
|
||||
|
||||
return $properties;
|
||||
|
|
|
@ -7,44 +7,45 @@
|
|||
|
||||
namespace Drupal\Core\Field\Plugin\Field\FieldType;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\NestedArray;
|
||||
use Drupal\Core\Entity\EntityInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Entity\TypedData\EntityDataDefinition;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldItemBase;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationWrapper;
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
use Drupal\Core\Field\PreconfiguredFieldUiOptionsInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Form\OptGroup;
|
||||
use Drupal\Core\Render\Element;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
use Drupal\Core\TypedData\DataReferenceDefinition;
|
||||
use Drupal\Core\TypedData\DataReferenceTargetDefinition;
|
||||
use Drupal\Core\TypedData\OptionsProviderInterface;
|
||||
use Drupal\Core\Validation\Plugin\Validation\Constraint\AllowedValuesConstraint;
|
||||
|
||||
/**
|
||||
* Defines the 'entity_reference' entity field type.
|
||||
*
|
||||
* Supported settings (below the definition's 'settings' key) are:
|
||||
* - target_type: The entity type to reference. Required.
|
||||
* - target_bundle: (optional): If set, restricts the entity bundles which may
|
||||
* may be referenced. May be set to an single bundle, or to an array of
|
||||
* allowed bundles.
|
||||
*
|
||||
* @FieldType(
|
||||
* id = "entity_reference",
|
||||
* label = @Translation("Entity reference"),
|
||||
* description = @Translation("An entity field containing an entity reference."),
|
||||
* category = @Translation("Reference"),
|
||||
* no_ui = TRUE,
|
||||
* default_widget = "entity_reference_autocomplete",
|
||||
* default_formatter = "entity_reference_label",
|
||||
* list_class = "\Drupal\Core\Field\EntityReferenceFieldItemList",
|
||||
* default_widget = "entity_reference_autocomplete",
|
||||
* default_formatter = "entity_reference_label",
|
||||
* constraints = {"ValidReference" = {}}
|
||||
* )
|
||||
*/
|
||||
class EntityReferenceItem extends FieldItemBase {
|
||||
|
||||
/**
|
||||
* Marker value to identify a newly created entity.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected static $NEW_ENTITY_MARKER = -1;
|
||||
class EntityReferenceItem extends FieldItemBase implements OptionsProviderInterface, PreconfiguredFieldUiOptionsInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -52,7 +53,6 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
public static function defaultStorageSettings() {
|
||||
return array(
|
||||
'target_type' => \Drupal::moduleHandler()->moduleExists('node') ? 'node' : 'user',
|
||||
'target_bundle' => NULL,
|
||||
) + parent::defaultStorageSettings();
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
*/
|
||||
public static function defaultFieldSettings() {
|
||||
return array(
|
||||
'handler' => 'default:' . (\Drupal::moduleHandler()->moduleExists('node') ? 'node' : 'user'),
|
||||
'handler' => 'default',
|
||||
'handler_settings' => array(),
|
||||
) + parent::defaultFieldSettings();
|
||||
}
|
||||
|
@ -82,34 +82,29 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
}
|
||||
|
||||
if ($target_id_data_type === 'integer') {
|
||||
$target_id_definition = DataDefinition::create('integer')
|
||||
->setLabel(new TranslationWrapper('@label ID', ['@label' => $target_type_info->getLabel()]))
|
||||
$target_id_definition = DataReferenceTargetDefinition::create('integer')
|
||||
->setLabel(new TranslatableMarkup('@label ID', ['@label' => $target_type_info->getLabel()]))
|
||||
->setSetting('unsigned', TRUE);
|
||||
}
|
||||
else {
|
||||
$target_id_definition = DataDefinition::create('string')
|
||||
->setLabel(new TranslationWrapper('@label ID', ['@label' => $target_type_info->getLabel()]));
|
||||
$target_id_definition = DataReferenceTargetDefinition::create('string')
|
||||
->setLabel(new TranslatableMarkup('@label ID', ['@label' => $target_type_info->getLabel()]));
|
||||
}
|
||||
$target_id_definition->setRequired(TRUE);
|
||||
$properties['target_id'] = $target_id_definition;
|
||||
|
||||
$properties['entity'] = DataReferenceDefinition::create('entity')
|
||||
->setLabel($target_type_info->getLabel())
|
||||
->setDescription(new TranslationWrapper('The referenced entity'))
|
||||
->setDescription(new TranslatableMarkup('The referenced entity'))
|
||||
// The entity object is computed out of the entity ID.
|
||||
->setComputed(TRUE)
|
||||
->setReadOnly(FALSE)
|
||||
->setTargetDefinition(EntityDataDefinition::create($settings['target_type']))
|
||||
// We can add a constraint for the target entity type. The list of
|
||||
// referenceable bundles is a field setting, so the corresponding
|
||||
// constraint is added dynamically in ::getConstraints().
|
||||
->addConstraint('EntityType', $settings['target_type']);
|
||||
|
||||
if (isset($settings['target_bundle'])) {
|
||||
$properties['entity']->addConstraint('Bundle', $settings['target_bundle']);
|
||||
// Set any further bundle constraints on the target definition as well,
|
||||
// such that it can derive more special data types if possible. For
|
||||
// example, "entity:node:page" instead of "entity:node".
|
||||
$properties['entity']->getTargetDefinition()
|
||||
->addConstraint('Bundle', $settings['target_bundle']);
|
||||
}
|
||||
return $properties;
|
||||
}
|
||||
|
||||
|
@ -158,6 +153,35 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getConstraints() {
|
||||
$constraints = parent::getConstraints();
|
||||
// Remove the 'AllowedValuesConstraint' validation constraint because entity
|
||||
// reference fields already use the 'ValidReference' constraint.
|
||||
foreach ($constraints as $key => $constraint) {
|
||||
if ($constraint instanceof AllowedValuesConstraint) {
|
||||
unset($constraints[$key]);
|
||||
}
|
||||
}
|
||||
list($current_handler) = explode(':', $this->getSetting('handler'), 2);
|
||||
if ($current_handler === 'default') {
|
||||
$handler_settings = $this->getSetting('handler_settings');
|
||||
if (isset($handler_settings['target_bundles'])) {
|
||||
$constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
|
||||
$constraints[] = $constraint_manager->create('ComplexData', [
|
||||
'entity' => [
|
||||
'Bundle' => [
|
||||
'bundle' => $handler_settings['target_bundles'],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -171,19 +195,23 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
parent::setValue($values, FALSE);
|
||||
// Support setting the field item with only one property, but make sure
|
||||
// values stay in sync if only property is passed.
|
||||
if (isset($values['target_id']) && !isset($values['entity'])) {
|
||||
// NULL is a valid value, so we use array_key_exists().
|
||||
if (is_array($values) && array_key_exists('target_id', $values) && !isset($values['entity'])) {
|
||||
$this->onChange('target_id', FALSE);
|
||||
}
|
||||
elseif (!isset($values['target_id']) && isset($values['entity'])) {
|
||||
elseif (is_array($values) && !array_key_exists('target_id', $values) && isset($values['entity'])) {
|
||||
$this->onChange('entity', FALSE);
|
||||
}
|
||||
elseif (isset($values['target_id']) && isset($values['entity'])) {
|
||||
elseif (is_array($values) && array_key_exists('target_id', $values) && isset($values['entity'])) {
|
||||
// If both properties are passed, verify the passed values match. The
|
||||
// only exception we allow is when we have a new entity: in this case
|
||||
// its actual id and target_id will be different, due to the new entity
|
||||
// marker.
|
||||
$entity_id = $this->get('entity')->getTargetIdentifier();
|
||||
if ($entity_id != $values['target_id'] && ($values['target_id'] != static::$NEW_ENTITY_MARKER || !$this->entity->isNew())) {
|
||||
// If the entity has been saved and we're trying to set both the
|
||||
// target_id and the entity values with a non-null target ID, then the
|
||||
// value for target_id should match the ID of the entity value.
|
||||
if (!$this->entity->isNew() && $values['target_id'] !== NULL && ($entity_id !== $values['target_id'])) {
|
||||
throw new \InvalidArgumentException('The target id and entity passed to the entity reference item do not match.');
|
||||
}
|
||||
}
|
||||
|
@ -216,10 +244,10 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
// Make sure that the target ID and the target property stay in sync.
|
||||
if ($property_name == 'entity') {
|
||||
$property = $this->get('entity');
|
||||
$target_id = $property->isTargetNew() ? static::$NEW_ENTITY_MARKER : $property->getTargetIdentifier();
|
||||
$target_id = $property->isTargetNew() ? NULL : $property->getTargetIdentifier();
|
||||
$this->writePropertyValue('target_id', $target_id);
|
||||
}
|
||||
elseif ($property_name == 'target_id' && $this->target_id != static::$NEW_ENTITY_MARKER) {
|
||||
elseif ($property_name == 'target_id') {
|
||||
$this->writePropertyValue('entity', $this->target_id);
|
||||
}
|
||||
parent::onChange($property_name, $notify);
|
||||
|
@ -252,6 +280,9 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
// react properly.
|
||||
$this->target_id = $this->entity->id();
|
||||
}
|
||||
if (!$this->isEmpty() && $this->target_id === NULL) {
|
||||
$this->target_id = $this->entity->id();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -266,6 +297,103 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
|
||||
$element['target_type'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Type of item to reference'),
|
||||
'#options' => \Drupal::entityManager()->getEntityTypeLabels(TRUE),
|
||||
'#default_value' => $this->getSetting('target_type'),
|
||||
'#required' => TRUE,
|
||||
'#disabled' => $has_data,
|
||||
'#size' => 1,
|
||||
);
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
|
||||
$field = $form_state->getFormObject()->getEntity();
|
||||
|
||||
// Get all selection plugins for this entity type.
|
||||
$selection_plugins = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionGroups($this->getSetting('target_type'));
|
||||
$handlers_options = array();
|
||||
foreach (array_keys($selection_plugins) as $selection_group_id) {
|
||||
// We only display base plugins (e.g. 'default', 'views', ...) and not
|
||||
// entity type specific plugins (e.g. 'default:node', 'default:user',
|
||||
// ...).
|
||||
if (array_key_exists($selection_group_id, $selection_plugins[$selection_group_id])) {
|
||||
$handlers_options[$selection_group_id] = Html::escape($selection_plugins[$selection_group_id][$selection_group_id]['label']);
|
||||
}
|
||||
elseif (array_key_exists($selection_group_id . ':' . $this->getSetting('target_type'), $selection_plugins[$selection_group_id])) {
|
||||
$selection_group_plugin = $selection_group_id . ':' . $this->getSetting('target_type');
|
||||
$handlers_options[$selection_group_plugin] = Html::escape($selection_plugins[$selection_group_id][$selection_group_plugin]['base_plugin_label']);
|
||||
}
|
||||
}
|
||||
|
||||
$form = array(
|
||||
'#type' => 'container',
|
||||
'#process' => array(array(get_class($this), 'fieldSettingsAjaxProcess')),
|
||||
'#element_validate' => array(array(get_class($this), 'fieldSettingsFormValidate')),
|
||||
|
||||
);
|
||||
$form['handler'] = array(
|
||||
'#type' => 'details',
|
||||
'#title' => t('Reference type'),
|
||||
'#open' => TRUE,
|
||||
'#tree' => TRUE,
|
||||
'#process' => array(array(get_class($this), 'formProcessMergeParent')),
|
||||
);
|
||||
|
||||
$form['handler']['handler'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Reference method'),
|
||||
'#options' => $handlers_options,
|
||||
'#default_value' => $field->getSetting('handler'),
|
||||
'#required' => TRUE,
|
||||
'#ajax' => TRUE,
|
||||
'#limit_validation_errors' => array(),
|
||||
);
|
||||
$form['handler']['handler_submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Change handler'),
|
||||
'#limit_validation_errors' => array(),
|
||||
'#attributes' => array(
|
||||
'class' => array('js-hide'),
|
||||
),
|
||||
'#submit' => array(array(get_class($this), 'settingsAjaxSubmit')),
|
||||
);
|
||||
|
||||
$form['handler']['handler_settings'] = array(
|
||||
'#type' => 'container',
|
||||
'#attributes' => array('class' => array('entity_reference-settings')),
|
||||
);
|
||||
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field);
|
||||
$form['handler']['handler_settings'] += $handler->buildConfigurationForm(array(), $form_state);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form element validation handler; Invokes selection plugin's validation.
|
||||
*
|
||||
* @param array $form
|
||||
* The form where the settings form is being included in.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The form state of the (entire) configuration form.
|
||||
*/
|
||||
public static function fieldSettingsFormValidate(array $form, FormStateInterface $form_state) {
|
||||
$field = $form_state->getFormObject()->getEntity();
|
||||
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field);
|
||||
$handler->validateConfigurationForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the item holds an unsaved entity.
|
||||
*
|
||||
|
@ -277,19 +405,22 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
* TRUE if the item holds an unsaved entity.
|
||||
*/
|
||||
public function hasNewEntity() {
|
||||
return $this->target_id === static::$NEW_ENTITY_MARKER;
|
||||
return !$this->isEmpty() && $this->target_id === NULL && $this->entity->isNew();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function calculateDependencies(FieldDefinitionInterface $field_definition) {
|
||||
$dependencies = [];
|
||||
if (is_array($field_definition->default_value) && count($field_definition->default_value)) {
|
||||
$target_entity_type = \Drupal::entityManager()->getDefinition($field_definition->getFieldStorageDefinition()->getSetting('target_type'));
|
||||
foreach ($field_definition->default_value as $default_value) {
|
||||
if (is_array($default_value) && isset($default_value['target_uuid'])) {
|
||||
$entity = \Drupal::entityManager()->loadEntityByUuid($target_entity_type->id(), $default_value['target_uuid']);
|
||||
$dependencies = parent::calculateDependencies($field_definition);
|
||||
$manager = \Drupal::entityManager();
|
||||
$target_entity_type = $manager->getDefinition($field_definition->getFieldStorageDefinition()->getSetting('target_type'));
|
||||
|
||||
// Depend on default values entity types configurations.
|
||||
if ($default_value = $field_definition->getDefaultValueLiteral()) {
|
||||
foreach ($default_value as $value) {
|
||||
if (is_array($value) && isset($value['target_uuid'])) {
|
||||
$entity = \Drupal::entityManager()->loadEntityByUuid($target_entity_type->id(), $value['target_uuid']);
|
||||
// If the entity does not exist do not create the dependency.
|
||||
// @see \Drupal\Core\Field\EntityReferenceFieldItemList::processDefaultValue()
|
||||
if ($entity) {
|
||||
|
@ -298,6 +429,29 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Depend on target bundle configurations.
|
||||
$handler = $field_definition->getSetting('handler_settings');
|
||||
if (!empty($handler['target_bundles'])) {
|
||||
if ($bundle_entity_type_id = $target_entity_type->getBundleEntityType()) {
|
||||
if ($storage = $manager->getStorage($bundle_entity_type_id)) {
|
||||
foreach ($storage->loadMultiple($handler['target_bundles']) as $bundle) {
|
||||
$dependencies[$bundle->getConfigDependencyKey()][] = $bundle->getConfigDependencyName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function calculateStorageDependencies(FieldStorageDefinitionInterface $field_definition) {
|
||||
$dependencies = parent::calculateStorageDependencies($field_definition);
|
||||
$target_entity_type = \Drupal::entityManager()->getDefinition($field_definition->getSetting('target_type'));
|
||||
$dependencies['module'][] = $target_entity_type->getProvider();
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
|
@ -305,21 +459,201 @@ class EntityReferenceItem extends FieldItemBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public static function onDependencyRemoval(FieldDefinitionInterface $field_definition, array $dependencies) {
|
||||
$changed = FALSE;
|
||||
if (!empty($field_definition->default_value)) {
|
||||
$target_entity_type = \Drupal::entityManager()->getDefinition($field_definition->getFieldStorageDefinition()->getSetting('target_type'));
|
||||
foreach ($field_definition->default_value as $key => $default_value) {
|
||||
if (is_array($default_value) && isset($default_value['target_uuid'])) {
|
||||
$entity = \Drupal::entityManager()->loadEntityByUuid($target_entity_type->id(), $default_value['target_uuid']);
|
||||
$changed = parent::onDependencyRemoval($field_definition, $dependencies);
|
||||
$entity_manager = \Drupal::entityManager();
|
||||
$target_entity_type = $entity_manager->getDefinition($field_definition->getFieldStorageDefinition()->getSetting('target_type'));
|
||||
|
||||
// Try to update the default value config dependency, if possible.
|
||||
if ($default_value = $field_definition->getDefaultValueLiteral()) {
|
||||
foreach ($default_value as $key => $value) {
|
||||
if (is_array($value) && isset($value['target_uuid'])) {
|
||||
$entity = $entity_manager->loadEntityByUuid($target_entity_type->id(), $value['target_uuid']);
|
||||
// @see \Drupal\Core\Field\EntityReferenceFieldItemList::processDefaultValue()
|
||||
if ($entity && isset($dependencies[$entity->getConfigDependencyKey()][$entity->getConfigDependencyName()])) {
|
||||
unset($field_definition->default_value[$key]);
|
||||
unset($default_value[$key]);
|
||||
$changed = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($changed) {
|
||||
$field_definition->setDefaultValue($default_value);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the 'target_bundles' handler setting if a bundle config dependency
|
||||
// has been removed.
|
||||
$bundles_changed = FALSE;
|
||||
$handler_settings = $field_definition->getSetting('handler_settings');
|
||||
if (!empty($handler_settings['target_bundles'])) {
|
||||
if ($bundle_entity_type_id = $target_entity_type->getBundleEntityType()) {
|
||||
if ($storage = $entity_manager->getStorage($bundle_entity_type_id)) {
|
||||
foreach ($storage->loadMultiple($handler_settings['target_bundles']) as $bundle) {
|
||||
if (isset($dependencies[$bundle->getConfigDependencyKey()][$bundle->getConfigDependencyName()])) {
|
||||
unset($handler_settings['target_bundles'][$bundle->id()]);
|
||||
$bundles_changed = TRUE;
|
||||
|
||||
// In case we deleted the only target bundle allowed by the field
|
||||
// we have to log a warning message because the field will not
|
||||
// function correctly anymore.
|
||||
if ($handler_settings['target_bundles'] === []) {
|
||||
\Drupal::logger('entity_reference')->critical('The %target_bundle bundle (entity type: %target_entity_type) was deleted. As a result, the %field_name entity reference field (entity_type: %entity_type, bundle: %bundle) no longer has any valid bundle it can reference. The field is not working correctly anymore and has to be adjusted.', [
|
||||
'%target_bundle' => $bundle->label(),
|
||||
'%target_entity_type' => $bundle->getEntityType()->getBundleOf(),
|
||||
'%field_name' => $field_definition->getName(),
|
||||
'%entity_type' => $field_definition->getTargetEntityTypeId(),
|
||||
'%bundle' => $field_definition->getTargetBundle()
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($bundles_changed) {
|
||||
$field_definition->setSetting('handler_settings', $handler_settings);
|
||||
}
|
||||
$changed |= $bundles_changed;
|
||||
|
||||
return $changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPossibleValues(AccountInterface $account = NULL) {
|
||||
return $this->getSettableValues($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPossibleOptions(AccountInterface $account = NULL) {
|
||||
return $this->getSettableOptions($account);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSettableValues(AccountInterface $account = NULL) {
|
||||
// Flatten options first, because "settable options" may contain group
|
||||
// arrays.
|
||||
$flatten_options = OptGroup::flattenOptions($this->getSettableOptions($account));
|
||||
return array_keys($flatten_options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSettableOptions(AccountInterface $account = NULL) {
|
||||
$field_definition = $this->getFieldDefinition();
|
||||
if (!$options = \Drupal::service('plugin.manager.entity_reference_selection')->getSelectionHandler($field_definition, $this->getEntity())->getReferenceableEntities()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Rebuild the array by changing the bundle key into the bundle label.
|
||||
$target_type = $field_definition->getSetting('target_type');
|
||||
$bundles = \Drupal::entityManager()->getBundleInfo($target_type);
|
||||
|
||||
$return = array();
|
||||
foreach ($options as $bundle => $entity_ids) {
|
||||
// The label does not need sanitizing since it is used as an optgroup
|
||||
// which is only supported by select elements and auto-escaped.
|
||||
$bundle_label = (string) $bundles[$bundle]['label'];
|
||||
$return[$bundle_label] = $entity_ids;
|
||||
}
|
||||
|
||||
return count($return) == 1 ? reset($return) : $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render API callback: Processes the field settings form and allows access to
|
||||
* the form state.
|
||||
*
|
||||
* @see static::fieldSettingsForm()
|
||||
*/
|
||||
public static function fieldSettingsAjaxProcess($form, FormStateInterface $form_state) {
|
||||
static::fieldSettingsAjaxProcessElement($form, $form);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds entity_reference specific properties to AJAX form elements from the
|
||||
* field settings form.
|
||||
*
|
||||
* @see static::fieldSettingsAjaxProcess()
|
||||
*/
|
||||
public static function fieldSettingsAjaxProcessElement(&$element, $main_form) {
|
||||
if (!empty($element['#ajax'])) {
|
||||
$element['#ajax'] = array(
|
||||
'callback' => array(get_called_class(), 'settingsAjax'),
|
||||
'wrapper' => $main_form['#id'],
|
||||
'element' => $main_form['#array_parents'],
|
||||
);
|
||||
}
|
||||
|
||||
foreach (Element::children($element) as $key) {
|
||||
static::fieldSettingsAjaxProcessElement($element[$key], $main_form);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render API callback: Moves entity_reference specific Form API elements
|
||||
* (i.e. 'handler_settings') up a level for easier processing by the
|
||||
* validation and submission handlers.
|
||||
*
|
||||
* @see _entity_reference_field_settings_process()
|
||||
*/
|
||||
public static function formProcessMergeParent($element) {
|
||||
$parents = $element['#parents'];
|
||||
array_pop($parents);
|
||||
$element['#parents'] = $parents;
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax callback for the handler settings form.
|
||||
*
|
||||
* @see static::fieldSettingsForm()
|
||||
*/
|
||||
public static function settingsAjax($form, FormStateInterface $form_state) {
|
||||
return NestedArray::getValue($form, $form_state->getTriggeringElement()['#ajax']['element']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit handler for the non-JS case.
|
||||
*
|
||||
* @see static::fieldSettingsForm()
|
||||
*/
|
||||
public static function settingsAjaxSubmit($form, FormStateInterface $form_state) {
|
||||
$form_state->setRebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getPreconfiguredOptions() {
|
||||
$options = array();
|
||||
|
||||
// Add all the commonly referenced entity types as distinct pre-configured
|
||||
// options.
|
||||
$entity_types = \Drupal::entityManager()->getDefinitions();
|
||||
$common_references = array_filter($entity_types, function (EntityTypeInterface $entity_type) {
|
||||
return $entity_type->isCommonReferenceTarget();
|
||||
});
|
||||
|
||||
/** @var \Drupal\Core\Entity\EntityTypeInterface $entity_type */
|
||||
foreach ($common_references as $entity_type) {
|
||||
$options[$entity_type->id()] = [
|
||||
'label' => $entity_type->getLabel(),
|
||||
'field_storage_config' => [
|
||||
'settings' => [
|
||||
'target_type' => $entity_type->id(),
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ class LanguageItem extends FieldItemBase {
|
|||
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
|
||||
$properties['value'] = DataDefinition::create('string')
|
||||
->setLabel(t('Language code'))
|
||||
->setSetting('is_ascii', TRUE)
|
||||
->setRequired(TRUE);
|
||||
|
||||
$properties['language'] = DataReferenceDefinition::create('language')
|
||||
|
@ -74,9 +73,8 @@ class LanguageItem extends FieldItemBase {
|
|||
return array(
|
||||
'columns' => array(
|
||||
'value' => array(
|
||||
'type' => 'varchar',
|
||||
'type' => 'varchar_ascii',
|
||||
'length' => 12,
|
||||
'is_ascii' => TRUE,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Drupal\Core\Field\Plugin\Field\FieldType;
|
|||
|
||||
use Drupal\Core\Entity\EntityMalformedException;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationWrapper;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
|
||||
/**
|
||||
|
@ -29,10 +29,10 @@ class PasswordItem extends StringItem {
|
|||
*/
|
||||
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
|
||||
$properties['value'] = DataDefinition::create('string')
|
||||
->setLabel(new TranslationWrapper('The hashed password'))
|
||||
->setLabel(new TranslatableMarkup('The hashed password'))
|
||||
->setSetting('case_sensitive', TRUE);
|
||||
$properties['existing'] = DataDefinition::create('string')
|
||||
->setLabel(new TranslationWrapper('Existing password'));
|
||||
->setLabel(new TranslatableMarkup('Existing password'));
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class PasswordItem extends StringItem {
|
|||
$entity = $this->getEntity();
|
||||
|
||||
// Update the user password if it has changed.
|
||||
if ($entity->isNew() || ($this->value && $this->value != $entity->original->{$this->getFieldDefinition()->getName()}->value)) {
|
||||
if ($entity->isNew() || (strlen(trim($this->value)) > 0 && $this->value != $entity->original->{$this->getFieldDefinition()->getName()}->value)) {
|
||||
// Allow alternate password hashing schemes.
|
||||
$this->value = \Drupal::service('password')->hash(trim($this->value));
|
||||
// Abort if the hashing failed and returned FALSE.
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Drupal\Core\Field\Plugin\Field\FieldType;
|
|||
|
||||
use Drupal\Core\Field\FieldItemBase;
|
||||
use Drupal\Core\Field\FieldStorageDefinitionInterface;
|
||||
use Drupal\Core\StringTranslation\TranslationWrapper;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
use Drupal\Core\TypedData\DataDefinition;
|
||||
|
||||
/**
|
||||
|
@ -31,9 +31,9 @@ abstract class StringItemBase extends FieldItemBase {
|
|||
*/
|
||||
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
|
||||
// This is called very early by the user entity roles field. Prevent
|
||||
// early t() calls by using the TranslationWrapper.
|
||||
// early t() calls by using the TranslatableMarkup.
|
||||
$properties['value'] = DataDefinition::create('string')
|
||||
->setLabel(new TranslationWrapper('Text value'))
|
||||
->setLabel(new TranslatableMarkup('Text value'))
|
||||
->setSetting('case_sensitive', $field_definition->getSetting('case_sensitive'))
|
||||
->setRequired(TRUE);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ use Drupal\Core\TypedData\DataDefinition;
|
|||
* label = @Translation("Timestamp"),
|
||||
* description = @Translation("An entity field containing a UNIX timestamp value."),
|
||||
* no_ui = TRUE,
|
||||
* default_widget = "datetime_default",
|
||||
* default_formatter = "timestamp",
|
||||
* constraints = {
|
||||
* "ComplexData" = {
|
||||
|
|
|
@ -73,7 +73,7 @@ class EntityReferenceAutocompleteWidget extends WidgetBase {
|
|||
|
||||
$operators = $this->getMatchOperatorOptions();
|
||||
$summary[] = t('Autocomplete matching: @match_operator', array('@match_operator' => $operators[$this->getSetting('match_operator')]));
|
||||
$summary[] = t('Textfield size: !size', array('!size' => $this->getSetting('size')));
|
||||
$summary[] = t('Textfield size: @size', array('@size' => $this->getSetting('size')));
|
||||
$placeholder = $this->getSetting('placeholder');
|
||||
if (!empty($placeholder)) {
|
||||
$summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
|
||||
|
@ -120,7 +120,7 @@ class EntityReferenceAutocompleteWidget extends WidgetBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function errorElement(array $element, ConstraintViolationInterface $error, array $form, FormStateInterface $form_state) {
|
||||
return $element['target_id'];
|
||||
return isset($element['target_id']) ? $element['target_id'] : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Drupal\Core\Field\Plugin\Field\FieldWidget;
|
||||
|
||||
use Drupal\Core\Field\FieldFilteredString;
|
||||
use Drupal\Core\Field\FieldFilteredMarkup;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\WidgetBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
@ -102,11 +102,11 @@ class NumberWidget extends WidgetBase {
|
|||
// Add prefix and suffix.
|
||||
if ($field_settings['prefix']) {
|
||||
$prefixes = explode('|', $field_settings['prefix']);
|
||||
$element['#field_prefix'] = FieldFilteredString::create(array_pop($prefixes));
|
||||
$element['#field_prefix'] = FieldFilteredMarkup::create(array_pop($prefixes));
|
||||
}
|
||||
if ($field_settings['suffix']) {
|
||||
$suffixes = explode('|', $field_settings['suffix']);
|
||||
$element['#field_suffix'] = FieldFilteredString::create(array_pop($suffixes));
|
||||
$element['#field_suffix'] = FieldFilteredMarkup::create(array_pop($suffixes));
|
||||
}
|
||||
|
||||
return array('value' => $element);
|
||||
|
|
|
@ -18,6 +18,7 @@ use Drupal\Core\Form\FormStateInterface;
|
|||
* label = @Translation("Check boxes/radio buttons"),
|
||||
* field_types = {
|
||||
* "boolean",
|
||||
* "entity_reference",
|
||||
* "list_integer",
|
||||
* "list_float",
|
||||
* "list_string",
|
||||
|
|
|
@ -18,6 +18,7 @@ use Drupal\Core\Form\FormStateInterface;
|
|||
* id = "options_select",
|
||||
* label = @Translation("Select list"),
|
||||
* field_types = {
|
||||
* "entity_reference",
|
||||
* "list_integer",
|
||||
* "list_float",
|
||||
* "list_string"
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Drupal\Core\Field\Plugin\Field\FieldWidget;
|
|||
|
||||
use Drupal\Core\Entity\FieldableEntityInterface;
|
||||
use Drupal\Core\Field\FieldDefinitionInterface;
|
||||
use Drupal\Core\Field\FieldFilteredString;
|
||||
use Drupal\Core\Field\FieldFilteredMarkup;
|
||||
use Drupal\Core\Field\FieldItemListInterface;
|
||||
use Drupal\Core\Field\WidgetBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
@ -73,7 +73,7 @@ abstract class OptionsWidgetBase extends WidgetBase {
|
|||
*/
|
||||
public static function validateElement(array $element, FormStateInterface $form_state) {
|
||||
if ($element['#required'] && $element['#value'] == '_none') {
|
||||
$form_state->setError($element, t('!name field is required.', array('!name' => $element['#title'])));
|
||||
$form_state->setError($element, t('@name field is required.', array('@name' => $element['#title'])));
|
||||
}
|
||||
|
||||
// Massage submitted form values.
|
||||
|
@ -191,7 +191,7 @@ abstract class OptionsWidgetBase extends WidgetBase {
|
|||
*/
|
||||
protected function sanitizeLabel(&$label) {
|
||||
// Allow a limited set of HTML tags.
|
||||
$label = FieldFilteredString::create($label);
|
||||
$label = FieldFilteredMarkup::create($label);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -60,7 +60,7 @@ class StringTextareaWidget extends WidgetBase {
|
|||
public function settingsSummary() {
|
||||
$summary = array();
|
||||
|
||||
$summary[] = t('Number of rows: !rows', array('!rows' => $this->getSetting('rows')));
|
||||
$summary[] = t('Number of rows: @rows', array('@rows' => $this->getSetting('rows')));
|
||||
$placeholder = $this->getSetting('placeholder');
|
||||
if (!empty($placeholder)) {
|
||||
$summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
|
||||
|
|
|
@ -60,7 +60,7 @@ class StringTextfieldWidget extends WidgetBase {
|
|||
public function settingsSummary() {
|
||||
$summary = array();
|
||||
|
||||
$summary[] = t('Textfield size: !size', array('!size' => $this->getSetting('size')));
|
||||
$summary[] = t('Textfield size: @size', array('@size' => $this->getSetting('size')));
|
||||
$placeholder = $this->getSetting('placeholder');
|
||||
if (!empty($placeholder)) {
|
||||
$summary[] = t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
|
||||
|
|
|
@ -60,7 +60,7 @@ class UriWidget extends WidgetBase {
|
|||
public function settingsSummary() {
|
||||
$summary = array();
|
||||
|
||||
$summary[] = $this->t('URI field size: !size', array('!size' => $this->getSetting('size')));
|
||||
$summary[] = $this->t('URI field size: @size', array('@size' => $this->getSetting('size')));
|
||||
$placeholder = $this->getSetting('placeholder');
|
||||
if (!empty($placeholder)) {
|
||||
$summary[] = $this->t('Placeholder: @placeholder', array('@placeholder' => $placeholder));
|
||||
|
|
|
@ -94,6 +94,16 @@ abstract class PluginSettingsBase extends PluginBase implements PluginSettingsIn
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getThirdPartySettings($module = NULL) {
|
||||
if ($module) {
|
||||
return isset($this->thirdPartySettings[$module]) ? $this->thirdPartySettings[$module] : NULL;
|
||||
}
|
||||
return $this->thirdPartySettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -109,6 +119,26 @@ abstract class PluginSettingsBase extends PluginBase implements PluginSettingsIn
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unsetThirdPartySetting($module, $key) {
|
||||
unset($this->thirdPartySettings[$module][$key]);
|
||||
// If the third party is no longer storing any information, completely
|
||||
// remove the array holding the settings for this module.
|
||||
if (empty($this->thirdPartySettings[$module])) {
|
||||
unset($this->thirdPartySettings[$module]);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getThirdPartyProviders() {
|
||||
return array_keys($this->thirdPartySettings);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -122,4 +152,17 @@ abstract class PluginSettingsBase extends PluginBase implements PluginSettingsIn
|
|||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function onDependencyRemoval(array $dependencies) {
|
||||
$changed = FALSE;
|
||||
if (!empty($this->thirdPartySettings) && !empty($dependencies['module'])) {
|
||||
$old_count = count($this->thirdPartySettings);
|
||||
$this->thirdPartySettings = array_diff_key($this->thirdPartySettings, array_flip($dependencies['module']));
|
||||
$changed = $old_count != count($this->thirdPartySettings);
|
||||
}
|
||||
return $changed;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
namespace Drupal\Core\Field;
|
||||
|
||||
use Drupal\Component\Plugin\PluginInspectionInterface;
|
||||
use Drupal\Core\Config\Entity\ThirdPartySettingsInterface;
|
||||
|
||||
/**
|
||||
* Interface definition for plugin with settings.
|
||||
*/
|
||||
interface PluginSettingsInterface extends PluginInspectionInterface {
|
||||
interface PluginSettingsInterface extends PluginInspectionInterface, ThirdPartySettingsInterface {
|
||||
|
||||
/**
|
||||
* Defines the default settings for this plugin.
|
||||
|
@ -65,34 +66,27 @@ interface PluginSettingsInterface extends PluginInspectionInterface {
|
|||
public function setSetting($key, $value);
|
||||
|
||||
/**
|
||||
* Returns the value of a third-party setting, or $default if not set.
|
||||
* Informs the plugin that some configuration it depends on will be deleted.
|
||||
*
|
||||
* @param string $module
|
||||
* The module providing the third-party setting.
|
||||
* @param string $key
|
||||
* The setting name.
|
||||
* @param mixed $default
|
||||
* (optional) The default value if the third party setting is not set.
|
||||
* Defaults to NULL.
|
||||
* This method allows plugins to keep their configuration up-to-date when a
|
||||
* dependency calculated with ::calculateDependencies() is removed. For
|
||||
* example, an entity view display contains a formatter having a setting
|
||||
* pointing to an arbitrary config entity. When that config entity is deleted,
|
||||
* this method is called by the view display to react to the dependency
|
||||
* removal by updating its configuration.
|
||||
*
|
||||
* @return mixed|NULL
|
||||
* The setting value. Returns NULL if the setting does not exist and
|
||||
* $default is not provided.
|
||||
* This method must return TRUE if the removal event updated the plugin
|
||||
* configuration or FALSE otherwise.
|
||||
*
|
||||
* @param array $dependencies
|
||||
* An array of dependencies that will be deleted keyed by dependency type.
|
||||
* Dependency types are 'config', 'content', 'module' and 'theme'.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the plugin configuration has changed, FALSE if not.
|
||||
*
|
||||
* @see \Drupal\Core\Entity\EntityDisplayBase
|
||||
*/
|
||||
public function getThirdPartySetting($module, $key, $default = NULL);
|
||||
|
||||
/**
|
||||
* Sets the value of a third-party setting for the plugin.
|
||||
*
|
||||
* @param string $module
|
||||
* The module providing the third-party setting.
|
||||
* @param string $key
|
||||
* The setting name.
|
||||
* @param mixed $value
|
||||
* The setting value.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setThirdPartySetting($module, $key, $value);
|
||||
public function onDependencyRemoval(array $dependencies);
|
||||
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface
|
|||
$delta = isset($get_delta) ? $get_delta : 0;
|
||||
$element = array(
|
||||
'#title' => $this->fieldDefinition->getLabel(),
|
||||
'#description' => FieldFilteredString::create(\Drupal::token()->replace($this->fieldDefinition->getDescription())),
|
||||
'#description' => FieldFilteredMarkup::create(\Drupal::token()->replace($this->fieldDefinition->getDescription())),
|
||||
);
|
||||
$element = $this->formSingleElement($items, $delta, $element, $form, $form_state);
|
||||
|
||||
|
@ -164,7 +164,7 @@ abstract class WidgetBase extends PluginSettingsBase implements WidgetInterface
|
|||
}
|
||||
|
||||
$title = $this->fieldDefinition->getLabel();
|
||||
$description = FieldFilteredString::create(\Drupal::token()->replace($this->fieldDefinition->getDescription()));
|
||||
$description = FieldFilteredMarkup::create(\Drupal::token()->replace($this->fieldDefinition->getDescription()));
|
||||
|
||||
$elements = array();
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ class WidgetPluginManager extends DefaultPluginManager {
|
|||
// If no widget is specified, use the default widget.
|
||||
if (!isset($configuration['type'])) {
|
||||
$field_type = $this->fieldTypeManager->getDefinition($field_type);
|
||||
$configuration['type'] = $field_type['default_widget'];
|
||||
$configuration['type'] = isset($field_type['default_widget']) ? $field_type['default_widget'] : NULL;
|
||||
}
|
||||
// Filter out unknown settings, and fill in defaults for missing settings.
|
||||
$default_settings = $this->getDefaultSettings($configuration['type']);
|
||||
|
|
Reference in a new issue