From f4bf934ff08521f7ae85786d2af5ac3efe14f6b6 Mon Sep 17 00:00:00 2001
From: Florent Torregrosa <florent.torregrosa@gmail.com>
Date: Tue, 11 Mar 2025 17:25:37 +0100
Subject: [PATCH 1/7] Issue #3512245 by grimreaper: Prop source to get
 background URL

---
 .../ui_patterns_settings.sources.schema.yml   |   8 +
 .../Source/MediaBackgroundImage.php           | 153 ++++++++++++++++++
 2 files changed, 161 insertions(+)
 create mode 100644 src/Plugin/UiPatterns/Source/MediaBackgroundImage.php

diff --git a/config/schema/ui_patterns_settings.sources.schema.yml b/config/schema/ui_patterns_settings.sources.schema.yml
index d26b260..64ce853 100644
--- a/config/schema/ui_patterns_settings.sources.schema.yml
+++ b/config/schema/ui_patterns_settings.sources.schema.yml
@@ -8,3 +8,11 @@ ui_patterns_source.media:
       mapping:
         media_library_selection:
           type: string
+
+ui_patterns_source.media_background_image:
+  type: mapping
+  label: 'Source: Media background image'
+  mapping:
+    media:
+      type: string
+      label: 'Media ID'
diff --git a/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php b/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
new file mode 100644
index 0000000..f619bde
--- /dev/null
+++ b/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
@@ -0,0 +1,153 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\ui_patterns_settings\Plugin\UiPatterns\Source;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
+use Drupal\Core\File\FileUrlGeneratorInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\file\FileInterface;
+use Drupal\image\ImageStyleInterface;
+use Drupal\media\MediaInterface;
+use Drupal\ui_patterns\Attribute\Source;
+use Drupal\ui_patterns\SourcePluginBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Plugin implementation of the source.
+ */
+#[Source(
+  id: 'media_background_image',
+  label: new TranslatableMarkup('Media: background image'),
+  description: new TranslatableMarkup('Background image URL from a media'),
+  prop_types: ['string', 'url']
+)]
+class MediaBackgroundImage extends SourcePluginBase {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected EntityTypeManagerInterface $entityTypeManager;
+
+  /**
+   * The file URL generator.
+   *
+   * @var \Drupal\Core\File\FileUrlGeneratorInterface
+   */
+  protected FileUrlGeneratorInterface $fileUrlGenerator;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
+    $plugin = parent::create($container, $configuration, $plugin_id, $plugin_definition);
+    $plugin->entityTypeManager = $container->get('entity_type.manager');
+    $plugin->fileUrlGenerator = $container->get('file_url_generator');
+    return $plugin;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultSettings(): array {
+    return [
+      'media' => NULL,
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropValue(): string {
+    if (!$this->moduleHandler->moduleExists('media')) {
+      return '';
+    }
+
+    /** @var string $mediaId */
+    $mediaId = $this->getSetting('media') ?? '';
+    if (!$mediaId) {
+      return '';
+    }
+
+    /** @var \Drupal\media\MediaStorage $mediaStorage */
+    $mediaStorage = $this->entityTypeManager->getStorage('media');
+    $media = $mediaStorage->load($mediaId);
+    if (!($media instanceof MediaInterface)) {
+      return '';
+    }
+
+    $fieldMapping = $this->propDefinition['allowed_bundles'] ?? [];
+    if (!isset($fieldMapping[$media->bundle()])) {
+      return '';
+    }
+
+    $fieldName = $fieldMapping[$media->bundle()];
+    if (!$media->hasField($fieldName)) {
+      return '';
+    }
+
+    $field = $media->get($fieldName);
+    if (!($field instanceof EntityReferenceFieldItemListInterface)) {
+      return '';
+    }
+
+    $imageStyle = $this->propDefinition['image_style'] ?? '';
+    foreach ($field->referencedEntities() as $file) {
+      if ($file instanceof FileInterface) {
+        $fileUri = $file->getFileUri();
+        if ($fileUri == NULL) {
+          return '';
+        }
+
+        if ($imageStyle !== '') {
+          $style = $this->entityTypeManager->getStorage('image_style')
+            ->load($imageStyle);
+          if (!($style instanceof ImageStyleInterface)) {
+            return '';
+          }
+          return $style->buildUrl($fileUri);
+        }
+        else {
+          return $this->fileUrlGenerator->transformRelative($this->fileUrlGenerator->generateString($fileUri));
+        }
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state): array {
+    $form = parent::settingsForm($form, $form_state);
+    if (!$this->moduleHandler->moduleExists('media_library_form_element')) {
+      $form['warning'] = [
+        '#theme' => 'status_messages',
+        '#message_list' => [
+          'error' => [
+            $this->t('You need to enable the Media Library Form Element module to use this source.'),
+          ],
+        ],
+      ];
+      return $form;
+    }
+
+    $bundles = [];
+    if (isset($this->propDefinition['allowed_bundles'])) {
+      $bundles = \array_keys($this->propDefinition['allowed_bundles']);
+    }
+
+    $form['media'] = [
+      '#type' => 'media_library',
+      '#allowed_bundles' => $bundles,
+      '#default_value' => $this->getSetting('media') ?? NULL,
+    ];
+    $this->addRequired($form['media']);
+    return $form;
+  }
+
+}
-- 
GitLab


From 0d15277bdba6cd2cb9a66597f95ba3ebe61590a9 Mon Sep 17 00:00:00 2001
From: Florent Torregrosa <florent.torregrosa@gmail.com>
Date: Tue, 11 Mar 2025 17:34:48 +0100
Subject: [PATCH 2/7] Issue #3512245 by grimreaper: Fix PHPStan

---
 src/Plugin/UiPatterns/Source/MediaBackgroundImage.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php b/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
index f619bde..64a24ff 100644
--- a/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
+++ b/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
@@ -117,6 +117,7 @@ class MediaBackgroundImage extends SourcePluginBase {
         }
       }
     }
+    return '';
   }
 
   /**
-- 
GitLab


From 1b441120805e5e65844da5f12c3ef81aef958386 Mon Sep 17 00:00:00 2001
From: Florent Torregrosa <florent.torregrosa@gmail.com>
Date: Mon, 17 Mar 2025 17:42:23 +0100
Subject: [PATCH 3/7] Issue #3512245 by grimreaper, pdureau: Prop source to get
 background URL

---
 .../ui_patterns_settings.sources.schema.yml   |   3 +
 .../Source/MediaBackgroundImage.php           | 126 +++++++++++++-----
 2 files changed, 94 insertions(+), 35 deletions(-)

diff --git a/config/schema/ui_patterns_settings.sources.schema.yml b/config/schema/ui_patterns_settings.sources.schema.yml
index 64ce853..33c13bd 100644
--- a/config/schema/ui_patterns_settings.sources.schema.yml
+++ b/config/schema/ui_patterns_settings.sources.schema.yml
@@ -16,3 +16,6 @@ ui_patterns_source.media_background_image:
     media:
       type: string
       label: 'Media ID'
+    image_style:
+      type: string
+      label: 'Image style'
diff --git a/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php b/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
index 64a24ff..0dd189d 100644
--- a/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
+++ b/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
@@ -23,7 +23,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
   id: 'media_background_image',
   label: new TranslatableMarkup('Media: background image'),
   description: new TranslatableMarkup('Background image URL from a media'),
-  prop_types: ['string', 'url']
+  prop_types: ['url']
 )]
 class MediaBackgroundImage extends SourcePluginBase {
 
@@ -57,6 +57,7 @@ class MediaBackgroundImage extends SourcePluginBase {
   public function defaultSettings(): array {
     return [
       'media' => NULL,
+      'image_style' => '',
     ];
   }
 
@@ -68,8 +69,14 @@ class MediaBackgroundImage extends SourcePluginBase {
       return '';
     }
 
-    /** @var string $mediaId */
     $mediaId = $this->getSetting('media') ?? '';
+    if (isset($mediaId['media_library_selection']) && !empty($mediaId['media_library_selection'])) {
+      $mediaId = $mediaId['media_library_selection'];
+    }
+    elseif (!is_string($mediaId)) {
+      $mediaId = FALSE;
+    }
+
     if (!$mediaId) {
       return '';
     }
@@ -81,43 +88,24 @@ class MediaBackgroundImage extends SourcePluginBase {
       return '';
     }
 
-    $fieldMapping = $this->propDefinition['allowed_bundles'] ?? [];
-    if (!isset($fieldMapping[$media->bundle()])) {
+    $fileUri = $this->getFileUri($media);
+    if (!$fileUri) {
       return '';
     }
 
-    $fieldName = $fieldMapping[$media->bundle()];
-    if (!$media->hasField($fieldName)) {
-      return '';
+    $imageStyle = $this->getSetting('image_style') ?? '';
+    $style = NULL;
+    if ($imageStyle !== '') {
+      $style = $this->entityTypeManager->getStorage('image_style')
+        ->load($imageStyle);
     }
 
-    $field = $media->get($fieldName);
-    if (!($field instanceof EntityReferenceFieldItemListInterface)) {
-      return '';
+    if ($style instanceof ImageStyleInterface) {
+      return $style->buildUrl($fileUri);
     }
-
-    $imageStyle = $this->propDefinition['image_style'] ?? '';
-    foreach ($field->referencedEntities() as $file) {
-      if ($file instanceof FileInterface) {
-        $fileUri = $file->getFileUri();
-        if ($fileUri == NULL) {
-          return '';
-        }
-
-        if ($imageStyle !== '') {
-          $style = $this->entityTypeManager->getStorage('image_style')
-            ->load($imageStyle);
-          if (!($style instanceof ImageStyleInterface)) {
-            return '';
-          }
-          return $style->buildUrl($fileUri);
-        }
-        else {
-          return $this->fileUrlGenerator->transformRelative($this->fileUrlGenerator->generateString($fileUri));
-        }
-      }
+    else {
+      return $this->fileUrlGenerator->transformRelative($this->fileUrlGenerator->generateString($fileUri));
     }
-    return '';
   }
 
   /**
@@ -137,9 +125,9 @@ class MediaBackgroundImage extends SourcePluginBase {
       return $form;
     }
 
-    $bundles = [];
-    if (isset($this->propDefinition['allowed_bundles'])) {
-      $bundles = \array_keys($this->propDefinition['allowed_bundles']);
+    $bundles = $this->getAllowedMediaBundles();
+    if (empty($bundles)) {
+      return $form;
     }
 
     $form['media'] = [
@@ -148,7 +136,75 @@ class MediaBackgroundImage extends SourcePluginBase {
       '#default_value' => $this->getSetting('media') ?? NULL,
     ];
     $this->addRequired($form['media']);
+
+    $imageStyles = $this->getAllowedImageStyles();
+    if (count($imageStyles) > 1) {
+      $form['image_style'] = [
+        '#type' => 'select',
+        '#title' => $this->t('Image style'),
+        '#options' => $imageStyles,
+        '#default_value' => $this->getSetting('image_style') ?? NULL,
+        '#empty_value' => '',
+        '#empty_option' => $this->t('None'),
+      ];
+    }
+    elseif (!empty($imageStyles)) {
+      $form['image_style'] = [
+        '#type' => 'value',
+        '#value' => array_shift($imageStyles),
+      ];
+    }
+
     return $form;
   }
 
+  /**
+   * Get the file URI of the background image.
+   *
+   * @param \Drupal\media\MediaInterface $media
+   *   The referenced media.
+   *
+   * @return string
+   *   The file URI or empty string of not found.
+   */
+  protected function getFileUri(MediaInterface $media): string {
+    foreach ($media->referencedEntities() as $file) {
+      if ($file instanceof FileInterface) {
+        $fileUri = $file->getFileUri();
+        if (is_string($fileUri)) {
+          return $fileUri;
+        }
+      }
+    }
+    return '';
+  }
+
+  /**
+   * Get the allowed media bundles.
+   *
+   * @return array
+   *   The media bundles.
+   */
+  protected function getAllowedMediaBundles(): array {
+    $bundles = [];
+    foreach ($this->entityTypeManager->getStorage('media_type')->loadMultiple() as $mediaType) {
+      $bundles[] = $mediaType->id();
+    }
+    return $bundles;
+  }
+
+  /**
+   * Get the allowed image styles.
+   *
+   * @return array
+   *   The image styles.
+   */
+  protected function getAllowedImageStyles(): array {
+    $imageStyles = [];
+    foreach ($this->entityTypeManager->getStorage('image_style')->loadMultiple() as $style) {
+      $imageStyles[$style->id()] = $style->label();
+    }
+    return $imageStyles;
+  }
+
 }
-- 
GitLab


From df9335ed537cae4279c7f7f2e0df7772e6cfc87f Mon Sep 17 00:00:00 2001
From: Florent Torregrosa <florent.torregrosa@gmail.com>
Date: Mon, 17 Mar 2025 17:43:00 +0100
Subject: [PATCH 4/7] Issue #3512245 by grimreaper, pdureau: Prop source to get
 background URL

---
 src/Plugin/UiPatterns/Source/MediaBackgroundImage.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php b/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
index 0dd189d..c16e1e0 100644
--- a/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
+++ b/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
@@ -5,7 +5,6 @@ declare(strict_types=1);
 namespace Drupal\ui_patterns_settings\Plugin\UiPatterns\Source;
 
 use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
 use Drupal\Core\File\FileUrlGeneratorInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
-- 
GitLab


From a133e22c4953bbdcd1d6bf7e99bb4499c5012ee4 Mon Sep 17 00:00:00 2001
From: Florent Torregrosa <florent.torregrosa@gmail.com>
Date: Mon, 17 Mar 2025 17:53:21 +0100
Subject: [PATCH 5/7] Issue #3512245 by grimreaper, pdureau: Prop source to get
 background URL

---
 .../Source/MediaBackgroundImage.php           | 26 +++++++++++++------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php b/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
index c16e1e0..9f0060f 100644
--- a/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
+++ b/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
@@ -68,14 +68,7 @@ class MediaBackgroundImage extends SourcePluginBase {
       return '';
     }
 
-    $mediaId = $this->getSetting('media') ?? '';
-    if (isset($mediaId['media_library_selection']) && !empty($mediaId['media_library_selection'])) {
-      $mediaId = $mediaId['media_library_selection'];
-    }
-    elseif (!is_string($mediaId)) {
-      $mediaId = FALSE;
-    }
-
+    $mediaId = $this->getMediaId();
     if (!$mediaId) {
       return '';
     }
@@ -206,4 +199,21 @@ class MediaBackgroundImage extends SourcePluginBase {
     return $imageStyles;
   }
 
+  /**
+   * The referenced media ID.
+   *
+   * @return string
+   *   The media ID. Empty string if not found.
+   */
+  protected function getMediaId(): string {
+    $mediaId = $this->getSetting('media') ?? '';
+    if (isset($mediaId['media_library_selection']) && !empty($mediaId['media_library_selection'])) {
+      $mediaId = $mediaId['media_library_selection'];
+    }
+    elseif (!is_string($mediaId)) {
+      $mediaId = '';
+    }
+    return $mediaId;
+  }
+
 }
-- 
GitLab


From 6813f7d78a8b7cb1372ae485dde190c2d60c7904 Mon Sep 17 00:00:00 2001
From: Florent Torregrosa <florent.torregrosa@gmail.com>
Date: Tue, 18 Mar 2025 09:17:26 +0100
Subject: [PATCH 6/7] Issue #3512245 by grimreaper, pdureau: Prop source to get
 image URL

---
 config/schema/ui_patterns_settings.sources.schema.yml     | 4 ++--
 .../{MediaBackgroundImage.php => MediaImageUrl.php}       | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)
 rename src/Plugin/UiPatterns/Source/{MediaBackgroundImage.php => MediaImageUrl.php} (96%)

diff --git a/config/schema/ui_patterns_settings.sources.schema.yml b/config/schema/ui_patterns_settings.sources.schema.yml
index 33c13bd..fd94083 100644
--- a/config/schema/ui_patterns_settings.sources.schema.yml
+++ b/config/schema/ui_patterns_settings.sources.schema.yml
@@ -9,9 +9,9 @@ ui_patterns_source.media:
         media_library_selection:
           type: string
 
-ui_patterns_source.media_background_image:
+ui_patterns_source.media_image_url:
   type: mapping
-  label: 'Source: Media background image'
+  label: 'Source: Media image URL'
   mapping:
     media:
       type: string
diff --git a/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php b/src/Plugin/UiPatterns/Source/MediaImageUrl.php
similarity index 96%
rename from src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
rename to src/Plugin/UiPatterns/Source/MediaImageUrl.php
index 9f0060f..23d5756 100644
--- a/src/Plugin/UiPatterns/Source/MediaBackgroundImage.php
+++ b/src/Plugin/UiPatterns/Source/MediaImageUrl.php
@@ -19,12 +19,12 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  * Plugin implementation of the source.
  */
 #[Source(
-  id: 'media_background_image',
-  label: new TranslatableMarkup('Media: background image'),
-  description: new TranslatableMarkup('Background image URL from a media'),
+  id: 'media_image_url',
+  label: new TranslatableMarkup('Media: image URL'),
+  description: new TranslatableMarkup('Get an image URL from a media'),
   prop_types: ['url']
 )]
