Commit 6d983692 authored by git's avatar git Committed by Marcos Cano
Browse files

Issue #3265320 by GTR18, marcoscano: Add support for NPR

parent cbf06c7e
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -49,6 +49,21 @@ field.formatter.settings.media_remote_google:
      type: string
      label: 'Iframe height'

field.formatter.settings.media_remote_npr:
  type: mapping
  label: 'NPR display format settings'
  mapping:
    formatter_class:
      type: string
      label: 'Formatter class name'
    width:
      type: string
      label: 'Iframe width'
    height:
      type: string
      label: 'Iframe height'


field.formatter.settings.media_remote_quickbase:
  type: mapping
  label: 'Quickbase display format settings'
+7 −0
Original line number Diff line number Diff line
@@ -65,6 +65,13 @@ function media_remote_theme($existing, $type, $theme, $path) {
        'height' => NULL,
      ],
    ],
    'media_remote_npr' => [
      'variables' => [
        'url' => NULL,
        'width' => NULL,
        'height' => NULL,
      ],
    ],
    'media_remote_quickbase' => [
      'variables' => [
        'url' => NULL,
+126 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\media_remote\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;

/**
 * Plugin implementation of the 'media_remote_npr' formatter.
 *
 * @FieldFormatter(
 *   id = "media_remote_npr",
 *   label = @Translation("Remote Media - NPR"),
 *   field_types = {
 *     "string"
 *   }
 * )
 */
class MediaRemoteNPRFormatter extends MediaRemoteFormatterBase {

  /**
   * {@inheritdoc}
   */
  public static function getUrlRegexPattern() {
    return '/^https:\/\/livesessions\.npr\.org\/embed\/v2\/videos\/(-*.*)/';
  }

  /**
   * {@inheritdoc}
   */
  public static function getValidUrlExampleStrings(): array {
    return [
      'https://livesessions.npr.org/embed/v2/videos/[video-id]',
    ];
  }

  /**
   * {@inheritdoc}
   */
  public static function deriveMediaDefaultNameFromUrl($url) {
    $matches = [];
    $pattern = static::getUrlRegexPattern();
    preg_match_all($pattern, $url, $matches);
    if (!empty($matches[1][0])) {
      return t('NPR video from @url', [
        '@url' => $url,
      ]);
    }
    return parent::deriveMediaDefaultNameFromUrl($url);
  }

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    $elements = [];
    foreach ($items as $delta => $item) {
      /** @var \Drupal\Core\Field\FieldItemInterface $item */
      if ($item->isEmpty()) {
        continue;
      }
      $matches = [];
      $pattern = static::getUrlRegexPattern();
      preg_match_all($pattern, $item->value, $matches);
      if (empty($matches[1][0])) {
        continue;
      }
      $elements[$delta] = [
        '#theme' => 'media_remote_npr',
        '#url' => $item->value,
        '#width' => $this->getSetting('width') ?? 960,
        '#height' => $this->getSetting('height') ?? 600,
      ];
    }
    return $elements;
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return [
        'width' => 960,
        'height' => 600,
      ] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    return parent::settingsForm($form, $form_state) + [
        'width' => [
          '#type' => 'number',
          '#title' => $this->t('Width'),
          '#default_value' => $this->getSetting('width'),
          '#size' => 5,
          '#maxlength' => 5,
          '#field_suffix' => $this->t('pixels'),
          '#min' => 50,
        ],
        'height' => [
          '#type' => 'number',
          '#title' => $this->t('Height'),
          '#default_value' => $this->getSetting('height'),
          '#size' => 5,
          '#maxlength' => 5,
          '#field_suffix' => $this->t('pixels'),
          '#min' => 50,
        ],
      ];
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $summary = parent::settingsSummary();
    $summary[] = $this->t('Iframe size: %width x %height pixels', [
      '%width' => $this->getSetting('width'),
      '%height' => $this->getSetting('height'),
    ]);
    return $summary;
  }

}
+12 −0
Original line number Diff line number Diff line
{#
/**
 * @file
 * Template implementation for the media_remote_npr theme hook.
 *
 * Available variables:
 * - url: (string) The full URL to this document.
 * - width: (int) The width of the iframe, in pixels.
 * - height: (int) The height of the iframe, in pixels.
 */
#}
<iframe src="{{ url }}?embedded=true" width="{{ width }}" height="{{ height }}"></iframe>
+87 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\media_remote\FunctionalJavascript\Formatters;

use Drupal\Tests\media_remote\FunctionalJavascript\MediaRemoteFunctionalJavascriptTestBase;

/**
 * Tests the NPR formatter.
 *
 * @group media_remote
 */
class NPRFormatterTest extends MediaRemoteFunctionalJavascriptTestBase {

  /**
   * Tests the NPR formatter.
   */
  public function testNPR() {
    $assert_session = $this->assertSession();
    $session = $this->getSession();
    $page = $session->getPage();

    // Set the formatter on the media source field.
    $source_field_name = $this->mediaType->getSource()->getSourceFieldDefinition($this->mediaType)->getName();
    \Drupal::service('entity_display.repository')
      ->getViewDisplay('media', $this->mediaType->id(), 'default')
      ->setComponent($source_field_name, [
        'type' => 'media_remote_npr',
      ])
      ->save();

    $node_title = 'Node with a NPR media';
    $node = $this->drupalCreateNode([
      'type' => $this->nodeType->id(),
      'title' => $node_title,
    ]);
    $this->drupalGet($node->toUrl('edit-form'));
    $this->openMediaLibraryForField('field_node__remote_media');
    // Enter an invalid URL and check the error message.
    $assert_session->elementExists('css', '.media-library-widget-modal input[name="url"]')
      ->setValue('https://drupal.org');
    $assert_session->elementExists('css', '.media-library-widget-modal input[value="Add"]')
      ->press();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->pageTextContains("The given URL is not valid. Valid values are in the format: https://livesessions.npr.org/embed/v2/videos/[video-id]");
    // Enter a valid URL and save the media item.
    $assert_session->elementExists('css', '.media-library-widget-modal input[name="url"]')
      ->setValue('https://livesessions.npr.org/embed/v2/videos/fdf413b3-73be-432b-97b3-43261b3a1376');
    $assert_session->elementExists('css', '.media-library-widget-modal input[value="Add"]')
      ->press();
    $assert_session->assertWaitOnAjaxRequest();
    $assert_session->pageTextNotContains("The given URL is not valid");
    $media_name = 'NPR video from https://livesessions.npr.org/embed/v2/videos/fdf413b3-73be-432b-97b3-43261b3a1376';
    $name_input = $assert_session->waitForElement('css', '.media-library-widget-modal input[name="media[0][fields][name][0][value]"]');
    $this->assertNotNull($name_input);
    $this->assertSame($media_name, $name_input->getValue());
    // Save the modal and the node form.
    $this->pressSaveButton();
    $this->pressInsertSelected();
    $name_in_widget = $assert_session->elementExists('css', '.field--name-field-node__remote-media .media-library-item__name');
    $this->assertSame($media_name, $name_in_widget->getText());
    $page->pressButton('Save');
    $assert_session->pageTextContains("{$this->nodeType->label()} {$node_title} has been updated");
    $iframe = $assert_session->elementExists('css', 'article.node--type-node-type .field--name-field-media-media-remote iframe[src^="https://livesessions.npr.org/"]');
    // Assert the default size is applied, since we haven't configured any.
    $this->assertSame('960', (string) $iframe->getAttribute('width'));
    $this->assertSame('600', (string) $iframe->getAttribute('height'));
    // Change the formatter settings and verify the iframe resizes.
    $this->drupalGet("/admin/structure/media/manage/{$this->mediaType->id()}/display");
    $assert_session->elementExists('css', 'input[data-drupal-selector="edit-fields-field-media-media-remote-settings-edit"]')
      ->click();
    $width_element = $assert_session->waitForElement('css', 'input[data-drupal-selector="edit-fields-field-media-media-remote-settings-edit-form-settings-width"]');
    $width_element->setValue(1000);
    $height_element = $assert_session->elementExists('css', 'input[data-drupal-selector="edit-fields-field-media-media-remote-settings-edit-form-settings-height"]');
    $height_element->setValue(700);
    $assert_session->elementExists('css', 'input[data-drupal-selector="edit-fields-field-media-media-remote-settings-edit-form-actions-save-settings"]')
      ->click();
    $assert_session->assertWaitOnAjaxRequest();
    $page->pressButton('Save');
    $assert_session->pageTextContains('Your settings have been saved');
    $this->drupalGet($node->toUrl());
    $iframe = $assert_session->elementExists('css', 'article.node--type-node-type .field--name-field-media-media-remote iframe[src^="https://livesessions.npr.org/"]');
    $this->assertSame('1000', (string) $iframe->getAttribute('width'));
    $this->assertSame('700', (string) $iframe->getAttribute('height'));
  }

}