toolshed-8.x-1.x-dev/toolshed.module
toolshed.module
<?php
/**
* @file
* The core Drupal module hooks and global helpers.
*/
use Drupal\Core\Asset\AttachedAssetsInterface;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Extension\Exception\UnknownExtensionException;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\toolshed\Utility\LibraryMinifyAlter;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
/**
* Implements hook_help().
*/
function toolshed_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'toolshed.js_configs.breakpoints':
case 'toolshed.js_configs.breakpoints_theme':
/** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler */
$theme_handler = \Drupal::service('theme_handler');
$theme_name = $route_match->getParameter('theme') ?: $theme_handler->getDefault();
$theme = $theme_handler->getTheme($theme_name);
return t('<p>These media queries are for <strong>@theme</strong> theme and the breakpoints defined
for that theme from the in the %file file. Order your media queries in the order in which they should be tested.
The first media query that is detected, will execute.</p>
<p>The default behavior is to trigger the `on` event trigger when the media query is <strong>TRUE</strong>.
Set the <strong>Inverted</strong> option to flip this logic and trigger `on` when query is <strong>FALSE</strong>.</p>', [
'@theme' => $theme->getName(),
'%file' => "{$theme_name}.breakpoints.yml",
]);
}
}
/**
* Implements hook_modules_installed().
*/
function toolshed_modules_installed(): void {
\Drupal::service('strategy.cache_clearer')->clearCachedDefinitions();
}
/**
* Implements hook_modules_uninstalled().
*/
function toolshed_modules_uninstalled(): void {
\Drupal::service('strategy.cache_clearer')->clearCachedDefinitions();
}
/**
* Implements hook_js_settings_alter().
*/
function toolshed_js_settings_alter(&$settings, AttachedAssetsInterface $assets): void {
if (isset($settings['Toolshed']['breakpoints'])) {
return;
}
// Ensure that something is set so breakpoints won't be attempted again.
$settings['Toolshed']['breakpoints'] = [];
try {
$theme = \Drupal::theme()->getActiveTheme()->getName();
$bps = \Drupal::config("toolshed.breakpoints.{$theme}")->get('settings') ?: [];
$bpsManager = \Drupal::service('breakpoint.manager');
foreach ($bps as $bpInfo) {
$bp = $bpsManager->getDefinition($bpInfo['name']);
if ($bp && !empty($bp['mediaQuery'])) {
$settings['Toolshed']['breakpoints'][] = [
'mediaQuery' => $bp['mediaQuery'],
'id' => $bpInfo['name'],
'event' => $bpInfo['event'],
'inverted' => $bpInfo['inverted'],
];
}
}
}
catch (ServiceNotFoundException $e) {
// Unable to get theme handler or breakpoint manager.
}
}
/**
* Implements hook_library_info_alter().
*/
function toolshed_library_info_alter(array &$libraries, $extension): void {
$assetConfig = \Drupal::config('toolshed.assets.config');
if ($extension === 'toolshed') {
$debounce = $assetConfig->get('debounce');
if (!empty($debounce['enabled'])) {
array_unshift($libraries['screen-events']['dependencies'], 'core/drupal.debounce');
$libraries['screen-events']['drupalSettings']['Toolshed']['eventDebounce'] = $debounce['delay'];
}
// Apply configured accordion behavior settings from the config.
$libraries['behavior.accordions']['drupalSettings']['Toolshed']['accordions'] = $assetConfig->get('accordions');
}
// The development asset flag is enabled, modify any libraries marked as
// "has_dev" to non-optimized versions of assets. These assets are expected
// to be in same directory, and have the same file name without ".min.js".
// Most of the files also have source maps to make it easier to debug.
if ($assetConfig->get('dev_assets')) {
try {
$ext_type = \Drupal::moduleHandler()->moduleExists($extension) ? 'module' : 'theme';
$path = \Drupal::service('extension.list.' . $ext_type)->getPath($extension);
foreach ($libraries as &$library) {
if (!empty($library['has_dev'])) {
LibraryMinifyAlter::minifiedToExpanded($library, $path);
}
}
}
catch (ServiceNotFoundException | UnknownExtensionException) {
// Unable to determine the extension path, so skip and don't try to
// alter the library assets at all.
}
}
}
/**
* Implements hook_form_alter().
*/
function toolshed_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void {
$form_object = $form_state->getFormObject();
if ($form_object instanceof EntityFormInterface) {
$entity = $form_object->getEntity();
$entity_type = $entity->getEntityTypeId();
// Only config entities have third party settings.
if ($entity instanceof ConfigEntityInterface) {
$plugin_manager = \Drupal::service('plugin.manager.toolshed.third_party');
$op = $form_object->getOperation();
// Apply ThirdPartyConfig plugins that add settings to this entity type.
/** @var \Drupal\toolshed\Plugin\ThirdPartyConfigInterface $plugin */
foreach ($plugin_manager->getPluginsByEntityType($entity_type) as $plugin) {
if ($plugin->isApplicable($entity, $op)) {
$plugin->addThirdPartyConfig($entity, $form, $form_state);
}
}
}
}
}
/**
* Implements hook_block_build_BLOCK_PLUGIN_ID_alter() for system_branding_block.
*/
function toolshed_block_build_system_branding_block_alter(array &$build, BlockPluginInterface $block): void {
if (theme_get_setting('dynamic_branding_front_page')) {
$build['#cache']['contexts'][] = 'url.path.is_front';
}
}
/**
* Implements hook_theme().
*/
function toolshed_theme($existing, $type, $theme, $path): array {
return [
'html_button' => [
'render element' => 'element',
],
];
}
/**
* Implements hook_preprocess_html_button().
*
* Allows us to render submit buttons using the HTML button instead of the
* default Drupal rendering which always defaults back to an INPUT tag.
*/
function template_preprocess_html_button(&$variables): void {
$variables['children'] = $variables['element']['#children'];
}
