bridtv-8.x-1.x-dev/src/Plugin/Field/FieldWidget/BridtvIdWidget.php

src/Plugin/Field/FieldWidget/BridtvIdWidget.php
<?php

namespace Drupal\bridtv\Plugin\Field\FieldWidget;

use Drupal\bridtv\BridApiConsumer;
use Drupal\bridtv\BridInfoNegotiator;
use Drupal\bridtv\BridSerialization;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Video ID widget for Brid.TV videos.
 *
 * @FieldWidget(
 *   id = "bridtv_id",
 *   module = "bridtv",
 *   label = @Translation("Direct video ID input"),
 *   field_types = {
 *     "bridtv"
 *   }
 * )
 */
class BridtvIdWidget extends WidgetBase implements ContainerFactoryPluginInterface {

  /**
   * The Brid.TV API consumer service.
   *
   * @var \Drupal\bridtv\BridApiConsumer
   */
  protected $consumer;

  /**
   * The negotiator service.
   *
   * @var \Drupal\bridtv\BridInfoNegotiator
   */
  protected $negotiator;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $consumer = $container->get('bridtv.consumer');
    $negotiator = $container->get('bridtv.negotiator');
    return new static(
      $plugin_id,
      $plugin_definition,
      $configuration['field_definition'],
      $configuration['settings'],
      $configuration['third_party_settings'],
      $consumer,
      $negotiator
    );
  }

  /**
   * Constructs a BridtvIdWidget object.
   *
   * @param string $plugin_id
   *   The plugin_id for the widget.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   *   The definition of the field to which the widget is associated.
   * @param array $settings
   *   The widget settings.
   * @param array $third_party_settings
   *   Any third party settings.
   * @param \Drupal\bridtv\BridApiConsumer $brid_api
   *   The Brid.TV API service.
   * @param \Drupal\bridtv\BridInfoNegotiator $negotiator
   *   The Brid Info Negotiator.
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, BridApiConsumer $brid_api, BridInfoNegotiator $negotiator) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
    $this->consumer = $brid_api;
    $this->negotiator = $negotiator;
  }

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $values = $items->get($delta)->getValue();
    $element['video_id'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Video ID'),
      '#description' => !empty($values['video_id']) ? $this->t('You cannot change the video ID, as it might be used by others already.') :
      $this->t('The Video ID can be found inside the Url of the video when logged in at cms.brid.tv.<br/> Go to the videos section and view the detail page of your desired video.<br/>Example: <em>cms.brid.tv/videos/edit/<b>321</b></em>would mean that <b>321</b> is the actual video ID.'),
      '#default_value' => !empty($values['video_id']) ? $values['video_id'] : NULL,
      '#disabled' => !empty($values['video_id']),
    ];
    $element['player'] = [
      '#type' => 'select',
      '#title' => $this->t('Player'),
      '#options' => ['_use_default' => $this->t('- Use default -')] + $this->negotiator->getPlayersListOptions(),
      '#default_value' => !empty($values['player']) ? $values['player'] : '_use_default',
      '#description' => $this->t('Choose the player to use as default, when not specified otherwise.'),
    ];
    $element['#element_validate'][] = [get_class($this), 'validateElement'];
    return $element;
  }

  /**
   * Form validation handler for widget elements.
   *
   * @param array $element
   *   The form element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public static function validateElement(array $element, FormStateInterface $form_state) {
    /** @var \Drupal\Core\Entity\FieldableEntityInterface $entity */
    $entity = $form_state->getFormObject()->getEntity();
    $field = NULL;
    foreach ($entity->getFieldDefinitions() as $definition) {
      if ($definition->getType() == 'bridtv') {
        $field = $definition->getName();
        break;
      }
    }
    $id_as_input = (int) $element['video_id']['#value'];
    if (!$id_as_input) {
      $form_state->setError($element['video_id'], t('No valid number is given.'));
    }
    /** @var \Drupal\bridtv\BridApiConsumer $consumer */
    $consumer = \Drupal::service('bridtv.consumer');
    if ($consumer->isReady()) {
      if ($field) {
        $previous_id_value = !$entity->get($field)->isEmpty() ? $entity->get($field)->first()->get('video_id')->getValue() : NULL;
        if (!($id_as_input == $previous_id_value)) {
          $storage = \Drupal::entityTypeManager()->getStorage($entity->getEntityTypeId());
          $query = $storage->getQuery();
          $query->accessCheck(TRUE);
          $existing = $query->condition($field . '.video_id', $id_as_input)->range(0, 1)->execute();
          if (!empty($existing)) {
            $existing = reset($existing);
            $existing = $storage->load($existing);
            $form_state->setError($element['video_id'], t('There is already an <a href=":existing" target="_blank">existing @type entity</a> for the requested video Id.',
              [
                ':existing' => $existing->toUrl()->toString(),
                '@type' => $entity->getEntityType()->getLabel(),
              ]));
          }
        }
      }
      $data = $consumer->fetchVideoData($id_as_input);
      if (empty($data)) {
        $form_state->setError($element['video_id'], t(
          'No video was found at Brid.TV for the requested Id.'
        ));
      }
    }
    else {
      $form_state->setError($element['video_id'], t(
        'The Brid.TV API is not available.
        The Id thus cannot be matched to an existing video.
        Please contact the site administrator.'
      ));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
    $massaged = [];
    foreach ($values as $value) {
      if (!empty($value['video_id'])) {
        $data = $this->consumer->fetchVideoData($value['video_id']);
        if (!empty($data)) {
          $decoded = BridSerialization::decode($data);
          $player_id = NULL;
          if (!empty($value['player'])) {
            $players = $this->negotiator->getPlayersListOptions();
            if (isset($players[$value['player']])) {
              $player_id = $value['player'];
            }
          }
          $massaged[] = [
            'video_id' => $value['video_id'],
            'title' => !empty($decoded['Video']['name']) ? $decoded['Video']['name'] : NULL,
            'description' => !empty($decoded['Video']['description']) ? $decoded['Video']['description'] : NULL,
            'publish_date' => !empty($decoded['Video']['publish']) ? $decoded['Video']['publish'] : NULL,
            'player' => $player_id,
            'data' => $data,
          ];
        }
      }
    }
    return $massaged;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc