improvements-2.x-dev/improvements.module

improvements.module
<?php

use Drupal\block\BlockForm;
use Drupal\block\BlockInterface;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Template\AttributeHelper;
use Drupal\Core\Url;
use Drupal\druhels\ArrayHelper;
use Drupal\file\FileInterface;
use Drupal\improvements\ImprovementsHelper;

/**
 * Implements hook_theme().
 */
function improvements_theme(): array {
  return [
    'simple_field' => [
      'render element' => 'element',
    ],
    'picture' => [
      'variables' => [
        'img' => [],
        'source' => [],
      ],
    ],
    'noindex' => [
      'render element' => 'element',
    ],
  ];
}

/**
 * Implements hook_cron().
 */
function improvements_cron(): void {
  // Trigger hook_daily_cron()
  $current_timestamp = \Drupal::time()->getRequestTime();
  $cron_last_run_timestamp = \Drupal::state()->get('system.cron_last');
  if (date('Ymd', $current_timestamp) != date('Ymd', $cron_last_run_timestamp)) {
    \Drupal::moduleHandler()->invokeAll('daily_cron');
  }
}

/**
 * Implements hook_mail_alter().
 */
function improvements_mail_alter(array &$message): void {
  // Invoke hook_mail_MESSAGE_ID_alter()
  \Drupal::moduleHandler()->alter('mail_' . $message['id'], $message);

  // Add debug headers to e-mail on dev environment
  if (str_ends_with(\Drupal::request()->getHost(), '.local')) {
    $message['headers']['X-Drupal-Mail-Id'] = $message['id'];
    $message['headers']['X-Drupal-Mail-Module'] = $message['module'];
    $message['headers']['X-Drupal-Mail-Key'] = $message['key'];
  }
}

/**
 * Implements hook_library_info_alter().
 */
function improvements_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') . '/assets/';
  }

  if ($extension == 'contextual') {
    $libraries['drupal.contextual-links']['js'][$module_assets_path . 'improvements.contextual.js'] = [];
  }
}

/**
 * Implements hook_element_info_alter().
 */
function improvements_element_info_alter(array &$elements): void {
  // Add page #pre_render callback to delete "off canvas" wrapper
  $elements['page']['#pre_render'][] = '\Drupal\improvements\ImprovementsTrustedCallbacks::pagePreRender';

  // Add support empty link fragment
  $elements['link']['#post_render'][] = '\Drupal\improvements\ImprovementsTrustedCallbacks::linkPostRender';

  // Decrease pager items
  $elements['pager']['#quantity'] = 5;
}

/**
 * Implements hook_entity_operation_alter().
 */
function improvements_entity_operation_alter(array &$operations, EntityInterface $entity): void {
  // Remove "destination" from entity operations links
  foreach ($operations as &$operation) {
    $operation_url = $operation['url']; /** @var Url $operation_url */
    $operation_url_query = $operation_url->getOption('query');
    if ($operation_url_query && isset($operation_url_query['destination'])) {
      unset($operation_url_query['destination']);
      $operation_url->setOption('query', $operation_url_query);
    }
  }
}

/**
 * Preprocess function for simple-field.html.twig.
 */
function improvements_preprocess_simple_field(array &$vars): void {
  $vars['content'] = $vars['element'] + [
    '#entity_type' => '',
    '#bundle' => '',
    '#field_name' => '',
    '#field_type' => 'string',
    '#label_display' => 'above',
    '#title' => '',
    '#is_multiple' => FALSE,
  ];

  $vars['content']['#theme'] = 'field';

  if (isset($vars['element']['#entity']) && $vars['element']['#entity'] instanceof EntityInterface) {
    $vars['content']['#entity_type'] = $vars['element']['#entity']->getEntityTypeId();
    $vars['content']['#bundle'] = $vars['element']['#entity']->bundle();
  }

  if (is_array($vars['element']['#items'])) {
    $vars['content'] += $vars['element']['#items'];
  }
  elseif (is_string($vars['element']['#items'])) {
    $vars['content'][0] = [
      '#markup' => $vars['element']['#items'],
    ];
  }

  unset($vars['content']['#children']);
  unset($vars['content']['#render_children']);
}

/**
 * Implements hook_theme_suggestions_HOOK(): simple_field.
 */
function improvements_theme_suggestions_simple_field(array $vars): array {
  $suggestions = [];
  if (isset($vars['element']['#field_name'])) {
    $suggestions[] = 'simple_field__' . $vars['element']['#field_name'];
  }
  return $suggestions;
}

