Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / entity_browser / src / Plugin / Field / FieldWidget / EntityReferenceBrowserWidget.php
index 0ac85bc8c671801ef2ceb622f45b6a6a7c17f8e8..719869ca67c90d35527155fa69f692195f6aaf01 100644 (file)
@@ -22,6 +22,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\Validator\ConstraintViolation;
 use Symfony\Component\Validator\ConstraintViolationListInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Session\AccountInterface;
 
 /**
  * Plugin implementation of the 'entity_reference' widget for entity browser.
@@ -68,6 +69,13 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
    */
   protected $moduleHandler;
 
+  /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
   /**
    * Constructs widget plugin.
    *
@@ -89,12 +97,15 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
    *   Field widget display plugin manager.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler service.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
    */
-  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, FieldWidgetDisplayManager $field_display_manager, ModuleHandlerInterface $module_handler) {
+  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, FieldWidgetDisplayManager $field_display_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user) {
     parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
     $this->entityTypeManager = $entity_type_manager;
     $this->fieldDisplayManager = $field_display_manager;
     $this->moduleHandler = $module_handler;
+    $this->currentUser = $current_user;
   }
 
   /**
@@ -110,7 +121,8 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
       $container->get('entity_type.manager'),
       $container->get('event_dispatcher'),
       $container->get('plugin.manager.entity_browser.field_widget_display'),
-      $container->get('module_handler')
+      $container->get('module_handler'),
+      $container->get('current_user')
     );
   }
 
@@ -118,15 +130,16 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
    * {@inheritdoc}
    */
   public static function defaultSettings() {
-    return array(
+    return [
       'entity_browser' => NULL,
       'open' => FALSE,
       'field_widget_display' => 'label',
       'field_widget_edit' => TRUE,
       'field_widget_remove' => TRUE,
+      'field_widget_replace' => FALSE,
       'field_widget_display_settings' => [],
       'selection_mode' => EntityBrowserElement::SELECTION_MODE_APPEND,
-    ) + parent::defaultSettings();
+    ] + parent::defaultSettings();
   }
 
   /**
@@ -165,7 +178,7 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
       '#default_value' => $this->getSetting('field_widget_display'),
       '#options' => $displays,
       '#ajax' => [
-        'callback' => array($this, 'updateSettingsAjax'),
+        'callback' => [$this, 'updateSettingsAjax'],
         'wrapper' => $id,
       ],
     ];
@@ -189,6 +202,13 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
       '#default_value' => $this->getSetting('field_widget_remove'),
     ];
 
+    $element['field_widget_replace'] = [
+      '#title' => $this->t('Display Replace button'),
+      '#description' => $this->t('This button will only be displayed if there is a single entity in the current selection.'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->getSetting('field_widget_replace'),
+    ];
+
     $element['open'] = [
       '#title' => $this->t('Show widget details as open by default'),
       '#description' => $this->t('If marked, the fieldset container that wraps the browser on the entity form will be loaded initially expanded.'),
@@ -354,21 +374,24 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
 
     // Enable entity browser if requirements for that are fulfilled.
     if (EntityBrowserElement::isEntityBrowserAvailable($selection_mode, $cardinality, count($ids))) {
+      $persistentData = $this->getPersistentData();
+
       $element['entity_browser'] = [
         '#type' => 'entity_browser',
         '#entity_browser' => $this->getSetting('entity_browser'),
         '#cardinality' => $cardinality,
         '#selection_mode' => $selection_mode,
         '#default_value' => $entities,
-        '#entity_browser_validators' => ['entity_type' => ['type' => $entity_type]],
+        '#entity_browser_validators' => $persistentData['validators'],
+        '#widget_context' => $persistentData['widget_context'],
         '#custom_hidden_id' => $hidden_id,
         '#process' => [
           ['\Drupal\entity_browser\Element\EntityBrowserElement', 'processEntityBrowser'],
           [get_called_class(), 'processEntityBrowser'],
         ],
       ];
-
     }
+
     $element['#attached']['library'][] = 'entity_browser/entity_reference';
 
     $field_parents = $element['#field_parents'];
@@ -405,18 +428,29 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
    */
   public static function updateWidgetCallback(array &$form, FormStateInterface $form_state) {
     $trigger = $form_state->getTriggeringElement();
+    $reopen_browser = FALSE;
     // AJAX requests can be triggered by hidden "target_id" element when
     // entities are added or by one of the "Remove" buttons. Depending on that
     // we need to figure out where root of the widget is in the form structure
     // and use this information to return correct part of the form.
+    $parents = [];
     if (!empty($trigger['#ajax']['event']) && $trigger['#ajax']['event'] == 'entity_browser_value_updated') {
       $parents = array_slice($trigger['#array_parents'], 0, -1);
     }
     elseif ($trigger['#type'] == 'submit' && strpos($trigger['#name'], '_remove_')) {
       $parents = array_slice($trigger['#array_parents'], 0, -static::$deleteDepth);
     }
+    elseif ($trigger['#type'] == 'submit' && strpos($trigger['#name'], '_replace_')) {
+      $parents = array_slice($trigger['#array_parents'], 0, -static::$deleteDepth);
+      // We need to re-open the browser. Instead of just passing "TRUE", send
+      // to the JS the unique part of the button's name that needs to be clicked
+      // on to relaunch the browser.
+      $reopen_browser = implode("-", array_slice($trigger['#parents'], 0, -static::$deleteDepth));
+    }
 
-    return NestedArray::getValue($form, $parents);
+    $parents = NestedArray::getValue($form, $parents);
+    $parents['#attached']['drupalSettings']['entity_browser_reopen_browser'] = $reopen_browser;
+    return $parents;
   }
 
   /**
@@ -484,13 +518,22 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
       $this->getSetting('field_widget_display_settings') + ['entity_type' => $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type')]
     );
 
+    $classes = ['entities-list'];
+    if ($this->fieldDefinition->getFieldStorageDefinition()->getCardinality() != 1) {
+      $classes[] = 'sortable';
+    }
+
+    // The "Replace" button will only be shown if this setting is enabled in the
+    // widget, and there is only one entity in the current selection.
+    $replace_button_access = $this->getSetting('field_widget_replace') && (count($entities) === 1);
+
     return [
       '#theme_wrappers' => ['container'],
-      '#attributes' => ['class' => ['entities-list']],
+      '#attributes' => ['class' => $classes],
       'items' => array_map(
-        function (ContentEntityInterface $entity, $row_id) use ($field_widget_display, $details_id, $field_parents) {
+        function (ContentEntityInterface $entity, $row_id) use ($field_widget_display, $details_id, $field_parents, $replace_button_access) {
           $display = $field_widget_display->view($entity);
-          $edit_button_access = $this->getSetting('field_widget_edit');
+          $edit_button_access = $this->getSetting('field_widget_edit') && $entity->access('update', $this->currentUser);
           if ($entity->getEntityTypeId() == 'file') {
             // On file entities, the "edit" button shouldn't be visible unless
             // the module "file_entity" is present, which will allow them to be
@@ -521,9 +564,27 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
               '#attributes' => [
                 'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
                 'data-row-id' => $row_id,
+                'class' => ['remove-button'],
               ],
               '#access' => (bool) $this->getSetting('field_widget_remove'),
             ],
+            'replace_button' => [
+              '#type' => 'submit',
+              '#value' => $this->t('Replace'),
+              '#ajax' => [
+                'callback' => [get_class($this), 'updateWidgetCallback'],
+                'wrapper' => $details_id,
+              ],
+              '#submit' => [[get_class($this), 'removeItemSubmit']],
+              '#name' => $this->fieldDefinition->getName() . '_replace_' . $entity->id() . '_' . $row_id . '_' . md5(json_encode($field_parents)),
+              '#limit_validation_errors' => [array_merge($field_parents, [$this->fieldDefinition->getName()])],
+              '#attributes' => [
+                'data-entity-id' => $entity->getEntityTypeId() . ':' . $entity->id(),
+                'data-row-id' => $row_id,
+                'class' => ['replace-button'],
+              ],
+              '#access' => $replace_button_access,
+            ],
             'edit_button' => [
               '#type' => 'submit',
               '#value' => $this->t('Edit'),
@@ -540,6 +601,9 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
                   ],
                 ],
               ],
+              '#attributes' => [
+                'class' => ['edit-button'],
+              ],
               '#access' => $edit_button_access,
             ],
           ];
@@ -561,6 +625,7 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor
       'validators' => [
         'entity_type' => ['type' => $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type')],
       ],
+      'widget_context' => [],
     ];
   }