aero_weather-1.0.3/src/Form/SettingsForm.php

src/Form/SettingsForm.php
<?php

namespace Drupal\aero_weather\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Component\Utility\UrlHelper;

/**
 * Provides a configuration form for Aero Weather settings.
 *
 * This form allows site administrators to configure settings for the Aero
 * Weather module.
 * It includes options to set the API key, manage caching, and customize
 * the icon styles for various weather elements (humidity, wind,
 * precipitation, etc.).
 * The form also allows the upload of weather icons, input of icon URLs,
 * or the use of font icons based on the selected style.
 */
class SettingsForm extends ConfigFormBase {

  /**
   * The file entity storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $fileStorage;

  /**
   * Constructs a new CartReminderSettingsForm.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager service.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->fileStorage = $entity_type_manager->getStorage('file');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return 'aero_weather_settings_form';
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames(): array {
    return ['aero_weather.settings'];
  }

  /**
   * {@inheritdoc}
   *
   * Builds the Aero Weather settings form with sections for:
   * - API key configuration
   * - Cache settings (enable/disable, cache duration, cache unit)
   * - Icon style management (select between default, uploaded, URL,
   * or font icons)
   */
  public function buildForm(array $form, FormStateInterface $form_state): array {
    $config = $this->config('aero_weather.settings');

    // API Key configuration.
    $form['aero_weather_api_key'] = [
      '#type' => 'textfield',
      '#title' => $this->t('API Key'),
      '#description' => $this->t('Enter your WeatherAPI API key here to fetch weather data. You can get your API key from <a href="https://www.weatherapi.com/my/" target="_blank">WeatherAPI</a>.'),
      '#default_value' => $config->get('api_key'),
      '#required' => TRUE,
    ];

    // Cache settings fieldset.
    $form['aero_weather_cache'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Cache Settings'),
    ];

    $form['aero_weather_cache']['aero_weather_cache_enabled'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable API Data Caching'),
      '#description' => $this->t('Enable caching to store weather data for a specified duration to improve performance.'),
      '#default_value' => $config->get('cache_enabled'),
    ];

    $form['aero_weather_cache']['aero_weather_cache_time'] = [
      '#type' => 'number',
      '#min' => 1,
      '#title' => $this->t('Cache Duration'),
      '#description' => $this->t('Define the duration for which weather data should be cached.'),
      '#default_value' => $config->get('cache_time') ?: 1,
      '#states' => [
        'visible' => [
          ':input[name="aero_weather_cache_enabled"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['aero_weather_cache']['aero_weather_cache_unit'] = [
      '#type' => 'select',
      '#title' => $this->t('Cache Unit'),
      '#options' => [
        'minutes' => $this->t('Minutes'),
        'hours' => $this->t('Hours'),
      ],
      '#description' => $this->t('Select the time unit for cache duration. You can choose between minutes or hours to define how long weather data should be stored in the cache before it expires.'),
      '#default_value' => $config->get('cache_unit') ?: 'hours',
      '#states' => [
        'visible' => [
          ':input[name="aero_weather_cache_enabled"]' => ['checked' => TRUE],
        ],
      ],
    ];

    // Icon Style Settings section.
    $form['icon_style_settings'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Icon Settings'),
    ];

    // Icon style selection.
    $form['icon_style_settings']['icon_style'] = [
      '#type' => 'select',
      '#title' => $this->t('Icon Style'),
      '#description' => $this->t('Choose the style of icons to use for weather elements.'),
      '#options' => [
        'default' => $this->t('Default icons'),
        'upload_url' => $this->t('Upload icon'),
        'url' => $this->t('File URL'),
        'font' => $this->t('Font icons'),
      ],
      '#default_value' => $config->get('icon_style') ?? 'default',
    ];

    // List of weather elements for which icons will be configured.
    $icon_elements = [
      'humidity', 'pressure', 'wind', 'uv_index', 'precipitation',
      'clouds', 'visibility', 'sunrise', 'sunset',
    ];

    // Loop through each weather element to provide options for uploading
    // or URL input for icons.
    foreach ($icon_elements as $element) {

      // Upload container for icon upload.
      $form['icon_style_settings']["{$element}_upload_container"] = [
        '#type' => 'container',
        '#states' => [
          'visible' => [
            ':input[name="icon_style"]' => ['value' => 'upload_url'],
          ],
        ],
      ];
      $form['icon_style_settings']["{$element}_upload_container"]["{$element}_upload"] = [
        '#type' => 'managed_file',
        '#title' => $this->t('@label Icon', ['@label' => ucwords(str_replace('_', ' ', $element))]),
        '#description' => $this->t('Upload an icon image for the weather element.'),
        '#upload_location' => 'public://aero_weather_icons/',
        '#default_value' => $config->get("{$element}_upload"),
        '#upload_validators'  => [
          'FileExtension' => ['extensions' => 'png jpg jpeg gif svg webp'],
        ],
      ];
      // URL container for file URL input.
      $form['icon_style_settings']["{$element}_url_container"] = [
        '#type' => 'container',
        '#states' => [
          'visible' => [
            ':input[name="icon_style"]' => ['value' => 'url'],
          ],
        ],
      ];
      $form['icon_style_settings']["{$element}_url_container"]["{$element}_url"] = [
        '#type' => 'textfield',
        '#title' => $this->t('@label Icon URL', ['@label' => ucwords(str_replace('_', ' ', $element))]),
        '#description' => $this->t('Provide the full URL of the @label icon image for the weather element.', ['@label' => ucwords(str_replace('_', ' ', $element))]),
        '#default_value' => $config->get("{$element}_url"),
      ];
      // Font icon container for icon name input.
      $form['icon_style_settings']["{$element}_font_container"] = [
        '#type' => 'container',
        '#states' => [
          'visible' => [
            ':input[name="icon_style"]' => ['value' => 'font'],
          ],
        ],
      ];
      $form['icon_style_settings']["{$element}_font_container"]["{$element}_font"] = [
        '#type' => 'textfield',
        '#title' => $this->t('@label Font Icon', ['@label' => ucwords(str_replace('_', ' ', $element))]),
        '#description' => $this->t('Enter the font icon element for the @label weather element, such as <i class="fa fa-book"></i> for FontAwesome or other icon class names from libraries like FontAwesome, Flaticon, etc.', ['@label' => ucwords(str_replace('_', ' ', $element))]),
        '#default_value' => $config->get("{$element}_font"),
      ];
    }

    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state): void {
    // Validate cache time.
    if ($form_state->getValue('aero_weather_cache_enabled')) {
      $cache_time = $form_state->getValue('aero_weather_cache_time');
      if (!is_numeric($cache_time) || $cache_time <= 0) {
        $form_state->setErrorByName('aero_weather_cache_time', $this->t('Cache duration must be a positive number.'));
      }
    }

    $icon_elements = [
      'humidity', 'pressure', 'wind', 'uv_index', 'precipitation',
      'clouds', 'visibility', 'sunrise', 'sunset',
    ];

    $icon_style = $form_state->getValue('icon_style');

    foreach ($icon_elements as $element) {
      // Validate URL fields.
      if ($icon_style === 'url') {
        $url = $form_state->getValue([$element . '_url']);
        if (!empty($url)) {
          if (!UrlHelper::isValid($url, TRUE)) {
            $form_state->setErrorByName("{$element}_url", $this->t('The URL provided for @element is not valid.', ['@element' => ucwords(str_replace('_', ' ', $element))]));
          }
          elseif (!str_starts_with($url, 'https://')) {
            $form_state->setErrorByName("{$element}_url", $this->t('Only HTTPS URLs are allowed for @element.', ['@element' => ucwords(str_replace('_', ' ', $element))]));
          }
        }
      }

      // Optional: Validate font icon strings for basic character safety.
      if ($icon_style === 'font') {
        $font_icon = $form_state->getValue([$element . '_font']);
        if (!empty($font_icon) && mb_strlen($font_icon) > 100) {
          $form_state->setErrorByName("{$element}_font", $this->t('Font icon class name for @element is too long.', ['@element' => ucwords(str_replace('_', ' ', $element))]));
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   *
   * Handles the form submission and saves the configuration.
   * Also handles managing file uploads, URLs, and font icons for
   * weather elements.
   * If the icon style is changed, previously set icon values will be
   * cleared automatically.
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    $config = $this->config('aero_weather.settings');
    $icon_elements = [
      'humidity', 'pressure', 'wind', 'uv_index', 'precipitation',
      'clouds', 'visibility', 'sunrise', 'sunset',
    ];

    $icon_style = $form_state->getValue('icon_style');

    // Save general settings.
    $config->set('api_key', $form_state->getValue('aero_weather_api_key'))
      ->set('cache_enabled', $form_state->getValue('aero_weather_cache_enabled'))
      ->set('cache_time', $form_state->getValue('aero_weather_cache_time'))
      ->set('cache_unit', $form_state->getValue('cache_unit'))
      ->set('icon_style', $icon_style);

    foreach ($icon_elements as $element) {
      $old_fids = $config->get("{$element}_upload") ?? [];

      // Clear previously stored values for icon settings.
      $config->set("{$element}_upload", NULL)
        ->set("{$element}_url", NULL)
        ->set("{$element}_font", NULL);

      // Handle file upload (if any)
      $fid = $form_state->getValue(["{$element}_upload"]) ?? [];
      if (!empty($fid)) {
        $file = $this->fileStorage->load(reset($fid));
        if ($file) {
          $file->setPermanent();
          $file->save();
          $config->set("{$element}_upload", [$file->id()]);
        }
      }
      else {
        // Set old files as temporary.
        foreach ($old_fids as $old_fid) {
          $old_file = $this->fileStorage->load($old_fid);
          if ($old_file) {
            $old_file->setTemporary();
            $old_file->save();
          }
        }
      }

      // Save URL and font icon values.
      $config->set("{$element}_url", $form_state->getValue(["{$element}_url"]));
      $config->set("{$element}_font", $form_state->getValue(["{$element}_font"]));
    }

    // Save all changes.
    $config->save();
    parent::submitForm($form, $form_state);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc