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);
}
}
