Loading config/schema/media_remote.schema.yml +15 −0 Original line number Diff line number Diff line Loading @@ -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' Loading media_remote.module +7 −0 Original line number Diff line number Diff line Loading @@ -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, Loading src/Plugin/Field/FieldFormatter/MediaRemoteNPRFormatter.php 0 → 100644 +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; } } templates/media-remote-npr.html.twig 0 → 100644 +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> tests/src/FunctionalJavascript/Formatters/NPRFormatterTest.php 0 → 100644 +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')); } } Loading
config/schema/media_remote.schema.yml +15 −0 Original line number Diff line number Diff line Loading @@ -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' Loading
media_remote.module +7 −0 Original line number Diff line number Diff line Loading @@ -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, Loading
src/Plugin/Field/FieldFormatter/MediaRemoteNPRFormatter.php 0 → 100644 +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; } }
templates/media-remote-npr.html.twig 0 → 100644 +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>
tests/src/FunctionalJavascript/Formatters/NPRFormatterTest.php 0 → 100644 +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')); } }