From 3ff2526ebd7f536cc4326943d440d39a2b42bb7b Mon Sep 17 00:00:00 2001
From: Jeff Fortune <jeff.fortune@bixal.com>
Date: Thu, 23 May 2024 16:46:36 -0500
Subject: [PATCH] Issue #3207619 by MrPaulDriver, chike, NicholasS, DrupalDope,
 JFortune: Default image and custom file directory do not save

---
 src/Plugin/Field/FieldType/BgImgItem.php | 145 +++++++++++++----------
 1 file changed, 80 insertions(+), 65 deletions(-)

diff --git a/src/Plugin/Field/FieldType/BgImgItem.php b/src/Plugin/Field/FieldType/BgImgItem.php
index 96b66e3..8e9f4d1 100644
--- a/src/Plugin/Field/FieldType/BgImgItem.php
+++ b/src/Plugin/Field/FieldType/BgImgItem.php
@@ -13,8 +13,7 @@ use Drupal\image\Plugin\Field\FieldType\ImageItem;
  * @FieldType(
  *   id = "bg_img_field",
  *   label = @Translation("Background Image Field"),
- *   description = @Translation("Field for creating responsive background
- *   images."),
+ *   description = @Translation("Field for creating responsive background images."),
  *   default_widget = "bg_img_field_widget",
  *   default_formatter = "bg_img_field_formatter",
  *   list_class = "\Drupal\file\Plugin\Field\FieldType\FileFieldItemList",
@@ -43,8 +42,7 @@ class BgImgItem extends ImageItem {
   public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) {
     $elements = parent::storageSettingsForm($form, $form_state, $has_data);
 
-    // Remove title and alt from the setting form, they are not need
-    // in background images.
+    // Remove title and alt from the setting form, they are not needed in background images.
     unset($elements['default_image']['alt']);
     unset($elements['default_image']['title']);
 
@@ -56,11 +54,11 @@ class BgImgItem extends ImageItem {
    */
   public static function defaultFieldSettings() {
     $settings = parent::defaultFieldSettings();
-    // Change value of setting  set in image field.
+    // Change value of setting set in image field.
     $settings['file_extensions'] = "png jpg jpeg svg";
     $settings['alt_field'] = 0;
     $settings['alt_field_required'] = 0;
-    // Add the specific css settings.
+    // Add the specific CSS settings.
     $settings['css_settings']['css_selector'] = '';
     $settings['css_settings']['css_repeat'] = 'inherit';
     $settings['css_settings']['css_background_size'] = 'inherit';
@@ -109,19 +107,19 @@ class BgImgItem extends ImageItem {
 
     $properties['css_selector'] = DataDefinition::create('string')
       ->setLabel(t('CSS Selector'))
-      ->setDescription(t("CSS selector that will be used to place the background image. attribute."));
+      ->setDescription(t("CSS selector that will be used to place the background image."));
 
     $properties['css_repeat'] = DataDefinition::create('string')
       ->setLabel(t('CSS Repeat Property'))
-      ->setDescription(t("CSS attribute that set the repeating value of the background image."));
+      ->setDescription(t("CSS attribute that sets the repeating value of the background image."));
 
     $properties['css_background_size'] = DataDefinition::create('string')
       ->setLabel(t('CSS Background Size Property'))
-      ->setDescription(t("CSS attribute that set the background size value of the background image."));
+      ->setDescription(t("CSS attribute that sets the background size value of the background image."));
 
     $properties['css_background_position'] = DataDefinition::create('string')
       ->setLabel(t('CSS Background Position Property'))
-      ->setDescription(t("CSS attribute that set the background position value of the background image."));
+      ->setDescription(t("CSS attribute that sets the background position value of the background image."));
 
     $properties['hide_css_Settings'] = DataDefinition::create('boolean')
       ->setLabel(t("Hide CSS Settings"))
@@ -135,6 +133,7 @@ class BgImgItem extends ImageItem {
    */
   public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
     $parentElements = parent::fieldSettingsForm($form, $form_state);
+    
     // Unset fields from image field that will not be used.
     unset($parentElements['alt_field']);
     unset($parentElements['alt_field_required']);
@@ -145,10 +144,10 @@ class BgImgItem extends ImageItem {
     unset($parentElements['default_image']['title']);
 
     $elements['css_settings'] = [
-      '#type' => 'details',
-      '#title' => $this->t('CSS Settings'),
-      '#description' => $this->t('Set default CSS properties for the background image.'),
-      '#open' => FALSE,
+        '#type' => 'details',
+        '#title' => $this->t('CSS Settings'),
+        '#description' => $this->t('Set default CSS properties for the background image.'),
+        '#open' => FALSE,
     ];
 
     // Load tokens based on the entity type it is on.
@@ -157,79 +156,95 @@ class BgImgItem extends ImageItem {
     // Get defined settings.
     $css_option_settings = $this->getSetting('css_settings');
 
-    // The css selector input field needed to.
+    // The CSS selector input field.
     $elements['css_settings']['css_selector'] = [
-      '#type'             => 'textfield',
-      '#title'            => $this->t('Selector'),
-      '#description'      => $this->t('CSS Selector for background image.'),
-      '#default_value'    => $css_option_settings['css_selector'],
-      '#token_types'      => $token_types,
+        '#type'             => 'textfield',
+        '#title'            => $this->t('Selector'),
+        '#description'      => $this->t('CSS Selector for background image.'),
+        '#default_value'    => $css_option_settings['css_selector'],
+        '#token_types'      => $token_types,
     ];
 
-    // The tokens that are scoped for the selector input.
     $elements['css_settings']['tokens'] = [
-      '#theme'        => 'token_tree_link',
-      '#token_types'  => $token_types,
-      '#global_types' => TRUE,
-      '#show_nested'  => FALSE,
+        '#theme'        => 'token_tree_link',
+        '#token_types'  => $token_types,
+        '#global_types' => TRUE,
+        '#show_nested'  => FALSE,
     ];
 
     // User ability to select a background repeat option.
     $elements['css_settings']['css_repeat'] = [
-      '#type' => 'radios',
-      '#title' => $this->t('Repeat Options'),
-      '#description' => $this->t('Add the css no repeat value to the background image.'),
-      '#default_value' => $css_option_settings['css_repeat'],
-      '#options' => [
-        "inherit" => $this->t("inherit"),
-        "no-repeat" => $this->t("no-repeat"),
-        "repeat" => $this->t('repeat'),
-      ],
+        '#type' => 'radios',
+        '#title' => $this->t('Repeat Options'),
+        '#description' => $this->t('Add the css no repeat value to the background image.'),
+        '#default_value' => $css_option_settings['css_repeat'],
+        '#options' => [
+            "inherit" => $this->t("inherit"),
+            "no-repeat" => $this->t("no-repeat"),
+            "repeat" => $this->t('repeat'),
+        ],
     ];
 
     // User the ability to choose background size.
     $elements['css_settings']['css_background_size'] = [
-      '#type' => 'radios',
-      '#title' => $this->t('Background Size'),
-      '#description' => $this->t("Add the background size setting you would like for the image, use inherit for default."),
-      '#default_value' => $css_option_settings['css_background_size'],
-      '#options' => [
-        'inherit' => $this->t('inherit'),
-        'auto' => $this->t('auto'),
-        'cover' => $this->t('cover'),
-        'contain' => $this->t('contain'),
-        'initial' => $this->t('initial'),
-      ],
+        '#type' => 'radios',
+        '#title' => $this->t('Background Size'),
+        '#description' => $this->t("Add the background size setting you would like for the image, use inherit for default."),
+        '#default_value' => $css_option_settings['css_background_size'],
+        '#options' => [
+            'inherit' => $this->t('inherit'),
+            'auto' => $this->t('auto'),
+            'cover' => $this->t('cover'),
+            'contain' => $this->t('contain'),
+            'initial' => $this->t('initial'),
+        ],
     ];
 
     // User the ability to set the background position.
     $elements['css_settings']['css_background_position'] = [
-      '#type' => 'radios',
-      '#title' => $this->t('Background Position'),
-      '#description' => $this->t('Set a background position'),
-      '#default_value' => $css_option_settings['css_background_position'],
-      '#options' => [
-        "inherit" => $this->t("inherit"),
-        "left top" => $this->t("left top"),
-        "left center" => $this->t("left center"),
-        "left bottom" => $this->t("left bottom"),
-        "right top" => $this->t("right bottom"),
-        "right center" => $this->t("right center"),
-        "right bottom" => $this->t("right bottom"),
-        "center top" => $this->t("center top"),
-        "center center" => $this->t("center center"),
-        "center bottom" => $this->t("center bottom"),
-      ],
-      '#tree' => TRUE,
+        '#type' => 'radios',
+        '#title' => $this->t('Background Position'),
+        '#description' => $this->t('Set a background position'),
+        '#default_value' => $css_option_settings['css_background_position'],
+        '#options' => [
+            "inherit" => $this->t("inherit"),
+            "left top" => $this->t("left top"),
+            "left center" => $this->t("left center"),
+            "left bottom" => $this->t("left bottom"),
+            "right top" => $this->t("right bottom"),
+            "right center" => $this->t("right center"),
+            "right bottom" => $this->t("right bottom"),
+            "center top" => $this->t("center top"),
+            "center center" => $this->t("center center"),
+            "center bottom" => $this->t("center bottom"),
+        ],
+    ];
+
+    // File extensions input to allow dynamic extensions.
+    $elements['file_extensions'] = [
+        '#type' => 'textfield',
+        '#title' => $this->t('Allowed file extensions'),
+        '#default_value' => $this->getSetting('file_extensions'),
+        '#description' => $this->t('Separate extensions with a space or comma. Example: "png jpg jpeg svg webp".'),
     ];
 
     $elements['file_settings'] = [
-      '#type' => 'details',
-      '#title' => $this->t("File Settings"),
-      '#open' => FALSE,
+        '#type' => 'details',
+        '#title' => $this->t("File Settings"),
+        '#open' => FALSE,
     ] + $parentElements;
 
     return $elements;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function preSave() {
+    parent::preSave();
+
+    // Handle the custom file extensions setting before saving.
+    $extensions = preg_split('/[\s,]+/', $this->getSetting('file_extensions'));
+    $this->setSetting('file_extensions', implode(' ', array_filter($extensions)));
+  }
 }
-- 
GitLab