-class MediaBackgroundImage extends SourcePluginBase {
+class MediaImageUrl extends SourcePluginBase {
 
   /**
    * The entity type manager.
-- 
GitLab


From 288cfe2e0c6309d77591059ef45578bf99ae87ee Mon Sep 17 00:00:00 2001
From: Florent Torregrosa <florent.torregrosa@gmail.com>
Date: Tue, 18 Mar 2025 10:36:25 +0100
Subject: [PATCH 7/7] Issue #3512245 by grimreaper, pdureau: Prop source to get
 image URL

---
 src/Plugin/UiPatterns/Source/MediaImageUrl.php | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/Plugin/UiPatterns/Source/MediaImageUrl.php b/src/Plugin/UiPatterns/Source/MediaImageUrl.php
index 23d5756..1d49bad 100644
--- a/src/Plugin/UiPatterns/Source/MediaImageUrl.php
+++ b/src/Plugin/UiPatterns/Source/MediaImageUrl.php
@@ -93,7 +93,7 @@ class MediaImageUrl extends SourcePluginBase {
     }
 
     if ($style instanceof ImageStyleInterface) {
-      return $style->buildUrl($fileUri);
+      return $this->fileUrlGenerator->transformRelative($style->buildUrl($fileUri));
     }
     else {
       return $this->fileUrlGenerator->transformRelative($this->fileUrlGenerator->generateString($fileUri));
@@ -130,7 +130,13 @@ class MediaImageUrl extends SourcePluginBase {
     $this->addRequired($form['media']);
 
     $imageStyles = $this->getAllowedImageStyles();
-    if (count($imageStyles) > 1) {
+    if (empty($imageStyles)) {
+      $form['image_style'] = [
+        '#type' => 'value',
+        '#value' => '',
+      ];
+    }
+    else {
       $form['image_style'] = [
         '#type' => 'select',
         '#title' => $this->t('Image style'),
@@ -140,12 +146,6 @@ class MediaImageUrl extends SourcePluginBase {
         '#empty_option' => $this->t('None'),
       ];
     }
-    elseif (!empty($imageStyles)) {
-      $form['image_style'] = [
-        '#type' => 'value',
-        '#value' => array_shift($imageStyles),
-      ];
-    }
 
     return $form;
   }
-- 
GitLab