Commit 458a4155 authored by Stephen Lucero's avatar Stephen Lucero
Browse files

Issue #3324889 by slucero, jordanpagewhite, mariohernandez: Media Selection...

Issue #3324889 by slucero, jordanpagewhite, mariohernandez: Media Selection Errors Without Media Type Configuration In Place
parent fd1305ad
Loading
Loading
Loading
Loading
+33 −7
Original line number Diff line number Diff line
@@ -147,6 +147,8 @@ class DrupalMediaEditor extends JSONEditor.AbstractEditor {

  build() {
    this.title = this.header = this.label = this.theme.getFormInputLabel(this.getTitle(), this.isRequired());
    this.input = this.theme.getFormInputField('text');
    this.button = this.getButton(this.path + '-media', 'upload', this.options.button_text);

    this.addUploader();
    this.addPreview();
@@ -266,10 +268,7 @@ class DrupalMediaEditor extends JSONEditor.AbstractEditor {
   */
  addUploader() {
    // Don't show uploader if this is readonly
    if(!this.schema.readOnly && !this.schema.readonly) {
      this.input = this.theme.getFormInputField('text');
      this.button = this.getButton(this.path + '-media', 'upload', this.options.button_text);

    if(this.shouldShowUploader()) {
      this.input.addEventListener('change', (e) => {
        e.preventDefault();
        e.stopPropagation();
@@ -284,6 +283,29 @@ class DrupalMediaEditor extends JSONEditor.AbstractEditor {
    }
  }

  /**
   * Test whether a media uploader button should be displayed.
   *
   * @returns {boolean}
   *   True if the uploader should be displayed. False otherwise.
   */
  shouldShowUploader() {
    let showUploader = true;

    // Don't show uploader if this is readonly
    if(this.schema.readOnly || this.schema.readonly) {
      showUploader = false;
    }

    // Don't show the uploader if no media types have been selected.
    let media_types = this.options.media_types;
    if (!media_types || media_types.length === 0) {
      showUploader = false;
    }

    return showUploader;
  }

  /**
   * Add the preview container for selected media.
   */
@@ -299,7 +321,7 @@ class DrupalMediaEditor extends JSONEditor.AbstractEditor {
    this.control = this.theme.getFormControl(this.label, this.input, this.preview);
    this.container.appendChild(this.control);

    if (this.button) {
    if (this.button && this.shouldShowUploader()) {
      this.container.appendChild(this.button);
    }

@@ -398,20 +420,24 @@ class DrupalImageUrlEditor extends DrupalMediaEditor {
  'use strict';
  Drupal.behaviors.patternkitEditorMediaLibrary = {
    attach: function (context, settings) {
      // Abort if a URL is not available for the media library opener.
      if (!window.JSONEditor || !settings.patternkitEditor.imageUrl || !settings.patternkitEditor.videoUrl) {
        return;
      }

      // Abort if configuration is missing for allowed media types.
      let mediaMapping = settings.patternkitEditor.mediaMapping;
      let image_options = {
        title: Drupal.t('Select image'),
        button_text: Drupal.t('Select/Upload image'),
        library_url: settings.patternkitEditor.imageUrl,
        media_types: settings.patternkitEditor.mediaMapping.image_types
        media_types: mediaMapping.image_types
      };
      let video_options = {
        title: Drupal.t('Select video'),
        button_text: Drupal.t('Select/Upload video'),
        library_url: settings.patternkitEditor.videoUrl,
        media_types: settings.patternkitEditor.mediaMapping.video_types
        media_types: mediaMapping.video_types
      }

      JSONEditor.defaults.options.drupal_image_media = image_options;
+35 −7
Original line number Diff line number Diff line
@@ -211,6 +211,8 @@ var DrupalMediaEditor = /*#__PURE__*/function (_JSONEditor$AbstractE) {
    key: "build",
    value: function build() {
      this.title = this.header = this.label = this.theme.getFormInputLabel(this.getTitle(), this.isRequired());
      this.input = this.theme.getFormInputField('text');
      this.button = this.getButton(this.path + '-media', 'upload', this.options.button_text);
      this.addUploader();
      this.addPreview();
    }
@@ -349,9 +351,7 @@ var DrupalMediaEditor = /*#__PURE__*/function (_JSONEditor$AbstractE) {
      var _this2 = this;

      // Don't show uploader if this is readonly
      if (!this.schema.readOnly && !this.schema.readonly) {
        this.input = this.theme.getFormInputField('text');
        this.button = this.getButton(this.path + '-media', 'upload', this.options.button_text);
      if (this.shouldShowUploader()) {
        this.input.addEventListener('change', function (e) {
          e.preventDefault();
          e.stopPropagation();
@@ -366,6 +366,31 @@ var DrupalMediaEditor = /*#__PURE__*/function (_JSONEditor$AbstractE) {
        });
      }
    }
    /**
     * Test whether a media uploader button should be displayed.
     *
     * @returns {boolean}
     *   True if the uploader should be displayed. False otherwise.
     */

  }, {
    key: "shouldShowUploader",
    value: function shouldShowUploader() {
      var showUploader = true; // Don't show uploader if this is readonly

      if (this.schema.readOnly || this.schema.readonly) {
        showUploader = false;
      } // Don't show the uploader if no media types have been selected.


      var media_types = this.options.media_types;

      if (!media_types || media_types.length === 0) {
        showUploader = false;
      }

      return showUploader;
    }
    /**
     * Add the preview container for selected media.
     */
@@ -384,7 +409,7 @@ var DrupalMediaEditor = /*#__PURE__*/function (_JSONEditor$AbstractE) {
      this.control = this.theme.getFormControl(this.label, this.input, this.preview);
      this.container.appendChild(this.control);

      if (this.button) {
      if (this.button && this.shouldShowUploader()) {
        this.container.appendChild(this.button);
      }

@@ -528,21 +553,24 @@ var DrupalImageUrlEditor = /*#__PURE__*/function (_DrupalMediaEditor3) {

  Drupal.behaviors.patternkitEditorMediaLibrary = {
    attach: function attach(context, settings) {
      // Abort if a URL is not available for the media library opener.
      if (!window.JSONEditor || !settings.patternkitEditor.imageUrl || !settings.patternkitEditor.videoUrl) {
        return;
      }
      } // Abort if configuration is missing for allowed media types.


      var mediaMapping = settings.patternkitEditor.mediaMapping;
      var image_options = {
        title: Drupal.t('Select image'),
        button_text: Drupal.t('Select/Upload image'),
        library_url: settings.patternkitEditor.imageUrl,
        media_types: settings.patternkitEditor.mediaMapping.image_types
        media_types: mediaMapping.image_types
      };
      var video_options = {
        title: Drupal.t('Select video'),
        button_text: Drupal.t('Select/Upload video'),
        library_url: settings.patternkitEditor.videoUrl,
        media_types: settings.patternkitEditor.mediaMapping.video_types
        media_types: mediaMapping.video_types
      };
      JSONEditor.defaults.options.drupal_image_media = image_options;
      JSONEditor.defaults.options.drupal_image_url = image_options;
+19 −7
Original line number Diff line number Diff line
@@ -28,14 +28,26 @@ function patternkit_media_library_requirements($phase) {
  if (empty($mapping) || empty($mapping['image_types']) || empty($mapping['video_types'])) {
    $link = Link::createFromRoute(t('here'), 'patternkit.settings.media_library');

    $requirements['patternkit_media_library_media_type_mapping'] = [
      'title' => t('Patternkit Media Library Media Type Mapping'),
      'description' => t('Patternkit Media Library settings are missing media type selections for selectable image and video types. This may be configured @link.', [
    if (empty($mapping['image_types'])) {
      $requirements['patternkit_media_library_image_media_type_mapping'] = [
        'title' => t('Missing Patternkit Media Library Image Media Type Mapping'),
        'description' => t('Patternkit Media Library settings are missing configuration for selectable image media types. This may be configured @link. Until this is configured, image media will not be selectable in Patternkit blocks.', [
          '@link' => $link->toString(),
        ]),
      'severity' => REQUIREMENT_WARNING,
        'severity' => REQUIREMENT_INFO,
      ];
    }

    if (empty($mapping['video_types'])) {
      $requirements['patternkit_media_library_video_media_type_mapping'] = [
        'title' => t('Missing Patternkit Media Library Video Media Type Mapping'),
        'description' => t('Patternkit Media Library settings are missing configuration for selectable video media types. This may be configured @link. Until this is configured, video media will not be selectable in Patternkit blocks.', [
          '@link' => $link->toString(),
        ]),
        'severity' => REQUIREMENT_INFO,
      ];
    }
  }

  return $requirements;
}
+2 −1
Original line number Diff line number Diff line
@@ -26,7 +26,8 @@ function patternkit_media_library_form_layout_builder_configure_block_alter(&$fo

    // Expose media/field type mapping configuration to drive allowed types in
    // media modals.
    $form_attached['drupalSettings']['patternkitEditor']['mediaMapping'] = $config->get('media_mapping');
    $media_mapping = $config->get('media_mapping') ?? ['image_types' => [], 'video_types' => []];
    $form_attached['drupalSettings']['patternkitEditor']['mediaMapping'] = $media_mapping;

    $form['settings']['configuration']['#attached'] = $form_attached;
  }
+101 −10
Original line number Diff line number Diff line
@@ -80,16 +80,7 @@ class JsonEditorMediaSelectionTest extends PatternkitMediaLibraryBrowserTestBase
    $this->video->save();

    // Configure media library mapping settings for Patternkit.
    $config = $this->config(MediaLibrarySettingsForm::SETTINGS);
    $config->set('media_mapping', [
      'image_types' => [
        'image',
      ],
      'video_types' => [
        'dummy_file',
      ],
    ]);
    $config->save();
    $this->setMediaMappingConfiguration(['image'], ['dummy_file']);

    $this->editorUser = $this->drupalCreateUser($this->editorPermissions);
    $this->drupalLogin($this->editorUser);
@@ -404,4 +395,104 @@ class JsonEditorMediaSelectionTest extends PatternkitMediaLibraryBrowserTestBase
    $assert->elementExists('css', '.patternkit-media-image-embed--component img');
  }

  /**
   * Test media selection for images without selected image media types.
   */
  public function testImageMediaSelectionWithoutConfiguration(): void {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();

    // Configure without any selected image bundles.
    $this->setMediaMappingConfiguration([]);

    $pattern_name = '[Patternkit] Media image embed';
    $field_name = 'root[image]';

    // Override the Node layout and place a patternkit block.
    $this->drupalGet('node/1/layout');
    $page->clickLink('Add block');

    // Wait for the block list to load before selecting a pattern to insert.
    $assert->waitForLink($pattern_name)->click();

    // Wait for the JSON Editor form to load.
    $assert->waitForField($field_name);

    // Wait and confirm the upload button was not added.
    $assert->assertNoElementAfterWait('css', 'div[data-schemapath="root.image"] button');
  }

  /**
   * Test media selection for image urls without selected image media types.
   */
  public function testImageUrlSelectionWithoutConfiguration(): void {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();

    // Configure without any selected image bundles.
    $this->setMediaMappingConfiguration([]);

    $pattern_name = '[Patternkit] Example';
    $field_name = 'root[image_url]';

    // Override the Node layout and place a patternkit block.
    $this->drupalGet('node/1/layout');
    $page->clickLink('Add block');

    // Wait for the block list to load before selecting a pattern to insert.
    $assert->waitForLink($pattern_name)->click();

    // Wait for the JSON Editor form to load.
    $assert->waitForField($field_name);

    // Wait and confirm the upload button was not added.
    $assert->assertNoElementAfterWait('css', 'div[data-schemapath="root.image_url"] button');
  }

  /**
   * Test media selection for video media without selected video media types.
   */
  public function testVideoMediaSelectionWithoutConfiguration(): void {
    $assert = $this->assertSession();
    $page = $this->getSession()->getPage();

    // Configure without any selected video bundles.
    $this->setMediaMappingConfiguration([], []);

    $pattern_name = '[Patternkit] Media video embed';
    $field_name = 'root[video]';

    // Override the Node layout and place a patternkit block.
    $this->drupalGet('node/1/layout');
    $page->clickLink('Add block');

    // Wait for the block list to load before selecting a pattern to insert.
    $assert->waitForLink($pattern_name)->click();

    // Wait for the JSON Editor form to load.
    $assert->waitForField($field_name);

    // Wait and confirm the upload button was not added.
    $assert->assertNoElementAfterWait('css', 'div[data-schemapath="root.video"] button');
  }

  /**
   * Set configuration for selectable media types in Patternkit patterns.
   *
   * @param string[] $image_types
   *   (Optional) An array of media bundle keys to save as selectable media
   *   types for image fields.
   * @param string[] $video_types
   *   (Optional) An array of media bundle keys to save as selectable media
   *   types for video fields.
   */
  protected function setMediaMappingConfiguration(array $image_types = [], array $video_types = []): void {
    $config = $this->config(MediaLibrarySettingsForm::SETTINGS);
    $config->set('media_mapping', [
      'image_types' => $image_types,
      'video_types' => $video_types,
    ]);
    $config->save();
  }

}