You are here

class EntityBrowserElement in Entity Browser 8

Same name and namespace in other branches
  1. 8.2 src/Element/EntityBrowserElement.php \Drupal\entity_browser\Element\EntityBrowserElement

Provides an Entity Browser form element.

Properties:

  • #entity_browser: Entity browser or ID of the Entity browser to be used.
  • #cardinality: (optional) Maximum number of items that are expected from the entity browser. Unlimited by default.
  • #default_value: (optional) Array of entities that Entity browser should be initialized with. It's only applicable when edit selection mode is used.
  • #entity_browser_validators: (optional) Array of validators that are to be passed to the entity browser. Array keys are plugin IDs and array values are plugin configuration values. Cardinality validator will be set automatically.
  • #selection_mode: (optional) Determines how selection in entity browser will be handled. Will selection be appended/prepended or it will be replaced in case of editing. Defaults to append.
  • #widget_context: (optional) Widget configuration overrides which enable use cases where the instance of a widget needs awareness of contextual configuration like field settings.

Return value will be an array of selected entities, which will appear under 'entities' key on the root level of the element's values in the form state.

Plugin annotation

@FormElement("entity_browser");

Hierarchy

Expanded class hierarchy of EntityBrowserElement

10 files declare their use of EntityBrowserElement
Cardinality.php in src/Plugin/EntityBrowser/WidgetValidation/Cardinality.php
CardinalityTest.php in tests/src/FunctionalJavascript/CardinalityTest.php
EntityBrowserViewsWidgetTest.php in tests/src/FunctionalJavascript/EntityBrowserViewsWidgetTest.php
EntityReferenceBrowserWidget.php in src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php
EntityReferenceWidgetTest.php in tests/src/FunctionalJavascript/EntityReferenceWidgetTest.php

... See full list

3 #type uses of EntityBrowserElement
EntityReferenceBrowserWidget::formElement in src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php
Returns the form for a single field widget.
entity_browser_entity_form_inline_entity_form_reference_form_alter in modules/entity_form/entity_browser_entity_form.module
Implements hook_inline_entity_form_reference_form_alter().
FormElementTest::buildForm in tests/modules/entity_browser_test/src/Form/FormElementTest.php
Form constructor.

File

src/Element/EntityBrowserElement.php, line 37

Namespace

Drupal\entity_browser\Element
View source
class EntityBrowserElement extends FormElement {

  /**
   * Indicating an entity browser can return an unlimited number of values.
   *
   * Note: When entity browser is used in Fields, cardinality is directly
   * propagated from Field settings, that's why this constant should be equal to
   * FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED.
   */
  const CARDINALITY_UNLIMITED = -1;

  /**
   * Selection from entity browser will be appended to existing list.
   *
   * When this selection mode is used, then entity browser will not be
   * populated with existing selection. Preselected list will be empty.
   *
   * Note: This option is also used by "js/entity_browser.common.js".
   */
  const SELECTION_MODE_APPEND = 'selection_append';

  /**
   * Selection from entity browser will be prepended to existing list.
   *
   * When this selection mode is used, then entity browser will not be
   * populated with existing selection. Preselected list will be empty.
   *
   * Note: This option is also used by "js/entity_browser.common.js".
   */
  const SELECTION_MODE_PREPEND = 'selection_prepend';