/**
 * Implements hook_editor_js_settings_alter().
 */
function improvements_editor_js_settings_alter(array &$settings): void {
  // Remove H1 from CKEditor formats
  foreach ($settings['editor']['formats'] as &$format_settings) {
    if (isset($format_settings['editorSettings']['format_tags'])) {
      $format_settings['editorSettings']['format_tags'] = str_replace('h1;', '', $format_settings['editorSettings']['format_tags']);
    }
  }
}

/**
 * Implements hook_block_access().
 *
 * @return ?AccessResultInterface[]
 */
function improvements_block_access(BlockInterface $block_config, string $operation, AccountInterface $account): ?array {
  if ($operation == 'view') {
    // Create hook hook_block_BLOCK_CONFIG_ID_view_access()
    $hook = 'block_' . $block_config->id() . '_view_access';
    return array_merge(
      Drupal::moduleHandler()->invokeAll($hook, [$block_config, $account]),
      ImprovementsHelper::invokeAllFromThemes($hook, [$block_config, $account])
    );
  }

  return NULL;
}

/**
 * Implements hook_entity_insert().
 */
function improvements_entity_insert(EntityInterface $entity): void {
  // Invoke hook_ENTITY_TYPE_manipulation()
  \Drupal::moduleHandler()->invokeAll($entity->getEntityTypeId() . '_manipulation', [$entity, 'insert']);
}

/**
 * Implements hook_entity_update().
 */
function improvements_entity_update(EntityInterface $entity): void {
  // Invoke hook_ENTITY_TYPE_manipulation()
  \Drupal::moduleHandler()->invokeAll($entity->getEntityTypeId() . '_manipulation', [$entity, 'update']);
}

/**
 * Implements hook_entity_update().
 */
function improvements_entity_delete(EntityInterface $entity): void {
  // Invoke hook_ENTITY_TYPE_manipulation()
  \Drupal::moduleHandler()->invokeAll($entity->getEntityTypeId() . '_manipulation', [$entity, 'delete']);
}

/**
 * Implements hook_entity_presave().
 */
function improvements_entity_presave(EntityInterface $entity): void {
  // Save to field data table info about width/height of svg image
  if (function_exists('svg_image_get_image_file_dimensions') && $entity instanceof FieldableEntityInterface) {
    foreach ($entity->getFieldDefinitions() as $field_name => $field_definition) {
      if ($field_definition->getType() == 'image') {
        foreach ($entity->get($field_name) as $image_field_item) {
          /** @var FileInterface $image_file_entity */
          $image_file_entity = $image_field_item->entity;
          if (
            $image_file_entity &&
            svg_image_is_file_svg($image_file_entity) &&
            !$image_field_item->width &&
            $image_file_dimensions = svg_image_get_image_file_dimensions($image_file_entity)
          ) {
            $image_field_item
              ->set('width', $image_file_dimensions['width'])
              ->set('height', $image_file_dimensions['height']);
          }
        }
      }
    }
  }
}

/**
 * Preprocess function for picture.html.twig.
 */
function improvements_preprocess_picture(array &$vars): void {
  $vars['img_attributes'] = new Attribute($vars['img']);

  foreach ($vars['source'] as &$source) {
    $source['attributes'] = new Attribute($source);
  }
}

/**
 * Preprocess fucntion for noindex.html.twig.
 */
function improvements_preprocess_noindex(array &$vars): void {
  $vars['children'] = $vars['element']['#children'];
}

/**
 * Implements hook_block_view_alter().
 */
function improvements_block_view_alter(array &$build, BlockPluginInterface $block): void {
  // Re-add block config entity because \Drupal\block\BlockViewBuilder::buildBlock() removes it.
  $block_config_entity = $build['#block']; /** @var BlockInterface $block_config_entity */
  $build['#block_config'] = $block_config_entity;
}

/**
 * Preprocess function for block.html.twig.
 */
function improvements_preprocess_block(array &$vars): void {
  $block_config_entity = $vars['elements']['#block_config'] ?? NULL; /** @var \Drupal\block\Entity\Block $block_config_entity */

  // Html attributes
  if ($block_config_entity && ($block_attributes_raw = $block_config_entity->getThirdPartySetting('improvements', 'attributes'))) {
    $block_attributes = ArrayHelper::formatKeyValueListAsArray($block_attributes_raw, ': ');
    $vars['attributes'] = array_merge($vars['attributes'] ?? [], ArrayHelper::formatArrayAsAttributes($block_attributes));
  }

  // Our way to preprocess block template by suggestion
  $preprocess_by_base_plugin_id = '_improvements_preprocess_block__' . $vars['base_plugin_id'];
  if (function_exists($preprocess_by_base_plugin_id)) {
    $preprocess_by_base_plugin_id($vars);
  }
}

