improvements-2.x-dev/modules/improvements_admin/improvements_admin.module
modules/improvements_admin/improvements_admin.module
<?php
use Drupal\block\Entity\Block;
use Drupal\block_content\BlockContentUuidLookup;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\SortArray;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\WidgetInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\Markup;
use Drupal\Core\Url;
use Drupal\druhels\ArrayHelper;
use Drupal\improvements\ImprovementsHelper;
/**
* Implements hook_form_FORM_ID_alter(): form_system_modules.
*/
function improvements_admin_form_system_modules_alter(array &$form, FormStateInterface $form_state): void {
// Add autofocus to modules filter input
if (isset($form['filters']['text'])) {
$form['filters']['text']['#attributes']['autofocus'] = TRUE;
}
}
/**
* Implements hook_field_widget_third_party_settings_form().
*/
function improvements_admin_field_widget_third_party_settings_form(WidgetInterface $widget, FieldDefinitionInterface $field_definition, string $form_mode, array $form, FormStateInterface $form_state): array {
$element = [];
$widget_plugin_id = $widget->getPluginId();
// "Long text" widgets
if (in_array($widget_plugin_id, ['text_textarea', 'text_textarea_with_summary'])) {
$element['max_length'] = [
'#type' => 'number',
'#title' => t('Max length'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'max_length'),
];
$element['dynamic_height'] = [
'#type' => 'checkbox',
'#title' => t('Dynamic height'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'dynamic_height'),
];
$element['disable_editor'] = [
'#type' => 'checkbox',
'#title' => t('Disable CKEditor'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'disable_editor'),
];
$element['hide_format_select'] = [
'#type' => 'checkbox',
'#title' => t('Hide format select'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'hide_format_select'),
];
$element['hide_label'] = [
'#type' => 'checkbox',
'#title' => t('Hide label'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'hide_label'),
];
}
// "Text textfield" widget
if ($widget_plugin_id == 'text_textfield') {
$element['hide_format_select'] = [
'#type' => 'checkbox',
'#title' => t('Hide format select'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'hide_format_select'),
];
$element['hide_label'] = [
'#type' => 'checkbox',
'#title' => t('Hide label'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'hide_label'),
];
}
// "String textfield" widget
if ($widget_plugin_id == 'string_textfield') {
$element['max_length'] = [
'#type' => 'number',
'#title' => t('Max length'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'max_length'),
];
$element['hide_label'] = [
'#type' => 'checkbox',
'#title' => t('Hide label'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'hide_label'),
];
}
// "E-mail" widget
if ($widget_plugin_id == 'email_default') {
$element['hide_label'] = [
'#type' => 'checkbox',
'#title' => t('Hide label'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'hide_label'),
];
}
// "File" widget
if ($widget_plugin_id == 'file_generic' || $widget_plugin_id == 'image_image') {
$element['autoupload'] = [
'#type' => 'checkbox',
'#title' => t('Auto upload'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'autoupload', TRUE),
];
$element['upload_button_state'] = [
'#type' => 'radios',
'#title' => t('Upload button state'),
'#options' => [
2 => t('Visually Hidden'),
1 => t('Visible'),
0 => t('Without button'),
],
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'upload_button_state', 2),
];
}
// "Single on/off checkbox" widget
if ($widget_plugin_id == 'boolean_checkbox') {
$element['custom_label'] = [
'#type' => 'textfield',
'#title' => t('Custom label'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'custom_label'),
];
}
// "Number field" widget
if ($widget_plugin_id == 'number') {
$element['size'] = [
'#type' => 'number',
'#title' => t('Input element size'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'size'),
];
}
// "Select list" widget
if ($widget_plugin_id == 'options_select') {
$element['empty_label'] = [
'#type' => 'textfield',
'#title' => t('Empty label'),
'#default_value' => $widget->getThirdPartySetting('improvements_admin', 'empty_label', '- Select a value -'),
];
}
return $element;
}
/**
* Implements hook_field_widget_single_element_form_alter().
*/
function improvements_admin_field_widget_single_element_form_alter(array &$element, FormStateInterface $form_state, array $context): void {
$widget = $context['widget']; /** @var WidgetInterface $widget */
$widget_plugin_id = $widget->getPluginId();
$third_party_settings = $widget->getThirdPartySettings('improvements_admin');
// Long text widgets
if ($widget_plugin_id == 'text_textarea' || $widget_plugin_id == 'text_textarea_with_summary') {
if (!empty($third_party_settings['max_length'])) {
$element['#maxlength'] = $third_party_settings['max_length'];
}
if (!empty($third_party_settings['dynamic_height'])) {
$element['#rows'] = ImprovementsHelper::getTextareaRowsCount((string)$element['#default_value'], (int)$element['#rows']);
}
if (!empty($third_party_settings['disable_editor'])) {
$element['#editor'] = FALSE;
}
if (!empty($third_party_settings['hide_format_select'])) {
$element['#after_build'][] = 'improvements_admin_hide_format_select';
}
}
// Text textfield widget
if ($widget_plugin_id == 'text_textfield') {
if (!empty($third_party_settings['max_length'])) {
$element['value']['#maxlength'] = $third_party_settings['max_length'];
}
if (!empty($third_party_settings['hide_format_select'])) {
$element['#after_build'][] = 'improvements_admin_hide_format_select';
}
}
// String textfield widget
if ($widget_plugin_id == 'string_textfield') {
if (!empty($third_party_settings['max_length'])) {
$element['value']['#maxlength'] = $third_party_settings['max_length'];
}
}
// File widget
if ($widget_plugin_id == 'file_generic' || $widget_plugin_id == 'image_image') {
$element['#autoupload'] = $third_party_settings['autoupload'] ?? TRUE;
$element['#upload_button_state'] = $third_party_settings['upload_button_state'] ?? 2;
}
// Metatags widget
if ($widget_plugin_id == 'metatag_firehose') {
// Close all details
foreach (Element::children($element) as $key) {
if (
isset($element[$key]['#type']) &&
$element[$key]['#type'] == 'details' &&
!empty($element[$key]['#open'])
) {
$element[$key]['#open'] = FALSE;
}
}
}
// "Single on/off checkbox" widget
if ($widget_plugin_id == 'boolean_checkbox') {
if (!empty($third_party_settings['custom_label'])) {
$element['#title'] = $third_party_settings['custom_label'];
$element['value']['#title'] = $third_party_settings['custom_label'];
}
}
// Number field widget
if ($widget_plugin_id == 'number') {
if (!empty($third_party_settings['size'])) {
$element['value']['#attributes']['style'] = "width:{$third_party_settings['size']}em;";
}
}
// "Select list" widget
if ($widget_plugin_id == 'options_select') {
if (isset($element['#options']['_none']) && !empty($third_party_settings['empty_label'])) {
$element['#options']['_none'] = t($third_party_settings['empty_label']);
}
}
// Hide label
if (!empty($third_party_settings['hide_label'])) {
$element['#title_display'] = 'invisible';
}
}
/**
* Formatted text element after build callback.
*/
function improvements_admin_hide_format_select(array $element, FormStateInterface $form_state): array {
if (isset($element['format'])) {
$element['format']['#attributes']['class'][] = 'visually-hidden';
}
return $element;
}
/**
* Implements hook_form_FORM_ID_alter(): block_admin_display_form.
*/
function improvements_admin_form_block_admin_display_form_alter(array &$form, FormStateInterface $form_state): void {
$block_content_uuid_lookup = \Drupal::service('block_content.uuid_lookup'); /** @var BlockContentUuidLookup $block_content_uuid_lookup */
$form['blocks']['#header'] = ArrayHelper::insertAfter($form['blocks']['#header'], 0, ['machine_name' => t('Machine name')]);
foreach (Element::children($form['blocks']) as $block_name) {
// Add link to edit block content in blocks layout page
if (isset($form['blocks'][$block_name]['operations'])) {
$block_plugin = Block::load($block_name)->getPlugin(); /** @var BlockPluginInterface $block_plugin */
if ($block_plugin->getBaseId() == 'block_content') {
$block_content_id = $block_content_uuid_lookup->get($block_plugin->getDerivativeId());
$form['blocks'][$block_name]['operations']['#links']['edit_content'] = [
'title' => t('Edit content'),
'url' => Url::fromRoute('entity.block_content.edit_form', ['block_content' => $block_content_id]),
'weight' => 20,
];
uasort($form['blocks'][$block_name]['operations']['#links'], '\Drupal\Component\Utility\SortArray::sortByWeightElement');
}
}
// Show block machine name
if (str_starts_with($block_name, 'region-')) {
$region_col_name = Element::children($form['blocks'][$block_name])[0];
$form['blocks'][$block_name][$region_col_name]['#wrapper_attributes']['colspan']++;
}
else {
$form['blocks'][$block_name] = ArrayHelper::insertAfter($form['blocks'][$block_name], 'info', [
'machine_name' => [
'#plain_text' => $block_name,
],
]);
}
}
}
/**
* Implements hook_form_FORM_ID_alter(): block_content_form.
*/
function improvements_admin_form_block_content_form_alter(array &$form, FormStateInterface $form_state): void {
// Add autofocus to content-block name field
if (isset($form['info']['widget'][0]['value'])) {
$form['info']['widget'][0]['value']['#attributes']['autofocus'] = TRUE;
}
}
/**
* Implements hook_contextual_links_alter().
*/
function improvements_admin_contextual_links_alter(array &$links, string $group, array $route_parameters): void {
// Change "content block" link from "Edit" to "Edit content"
// @see block_content.links.contextual.yml
if ($group == 'block_content' && isset($links['block_content.block_edit'])) {
$links['block_content.block_edit']['title'] = t('Edit content');
}
// Sort links by weight
uasort($links, [SortArray::class, 'sortByWeightElement']);
}
/**
* Implements hook_form_FORM_ID_alter(): entity_view_display_edit_form.
*/
function improvements_admin_form_entity_view_display_edit_form_alter(array &$form, FormStateInterface $form_state): void {
// Add field machine name to label
if (isset($form['fields'])) {
foreach (Element::children($form['fields']) as $key) {
if (isset($form['fields'][$key]['human_name'])) {
$form['fields'][$key]['human_name']['#suffix'] = Markup::create(' <span style="opacity:0.6;">(' . $key . ')</span>');
}
}
}
}
/**
* Implements hook_form_FORM_ID_alter(): entity_form_display_edit_form.
*/
function improvements_admin_form_entity_form_display_edit_form_alter(array &$form, FormStateInterface $form_state): void {
// Add field machine name to label
if (isset($form['fields'])) {
foreach (Element::children($form['fields']) as $key) {
if (isset($form['fields'][$key]['human_name'])) {
$form['fields'][$key]['human_name']['#suffix'] = Markup::create(' <span style="opacity:0.6;">(' . $key . ')</span>');
}
}
}
}
/**
* Implements hook_form_FORM_ID_alter(): filter_admin_overview.
*/
function improvements_admin_form_filter_admin_overview_alter(array &$form, FormStateInterface $form_state): void {
// Add filter id to table
$form['formats']['#header'] = ArrayHelper::insertAfter($form['formats']['#header'], 'label', ['id' => t('ID')]);
foreach (Element::children($form['formats']) as $key) {
$form['formats'][$key] = ArrayHelper::insertAfter($form['formats'][$key], 'label', [
'id' => [
'#plain_text' => $key,
]
]);
}
}
/**
* Implements hook_form_FORM_ID_alter(): backup_migrate_settings_form.
*/
function improvements_admin_form_backup_migrate_settings_form_alter(array &$form, FormStateInterface $form_state): void {
if (isset($form['config']['db_exclude']['exclude_tables'])) {
$form['config']['db_exclude']['exclude_tables']['#size'] = 15;
}
if (isset($form['config']['db_exclude']['nodata_tables'])) {
$form['config']['db_exclude']['nodata_tables']['#size'] = 15;
}
}
/**
* Implements hook_form_FORM_ID_alter(): devel_execute_form.
*/
function improvements_admin_form_devel_execute_form_alter(array &$form, FormStateInterface $form_state): void {
// Restore code from user data
if (!$form['execute']['code']['#default_value']) {
$form['execute']['code']['#default_value'] = \Drupal::service('user.data')->get('improvements', \Drupal::currentUser()->id(), 'devel_code');
}
array_unshift($form['#submit'], 'improvements_admin_form_devel_execute_form_submit');
}
/**
* Custom #submit callback for devel_execute_form.
*/
function improvements_admin_form_devel_execute_form_submit(array &$form, FormStateInterface $form_state): void {
// Save code in user data
if ($code = $form_state->getValue('code')) {
\Drupal::service('user.data')->set('improvements', \Drupal::currentUser()->id(), 'devel_code', $code);
}
}
/**
* Implements hook_form_FORM_ID_alter(): language_content_settings_form.
*/
function improvements_admin_form_language_content_settings_form_alter(array &$form, FormStateInterface $form_state): void {
foreach (Element::children($form['settings']) as $entity_type_id) {
$form['settings'][$entity_type_id]['#title'] .= " ({$form['settings'][$entity_type_id]['#entity_type']})";
foreach (Element::children($form['settings'][$entity_type_id]) as $bundle_name) {
$form['settings'][$entity_type_id][$bundle_name]['settings']['#label'] .= " ($bundle_name)";
if (!empty($form['settings'][$entity_type_id][$bundle_name]['fields'])) {
foreach (Element::children($form['settings'][$entity_type_id][$bundle_name]['fields']) as $field_name) {
$form['settings'][$entity_type_id][$bundle_name]['fields'][$field_name]['#label'] .= " ($field_name)";
}
}
}
}
}
/**
* Implements hook_form_FORM_ID_alter(): pathauto_pattern_form.
*/
function improvements_admin_form_pathauto_pattern_form_alter(array &$form, FormStateInterface $form_state): void {
// Increase size of pattern input
if (isset($form['pattern_container']['pattern'])) {
$form['pattern_container']['pattern']['#size'] = 100;
}
}
/**
* Implements hook_daily_cron().
*/
function improvements_admin_daily_cron(): void {
// Send watchdog errors to e-mail
$watchdog_settings = \Drupal::config('improvements_admin.watchdog_settings')->get();
if ($watchdog_settings['send_records_to_email']) {
$cront_last_run_timestamp = \Drupal::state()->get('system.cron_last');
$records = \Drupal::database()->select('watchdog', 'w')
->fields('w')
->condition('w.severity', RfcLogLevel::ERROR, '<=')
->condition('w.timestamp', $cront_last_run_timestamp, '>=')
->orderBy('w.wid')
->range(0, 100)
->execute()
->fetchAll();
if ($records) {
if ($watchdog_settings['send_records_email']) {
$email = \Drupal::token()->replace($watchdog_settings['send_records_email']);
}
else {
$email = ImprovementsHelper::getEmailForNotifications();
}
\Drupal::service('plugin.manager.mail')->mail('improvements', 'watchdog_records', $email, 'en', [
'records' => $records,
]);
}
}
}
/**
* Implements hook_mail().
*/
function improvements_admin_mail(string $key, array &$message, array $params): void {
if ($key == 'watchdog_records') {
$message['subject'] = t('Watchdog records');
$table_rows = [];
foreach ($params['records'] as $record) {
$record_variables = $record->variables ? @unserialize($record->variables) : [];
$record_message = new FormattableMarkup($record->message, $record_variables ?: []);
$table_rows[] = [
'type' => $record->type,
'date' => date('d.m.Y, H:i:s', $record->timestamp),
'message' => Unicode::truncate(strip_tags($record_message), 256, FALSE, TRUE),
'action' => Link::createFromRoute(t('Open', [], ['context' => 'Action']), 'dblog.event', ['event_id' => $record->wid]),
];
}
$table_build = [
'#theme' => 'table__watchdog_records',
'#header' => [
'type' => t('Type'),
'date' => t('Date'),
'message' => t('Message'),
'action' => t('Action'),
],
'#rows' => $table_rows,
'#attributes' => [
'class' => ['table'],
],
];
$message['body'][] = \Drupal::service('renderer')->render($table_build);
}
}
