diff --git a/config/schema/ui_patterns_settings.sources.schema.yml b/config/schema/ui_patterns_settings.sources.schema.yml index d26b260542288cc9d019e564e3711165b7ac59df..fd940831072bb980feab1ff73781cd6ad24a1920 100644 --- a/config/schema/ui_patterns_settings.sources.schema.yml +++ b/config/schema/ui_patterns_settings.sources.schema.yml @@ -8,3 +8,14 @@ ui_patterns_source.media: mapping: media_library_selection: type: string + +ui_patterns_source.media_image_url: + type: mapping + label: 'Source: Media image URL' + mapping: + media: + type: string + label: 'Media ID' + image_style: + type: string + label: 'Image style' diff --git a/src/Plugin/UiPatterns/Source/MediaImageUrl.php b/src/Plugin/UiPatterns/Source/MediaImageUrl.php new file mode 100644 index 0000000000000000000000000000000000000000..1d49bad0222fadd266233807d75a5464a485ee11 --- /dev/null +++ b/src/Plugin/UiPatterns/Source/MediaImageUrl.php @@ -0,0 +1,219 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\ui_patterns_settings\Plugin\UiPatterns\Source; + +use Drupal\Core\Entity\EntityTypeManagerInterface; +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_image_url', + label: new TranslatableMarkup('Media: image URL'), + description: new TranslatableMarkup('Get an image URL from a media'), + prop_types: ['url'] +)] +class MediaImageUrl 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, + 'image_style' => '', + ]; + } + + /** + * {@inheritdoc} + */ + public function getPropValue(): string { + if (!$this->moduleHandler->moduleExists('media')) { + return ''; + } + + $mediaId = $this->getMediaId(); + if (!$mediaId) { + return ''; + } + + /** @var \Drupal\media\MediaStorage $mediaStorage */ + $mediaStorage = $this->entityTypeManager->getStorage('media'); + $media = $mediaStorage->load($mediaId); + if (!($media instanceof MediaInterface)) { + return ''; + } + + $fileUri = $this->getFileUri($media); + if (!$fileUri) { + return ''; + } + + $imageStyle = $this->getSetting('image_style') ?? ''; + $style = NULL; + if ($imageStyle !== '') { + $style = $this->entityTypeManager->getStorage('image_style') + ->load($imageStyle); + } + + if ($style instanceof ImageStyleInterface) { + return $this->fileUrlGenerator->transformRelative($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 = $this->getAllowedMediaBundles(); + if (empty($bundles)) { + return $form; + } + + $form['media'] = [ + '#type' => 'media_library', + '#allowed_bundles' => $bundles, + '#default_value' => $this->getSetting('media') ?? NULL, + ]; + $this->addRequired($form['media']); + + $imageStyles = $this->getAllowedImageStyles(); + if (empty($imageStyles)) { + $form['image_style'] = [ + '#type' => 'value', + '#value' => '', + ]; + } + else { + $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'), + ]; + } + + 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; + } + + /** + * 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; + } + +}