Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
triogroup/trio_touchpoint / src / Element / MediaLibrary.php
Size: Mime:
<?php

namespace Drupal\trio_touchpoint\Element;

use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\FormElement;
use Drupal\entity_browser\Element\EntityBrowserElement;

/**
 * Provides a Media library form element.
 *
 * The #default_value accepted by this element is an ID of a media object.
 *
 * @FormElement("media_library")
 *
 * Usage can include the following components:
 *
 *   $element['image'] = [
 *     '#type' => 'media_library',
 *     '#allowed_bundles' => ['image'],
 *     '#title' => t('Upload your image'),
 *     '#default_value' => NULL|1,
 *     '#description' => t('Upload or select your profile image.'),
 *     '#cardinality' => -1|1,
 *   ];
 */
class MediaLibrary extends FormElement {

  /**
   * Expand the media_library_element into it's required sub-elements.
   *
   * @param array $element
   *   The base form element render array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state object.
   * @param array $complete_form
   *   The complete form render array.
   *
   * @return array
   *   The form element render array.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public static function processMediaLibrary(array &$element, FormStateInterface $form_state, array &$complete_form): array {
    $widget_key = $element['#delta'];
    $parents = $element['#parents'];
    $field_name = array_pop($parents);
    $id_suffix = $parents ? '-' . implode('-', $parents) : '';
    $wrapper_id = Html::getUniqueId('touchpoint-image-entity-browser-wrapper');
    $element = array_merge(
      $element,
      [
        '#target_bundles' => !empty($allowed_media_type_ids) ? $allowed_media_type_ids : FALSE,
        '#cardinality' => $element['#cardinality'] ?? 1,
        '#attributes' => [
          'id' => $wrapper_id,
          'class' => ['media-library-form-element'],
        ],
      ]
      );

    $entity_ids = '';
    $default_value = NULL;
    $entities = [];

    if (!empty($element['#value'])) {
      $default_value = $element['#value'];
    }
    if (isset($default_value['image']['target_id'])) {
      $entity_ids = $default_value['image']['target_id'];
    }
    else {
      $entity_ids = $default_value;
    }

    if (($trigger = $form_state->getTriggeringElement())) {
      $last_parent = end($trigger['#array_parents']);
      if (in_array($last_parent, ['entity_ids', 'remove'])) {

        // Ckeck if this element triggered the change.
        $id = (array_slice($trigger['#parents'], 4, 1));
        if ($id[0] == $widget_key) {
          if ($trigger['#type'] != 'submit') {
            $ids = $trigger['#value'];
            $entities = EntityBrowserElement::processEntityIds($ids);
          }
        }
      }
    }
    if (empty($entities) && !empty($entity_ids)) {
      $entities = EntityBrowserElement::processEntityIds($entity_ids);
    }

    $element['image'] = [
      '#type' => 'details',
      '#title' => t('Image'),
      '#open' => TRUE,
      '#weight' => 15,
      '#attributes' => [
        'id' => $wrapper_id,
      ],
      'target_id' => [
        '#type' => 'hidden',
        '#value' => implode(' ', array_map(
          function (EntityInterface $item) {
            return $item->getEntityTypeId() . ':' . $item->id();
          },
          $entities
        )),
      ],
    ];

    if (empty($entities)) {
      $element['image']['entity_browser'] = [
        '#type' => 'entity_browser',
        '#entity_browser' => 'media_bundle_image_browser',
        '#entity_browser_validators' => [
          'entity_type' => ['type' => 'media'],
        ],
        '#process' => [
          [
            '\Drupal\entity_browser\Element\EntityBrowserElement',
            'processEntityBrowser',
          ],
          [get_called_class(), 'processEntityBrowser'],
        ],
        '#cardinality' => 1,
        '#wrapper_id' => $wrapper_id,
      ];
    }
    if (!empty($entities)) {
      $entity = reset($entities);

      $result = [
        '#type' => 'container',
        'display' => \Drupal::entityTypeManager()->getViewBuilder($entity->getEntityTypeId())
          ->view($entity, 'default'),
      ];
      $result['operations'] = [
        'remove' => [
          '#type' => 'submit',
          '#value' => t('Remove'),
          '#name' => 'remove' . $field_name . '-' . $id_suffix,
          '#ajax' => [
            'callback' => [get_called_class(), 'updateCallback'],
            'wrapper' => $wrapper_id,
          ],
          '#submit' => [[get_called_class(), 'removeItemSubmit']],

        ],
      ];
      $element['image']['current'] = $result;
    }
    return $element;
  }

  /**
   * Render API callback: Processes the entity browser element.
   */
  public static function processEntityBrowser(&$element, FormStateInterface $form_state, &$complete_form) {
    $element['entity_ids']['#ajax'] = [
      'callback' => [get_called_class(), 'updateCallback'],
      'wrapper' => $element['#wrapper_id'],
      'event' => 'entity_browser_value_updated',
    ];
    return $element;
  }

  /**
   * AJAX callback: Re-renders the Entity Browser element.
   */
  public static function updateCallback(array &$form, FormStateInterface $form_state) {
    $trigger = $form_state->getTriggeringElement();
    if (isset($trigger['#type']) && $trigger['#type'] === 'submit') {
      $parents = array_slice($trigger['#array_parents'], 0, -3);
      $selection = NestedArray::getValue($form, $parents);
    }
    else {
      $parents = array_slice($trigger['#array_parents'], 0, -2);
      $selection = NestedArray::getValue($form, $parents);
    }
    return $selection;
  }

  /**
   * Submit callback for remove image buttons.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   *
   * @return mixed
   *   The updated form element.
   */
  public static function removeItemSubmit(array &$form, FormStateInterface &$form_state) {
    $triggering_element = $form_state->getTriggeringElement();
    $parents = array_slice($triggering_element['#array_parents'], 0, -4);
    $element = NestedArray::getValue($form, $parents);
    $user_input_parents = array_slice($triggering_element['#parents'], 0, -4);
    $element['#value'] = '';
    $element['#default_value'] = '';

    $form_state->setValueForElement($element, '');
    $user_input = $form_state->getUserInput();
    NestedArray::setValue($user_input, $user_input_parents, '');
    $form_state->setUserInput($user_input);
    $form_state->setValue($user_input_parents, '');

    $form_state->setRebuild(TRUE);
  }

  /**
   * Extract the proper portion of our default_value.
   *
   * @param array $element
   *   The render element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state object.
   * @param array $complete_form
   *   The complete form render array.
   */
  public static function elementValidateMediaLibrary(array &$element, FormStateInterface $form_state, array &$complete_form) {
    $value = NULL;

    if (!empty($element['#value'])) {
      $value = $element['#value'];

      if (isset($value['image']['target_id'])) {
        $value = $value['image']['target_id'];
      }
    }
    $form_state->setValueForElement($element, $value);
  }

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $class = get_class($this);

    return [
      '#input' => TRUE,
      '#tree' => TRUE,
      '#cardinality' => 1,
      '#allowed_bundles' => [],
      '#process' => [
        [$class, 'processAjaxForm'],
        [$class, 'processMediaLibrary'],
        [$class, 'processGroup'],
      ],
      '#pre_render' => [
        [$class, 'preRenderGroup'],
      ],

      '#element_validate' => [
        [$class, 'elementValidateMediaLibrary'],
      ],
      '#theme' => 'media_library_element',
    ];
  }

}