improvements-2.x-dev/modules/improvements_form/improvements_form.module
modules/improvements_form/improvements_form.module
<?php
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\Markup;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Template\Attribute;
use Drupal\druhels\DrupalHelper;
use Drupal\views\ViewExecutable;
require_once __DIR__ . '/improvements_form.tracking_submit.inc';
/**
* Implements hook_theme().
*/
function improvements_form_theme(): array {
return [
// Override system "select" template for add support attributes for "option" element
'select' => [
'render element' => 'element',
],
];
}
/**
* Implements hook_library_info_alter().
*/
function improvements_form_library_info_alter(array &$libraries, string $extension): void {
static $module_assets_path;
if (!$module_assets_path) {
$module_assets_path = '/' . \Drupal::service('extension.path.resolver')->getPath('module', 'improvements_form') . '/assets/';
}
if ($extension == 'core') {
$libraries['drupal.ajax']['js'][$module_assets_path . 'improvements.ajax.js'] = [];
$libraries['drupal.ajax']['js'][$module_assets_path . 'improvements.ajax-commands.js'] = [];
$libraries['drupal.dialog.ajax']['js'][$module_assets_path . 'improvements.dialog.ajax.js'] = [];
}
if ($extension == 'file') {
$libraries['drupal.file']['js'][$module_assets_path . 'improvements.file.js'] = [];
}
}
/**
* Implements hook_element_info_alter().
*/
function improvements_form_element_info_alter(array &$elements): void {
// Improvements managed_file element functionality
$elements['managed_file']['#pre_render'][] = '\Drupal\improvements_form\ImprovementsFormTrustedCallbacks::managedFilePreRender';
$elements['managed_file']['#process'][] = 'improvements_form_managed_file_process';
// Improvements textarea element functionality
$elements['textarea']['#attached']['library'][] = 'improvements_form/textarea';
}
/**
* Implements hook_form_alter().
*/
function improvements_form_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void {
// Add hidden value to forms in Dialog
if (in_array(\Drupal::request()->query->get('_wrapper_format'), ['drupal_modal', 'drupal_dialog'])) {
$form['_in_dialog'] = [
'#type' => 'hidden',
'#default_value' => 1,
'#weight' => 10000,
];
}
foreach (['form_build_id', 'form_token', 'form_id', 'antibot_key'] as $element_name) {
if (isset($form[$element_name])) {
// Move hidden system elements to form bottom
$form[$element_name]['#weight'] = 10000;
// Remove autocomplete attribute from system elements
unset($form[$element_name]['#attributes']['autocomplete']);
}
}
// Add class to views exposed form
if ($form_id == 'views_exposed_form') {
$view_executable = $form_state->get('view'); /** @var ViewExecutable $view_executable */
$form['#attributes']['class'][] = Html::getClass($view_executable->id()) . '-views-exposed-form';
}
improvements_form_tracking_submit_form_alter($form, $form_state, $form_id);
}
/**
* Preprocess function for captcha.html.twig.
*
* @TODO Remove after issue closed https://www.drupal.org/project/recaptcha/issues/2493183
*/
function improvements_form_preprocess_captcha(array &$vars): void {
// Attach js for improvements recaptcha functionality
if (
isset($vars['element']['#captcha_validate']) &&
$vars['element']['#captcha_validate'] == 'recaptcha_captcha_validation' &&
// https://www.drupal.org/project/recaptcha/issues/2493183#comment-15005511
!\Drupal::service('library.discovery')->getLibraryByName('recaptcha', 'recaptcha')
) {
$vars['#attached']['library'][] = 'improvements_form/recaptcha';
}
}
/**
* Preprocess function for input.html.twig.
*/
function improvements_form_preprocess_input(array &$vars): void {
// Implements new #title_display value "placeholder"
if (!empty($vars['element']['#title_display']) && $vars['element']['#title_display'] == 'placeholder') {
$vars['attributes']['placeholder'] = $vars['element']['#title'];
}
}
/**
* Implements hook_field_widget_single_element_WIDGET_TYPE_form_alter(): datetime_default.
*/
function improvements_form_field_widget_single_element_datetime_default_form_alter(array &$element, FormStateInterface $form_state, array $context): void {
// Remove wrapper from datetime widget
if (isset($element['#theme_wrappers'])) {
$element['#type'] = 'item';
$element['#theme_wrappers'] = array_diff($element['#theme_wrappers'], ['fieldset']);
$element['#theme_wrappers'][] = 'form_element';
}
}
/**
* Preprocess function for select.html.twig.
*/
function improvements_form_preprocess_select(array &$vars): void {
// Create attributes for each option
$options_attributes = $vars['element']['#options_attributes'] ?? [];
foreach ($vars['options'] as &$option) {
$option_attributes = [];
if (isset($option['value'])) {
$option_attributes = $options_attributes[$option['value']] ?? [];
$option_attributes['value'] = $option['value'];
}
if (!empty($option['selected'])) {
$option_attributes['selected'] = 'selected';
}
$option['attributes'] = new Attribute($option_attributes);
// Fallback for themes with overriden select.html.twig
if (isset($option['value'], $options_attributes[$option['value']])) {
$option_attributes = new Attribute($options_attributes[$option['value']]);
$option['value'] = Markup::create(Html::escape($option['value']) . '" ' . $option_attributes . ' data-drupal-empty="');
}
}
}
/**
* Managed file element #process callback.
*/
function improvements_form_managed_file_process(array &$element, FormStateInterface $form_state, array &$complete_form): array {
// Remove status message "Your upload has been renamed to ..."
DrupalHelper::removeStatusMessage(
MessengerInterface::TYPE_STATUS,
fn($message) => str_contains((string)$message, 'Your upload has been renamed to')
);
return $element;
}
/**
* Implements hook_field_widget_single_element_WIDGET_ID_form_alter(): file_generic.
*/
function improvements_form_field_widget_single_element_file_generic_form_alter(array &$element, FormStateInterface $form_state, array $context): void {
$element['#process'][] = 'improvements_form_file_generic_widget_process';
}
/**
* File widget #process callback.
*/
function improvements_form_file_generic_widget_process(array $element, FormStateInterface $form_state, array $form): array {
if (
isset($element['description']) &&
(string)$element['description']['#title'] == (string)(new TranslatableMarkup('Description'))
) {
$element['description']['#title'] = $element['#title'] . ' (' . t('description') . ')';
}
return $element;
}
/**
* Implements hook_field_widget_single_element_WIDGET_ID_form_alter(): image_image.
*/
function improvements_form_field_widget_single_element_image_image_form_alter(array &$element, FormStateInterface $form_state, array $context): void {
$element['#process'][] = 'improvements_form_image_widget_process';
}
/**
* Image widget #process callback.
*/
function improvements_form_image_widget_process(array $element, FormStateInterface $form_state, array $form): array {
if (isset($element['title'])) {
$element['title']['#weight'] = 1;
}
if (isset($element['alt'])) {
$element['alt']['#weight'] = 2;
}
return $element;
}