  /**
   * Selection from entity browser will replace existing.
   *
   * When this selection mode is used, then entity browser will be populated
   * with existing selection and returned selected list will replace existing
   * selection. This option requires entity browser selection display with
   * preselection support.
   *
   * Note: This option is also used by "js/entity_browser.common.js".
   */
  const SELECTION_MODE_EDIT = 'selection_edit';

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $class = get_class($this);
    return [
      '#input' => TRUE,
      '#tree' => TRUE,
      '#cardinality' => static::CARDINALITY_UNLIMITED,
      '#selection_mode' => static::SELECTION_MODE_APPEND,
      '#process' => [
        [
          $class,
          'processEntityBrowser',
        ],
      ],
      '#default_value' => [],
      '#entity_browser_validators' => [],
      '#widget_context' => [],
      '#attached' => [
        'library' => [
          'entity_browser/common',
        ],
      ],
    ];
  }

  /**
   * Get selection mode options.
   *
   * @return array
   *   Selection mode options.
   */
  public static function getSelectionModeOptions() {
    return [
      static::SELECTION_MODE_APPEND => t('Append to selection'),
      static::SELECTION_MODE_PREPEND => t('Prepend selection'),
      static::SELECTION_MODE_EDIT => t('Edit selection'),
    ];
  }

  /**
   * Check whether entity browser should be available for selection of entities.
   *
   * @param string $selection_mode
   *   Used selection mode.
   * @param int $cardinality
   *   Used cardinality.
   * @param int $preselection_size
   *   Preseletion size, if it's available.
   *
   * @return bool
   *   Returns positive if entity browser can be used.
   */
  public static function isEntityBrowserAvailable($selection_mode, $cardinality, $preselection_size) {
    if ($selection_mode == static::SELECTION_MODE_EDIT) {
      return TRUE;
    }
    $cardinality_exceeded = $cardinality != static::CARDINALITY_UNLIMITED && $preselection_size >= $cardinality;
    return !$cardinality_exceeded;
  }

  /**
   * Render API callback: Processes the entity browser element.
   */
  public static function processEntityBrowser(&$element, FormStateInterface $form_state, &$complete_form) {

    /** @var \Drupal\entity_browser\EntityBrowserInterface $entity_browser */
    if (is_string($element['#entity_browser'])) {
      $entity_browser = EntityBrowser::load($element['#entity_browser']);
    }
    else {
      $entity_browser = $element['#entity_browser'];
    }

    // Propagate selection if edit selection mode is used.
    $entity_browser_preselected_entities = [];
    if ($element['#selection_mode'] === static::SELECTION_MODE_EDIT) {
      if ($entity_browser
        ->getSelectionDisplay()
        ->supportsPreselection()) {
        $entity_browser_preselected_entities = $element['#default_value'];
      }
      else {
        $field_element = NestedArray::getValue($complete_form, array_slice($element['#array_parents'], 0, -1));
        $tparams = [
          '@field_name' => !empty($field_element['#title']) ? $field_element['#title'] : $element['#custom_hidden_id'],
          '%selection_mode' => static::getSelectionModeOptions()[static::SELECTION_MODE_EDIT],
          '@browser_link' => $entity_browser
            ->toLink($entity_browser
            ->label(), 'edit-form')
            ->toString(),
        ];
        \Drupal::messenger()
          ->addWarning(t('There is a configuration problem with field "@field_name". The selection mode %selection_mode requires an entity browser with a selection display plugin that supports preselection.  Either change the selection mode or update the @browser_link entity browser to use a selection display plugin that supports preselection.', $tparams));
      }
    }
    $default_value = implode(' ', array_map(function (EntityInterface $item) {
      return $item
        ->getEntityTypeId() . ':' . $item
        ->id();
    }, $entity_browser_preselected_entities));
    $validators = array_merge($element['#entity_browser_validators'], [
      'cardinality' => [
        'cardinality' => $element['#cardinality'],
      ],
    ]);

    // Display error message if the entity browser was not found.
    if (!$entity_browser) {
      $element['entity_browser'] = [
        '#type' => 'markup',
        '#markup' => is_string($element['#entity_browser']) ? t('Entity browser @browser not found.', [
          '@browser' => $element['#entity_browser'],
        ]) : t('Entity browser not found.'),
      ];
    }
    else {
      $display = $entity_browser
        ->getDisplay();
      $display
        ->setUuid(sha1(implode('-', array_merge([
        $complete_form['#build_id'],
      ], $element['#parents']))));
      $element['entity_browser'] = [
        '#eb_parents' => array_merge($element['#parents'], [
          'entity_browser',
        ]),
      ];
      $element['entity_browser'] = $display
        ->displayEntityBrowser($element['entity_browser'], $form_state, $complete_form, [
        'validators' => $validators,
        'selected_entities' => $entity_browser_preselected_entities,
        'widget_context' => $element['#widget_context'],
      ]);
      $hidden_id = Html::getUniqueId($element['#id'] . '-target');
      $element['entity_ids'] = [
        '#type' => 'hidden',
        '#id' => $hidden_id,
        // We need to repeat ID here as it is otherwise skipped when rendering.
        '#attributes' => [
          'id' => $hidden_id,
          'class' => [
            'eb-target',
          ],
        ],
        '#default_value' => $default_value,
      ];
      $element['#attached']['drupalSettings']['entity_browser'] = [
        $entity_browser
          ->getDisplay()
          ->getUuid() => [
          'cardinality' => $element['#cardinality'],
          'selection_mode' => $element['#selection_mode'],
          'selector' => '#' . $hidden_id,
        ],
      ];
    }
    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
    if ($input === FALSE) {
      return $element['#default_value'] ?: [];
    }
    $entities = [];
    if ($input['entity_ids']) {
      $entities = static::processEntityIds($input['entity_ids']);
    }
    return [
      'entities' => $entities,
    ];
  }

  /**
   * Processes entity IDs and gets array of loaded entities.
   *
   * @param array|string $ids
   *   Processes entity IDs as they are returned from the entity browser. They
   *   are in [entity_type_id]:[entity_id] form. Array of IDs or a
   *   space-delimited string is supported.
   *
   * @return \Drupal\Core\Entity\EntityInterface[]
   *   Array of entity objects.
   */
  public static function processEntityIds($ids) {
    if (!is_array($ids)) {
      $ids = array_filter(explode(' ', $ids));
    }
    return array_map(function ($item) {
      list($entity_type, $entity_id) = explode(':', $item);
      $entity = \Drupal::entityTypeManager()
        ->getStorage($entity_type)
        ->load($entity_id);
      return \Drupal::service('entity.repository')
        ->getTranslationFromContext($entity);
    }, $ids);
  }

  /**
   * Processes entity IDs and gets array of loaded entities.
   *
   * @param string $id
   *   Processes entity ID as it is returned from the entity browser. ID should
   *   be in [entity_type_id]:[entity_id] form.
   *
   * @return \Drupal\Core\Entity\EntityInterface
   *   Entity object.
   */
  public static function processEntityId($id) {
    $return = static::processEntityIds([
      $id,
    ]);
    return current($return);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
EntityBrowserElement::CARDINALITY_UNLIMITED constant Indicating an entity browser can return an unlimited number of values.
EntityBrowserElement::getInfo public function Returns the element properties for this element. Overrides ElementInterface::getInfo
EntityBrowserElement::getSelectionModeOptions public static function Get selection mode options.
EntityBrowserElement::isEntityBrowserAvailable public static function Check whether entity browser should be available for selection of entities.
EntityBrowserElement::processEntityBrowser public static function Render API callback: Processes the entity browser element.
EntityBrowserElement::processEntityId public static function Processes entity IDs and gets array of loaded entities.
EntityBrowserElement::processEntityIds public static function Processes entity IDs and gets array of loaded entities.
EntityBrowserElement::SELECTION_MODE_APPEND constant Selection from entity browser will be appended to existing list.
EntityBrowserElement::SELECTION_MODE_EDIT constant Selection from entity browser will replace existing.
EntityBrowserElement::SELECTION_MODE_PREPEND constant Selection from entity browser will be prepended to existing list.
EntityBrowserElement::valueCallback public static function Determines how user input is mapped to an element's #value property. Overrides FormElement::valueCallback
FormElement::processAutocomplete public static function Adds autocomplete functionality to elements.
FormElement::processPattern public static function #process callback for #pattern form element property.
FormElement::validatePattern public static function #element_validate callback for #pattern form element property.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginBase::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. 92
RenderElement::preRenderAjaxForm public static function Adds Ajax information about an element to communicate with JavaScript.
RenderElement::preRenderGroup public static function Adds members of this group as actual elements for rendering.
RenderElement::processAjaxForm public static function Form element processing handler for the #ajax form property. 1
RenderElement::processGroup public static function Arranges elements into groups.
RenderElement::setAttributes public static function Sets a form element's class attribute. Overrides ElementInterface::setAttributes
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.