/**
 * Implements hook_entity_base_field_info_alter().
 *
 * @param BaseFieldDefinition[] $fields
 */
function improvements_entity_base_field_info_alter(array &$fields, EntityTypeInterface $entity_type): void {
  if ($entity_type->id() == 'paragraph') {
    $fields['created']->setLabel(t('Date of creation'));
  }
}

/**
 * Implements hook_cache_flush().
 */
function improvements_cache_flush(): void {
  // Clear "flood" table
  $database = \Drupal::database();
  if ($database->schema()->tableExists('flood')) {
    $database->truncate('flood')->execute();
  }
}

/**
 * Implements hook_field_widget_info_alter().
 */
function improvements_field_widget_info_alter(array &$info): void {
  $info['string_textarea']['field_types'][] = 'string';
  $info['string_textfield']['field_types'][] = 'string_long';
}

/**
 * Implements hook_field_formatter_info_alter().
 */
function improvements_field_formatter_info_alter(array &$info): void {
  $info['file_default']['field_types'][] = 'image';
}

/**
 * Implements hook_page_ROUTE_NAME_result_alter(): entity.paragraphs_type.collection.
 */
function improvements_page_entity_paragraphs_type_collection_result_alter(&$result): void {
  // Hide "icon" column if all icons is empty
  if (!empty($result['table']['#rows']) && ArrayHelper::columnIsEmpty($result['table']['#rows'], 'icon_file')) {
    unset($result['table']['#header']['icon_file']);
    foreach ($result['table']['#rows'] as &$row) {
      unset($row['icon_file']);
    }
  }
}

/**
 * Preprocess function for pager.html.twig.
 */
function improvements_preprocess_pager(array &$vars): void {
  // Add fragment to pager items url
  if (!empty($vars['items']) && !empty($vars['pager']['#route_fragment'])) {
    foreach ($vars['items'] as $item_name => &$item) {
      if ($item_name == 'pages') {
        foreach ($item as &$item_item) {
          _improvements_add_fragment_to_pager_item($item_item, $vars['pager']['#route_fragment']);
        }
      }
      else {
        _improvements_add_fragment_to_pager_item($item, $vars['pager']['#route_fragment']);
      }
    }
  }
}

/**
 * Add url fragment to pager item.
 */
function _improvements_add_fragment_to_pager_item(array &$item, string $fragment): void {
  $item['href'] .= '#' . $fragment;
}

/**
 * Implements hook_form_FORM_ID_alter(): block_form.
 *
 * @see \Drupal\block\BlockForm
 */
function improvements_form_block_form_alter(array &$form, FormStateInterface $form_state): void {
  $block_form_object = $form_state->getFormObject(); /** @var BlockForm $block_form_object */
  $block_config = $block_form_object->getEntity(); /** @var BlockInterface $block_config */

  $form['third_party_settings']['improvements']['attributes'] = [
    '#type' => 'textarea',
    '#title' => t('Html attributes'),
    '#description' => t('Format') . ' <code>key: value</code>',
    '#default_value' => $block_config->getThirdPartySetting('improvements', 'attributes'),
    '#rows' => 2,
  ];
}

/**
 * Remove "title" attribute from menu links.
 */
function improvements_unset_menu_items_description(array &$items): void {
  foreach ($items as $key => &$item) {
    $url = $item['url']; /** @var Url $url */
    $url_attributes = $url->getOption('attributes');

    if (isset($url_attributes['title'])) {
      unset($url_attributes['title']);
      $url->setOption('attributes', $url_attributes);
    }

    // Processing child items
    if (!empty($item['below'])) {
      improvements_unset_menu_items_description($item['below']);
    }
  }
}

/**
 * Implements hook_entity_view_alter().
 */
function improvements_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display): void {
  // Not using Element::children() to improve performance
  foreach ($build as $element) {
    if (is_array($element) && isset($element['#entity_attributes'])) {
      $build['#attributes'] = AttributeHelper::mergeCollections($build['#attributes'] ?? [], $element['#entity_attributes']);
    }
  }
}

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

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