seeds_toolbar-8.x-1.11/seeds_toolbar.module
seeds_toolbar.module
<?php
/**
* @file
* Contains all the hooks to control the toolbar.
*
* Also contains custom functions.
*/
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
/**
* Implements hook_help().
*/
function seeds_toolbar_help($route_name, RouteMatchInterface $route_match) {
if ($route_name === 'help.page.seeds_toolbar') {
return [
'#theme' => 'seeds_toolbar_help',
];
}
return NULL;
}
/**
* Implements hook_theme().
*/
function seeds_toolbar_theme() {
return [
'seeds_toolbar' => [
'render element' => 'children',
'variables' => [
'icon_link' => NULL,
],
'base hook' => 'toolbar',
],
'seeds_add' => [
'render element' => 'children',
'variables' => [
'content_links' => NULL,
'taxonomy_links' => NULL,
'blocks_links' => NULL,
'search' => NULL,
],
],
'seeds_toolbar_menu' => [
'render element' => 'children',
'base hook' => 'menu',
],
'seeds_add_menu' => [
'render element' => 'children',
'variables' => [
'items' => NULL,
'menu_name' => 'menu',
],
// Changing the base hook fixes an error with menu_link_attributes module.
'base hook' => 'seeds_add_menu',
],
'seeds_toolbar_help' => [
'render element' => 'children',
],
'seeds_local_task' => [
'render element' => 'children',
'variables' => [
'items' => NULL,
],
],
];
}
/**
* Implements hook_theme_suggestions_menu_alter().
*/
function seeds_toolbar_theme_suggestions_menu_alter(array &$suggestions, array $variables) {
if ($variables['theme_hook_original'] == 'menu__toolbar__admin') {
$suggestions[] = 'seeds_toolbar_menu';
}
}
/**
* Implements hook_theme_suggestions_hook().
*/
function seeds_toolbar_theme_suggestions_toolbar() {
return 'seeds_toolbar';
}
/**
* Implements hook_page_attachments().
*/
function seeds_toolbar_page_attachments(array &$attachments) {
// Get the current user.
$user = \Drupal::currentUser();
// Check for permission.
if ($user->hasPermission('access toolbar')) {
$config = \Drupal::config('seeds_toolbar.settings');
// Cache tags.
$attachments['#cache']['tags'][] = $config->getCacheTags()[0];
// JS Libraries.
$attachments['#attached']['library'][] = 'seeds_toolbar/toolbar';
$attachments['#attached']['drupalSettings']['seeds_toolbar'] = [
'compact' => $config->get('compact'),
'support' => $config->get('support'),
'style' => $config->get('style'),
];
if ($config->get('fixed_elements')) {
$attachments['#attached']['library'][] = 'seeds_toolbar/fixed_elements';
}
}
}
/**
* Implements hook_library_info_alter().
*/
function seeds_toolbar_library_info_alter(&$libraries, $extension) {
// Clear all attached js and css from toolbar module and admin toolbar.
if ($extension == 'toolbar' || $extension == 'admin_toolbar') {
$libraries['toolbar.menu']['css'] = [];
$libraries['toolbar.escapeAdmin']['css'] = [];
$libraries['toolbar']['css'] = [];
$libraries['toolbar.menu']['js'] = [];
$libraries['toolbar.escapeAdmin']['js'] = [];
$libraries['toolbar']['js'] = [];
$libraries['toolbar.tree']['css'] = [];
$libraries['toolbar.tree']['js'] = [];
$libraries['toolbar.icon']['js'] = [];
}
// Remove devel toolbar css.
if ($extension === 'devel') {
$libraries['devel-toolbar']['css'] = [];
}
// Fix JS loading compatibility for Responsive Preview module.
if ($extension == "seeds_toolbar") {
$moduleHandler = \Drupal::service('module_handler');
if ($moduleHandler->moduleExists('responsive_preview')) {
$libraries['toolbar']['dependencies'][] = 'responsive_preview/drupal.responsive-preview';
}
// Add custom style if it exists.
$custom_style = \Drupal::config('seeds_toolbar.settings')->get('custom_style');
if (isset($custom_style) && !empty($custom_style)) {
$libraries['toolbar']['css']['theme'][$custom_style] = [];
}
}
}
/**
* Implements hook_toolbar().
*/
function seeds_toolbar_toolbar() {
$config = \Drupal::config('seeds_toolbar.settings');
$items = [];
// Support Tab.
$support_url = $config->get('support') ? $config->get('support') : NULL;
if (isset($support_url) && $support_url) {
$items['seeds_support'] = [
'#weight' => 1000,
'#type' => 'toolbar_item',
'tab' => [
'#type' => 'html_tag',
'#tag' => 'a',
'#title' => t('Support'),
'#attributes' => [
'title' => t('Link to the support page'),
'class' => ['toolbar-icon', 'toolbar-icon-support'],
'href' => $support_url,
'target' => '_blank',
],
],
];
}
$items['seeds_add'] = [
'#type' => 'toolbar_item',
'tab' => [
'#type' => 'html_tag',
'#tag' => 'button',
'#value' => t('Seeds Add'),
'#attributes' => [
'class' => ['toolbar-icon', 'toolbar-icon-seeds-add'],
],
],
'tray' => [
'#theme' => 'seeds_add',
],
];
$items['seeds_logo'] = [
'#type' => 'toolbar_item',
'#attributes' => [
'class' => 'toolbar-icon-seeds',
],
'tab' => [
'#type' => 'link',
'#title' => t('Home'),
'#url' => Url::fromRoute('<front>'),
'#attributes' => [
'title' => t('Home'),
'class' => ['toolbar-icon', 'toolbar-icon-seeds'],
],
],
];
$items['seeds_local_task'] = [
'#type' => 'toolbar_item',
'#attributes' => [
'class' => 'toolbar-icon-seeds',
],
'tab' => [
'#type' => 'html_tag',
'#title' => t('local task'),
'#tag' => 'button',
'#value' => t('Seeds Local Task'),
'#attributes' => [
'class' => ['toolbar-icon', 'toolbar-icon-seeds-local-task'],
],
],
'tray' => [
'#theme' => 'seeds_local_task',
],
];
return $items;
}
/**
* Implements hook_toolbar_alter().
*/
function seeds_toolbar_toolbar_alter(&$items) {
// Convert the administration link to a button tag.
$items["administration"]["tab"]['#type'] = 'html_tag';
$items["administration"]["tab"]['#tag'] = 'button';
unset($items["administration"]["tab"]['#url']);
// Add trigger class to responsive reviews.
if (\Drupal::service('router.admin_context')->isAdminRoute()) {
// Remove responsive preview from backend, it causes weird problems.
if (isset($items['responsive_preview'])) {
unset($items['responsive_preview']);
}
}
else {
// Remove "back to site" in front end.
unset($items['home']);
if (isset($items['responsive_preview'])) {
$items['responsive_preview']['tab']['trigger']['#attributes']['class'][] = 'trigger';
}
}
// 'Masquerade' Integration.
if (isset($items['masquerade_switch_back'])) {
$items['masquerade_switch_back']['tab']['#attributes']['class'][] = 'toolbar-icon-masquerade';
}
// 'Admin Toolbar' Search Integration
if (\Drupal::moduleHandler()->moduleExists('admin_toolbar_search') && \Drupal::currentUser()->hasPermission('use admin toolbar search')) {
$items['administration_search']['tab'] = [
'#type' => 'link',
'#title' => t('Search'),
'#url' => URL::fromRoute('system.admin'),
'#attributes' => [
'class' => [
'toolbar-icon',
],
],
];
$items['administration_search']['tray'] = [
'search' => [
'#title' => 'Search',
'#type' => 'textfield',
'#size' => 60,
'#attributes' => [
'id' => 'admin-toolbar-search-input',
'aria-labelledby' => 'toolbar-item-administration-search',
],
],
];
}
// Order the tabs if they exist.
$first_tabs = [
'home',
'seeds_logo',
'administration',
'seeds_add',
'shortcuts',
'coffee',
'seeds_support',
'contextual',
'devel',
'masquerade_switch_back',
'seeds_local_task',
];
$items = \Drupal::service('seeds_toolbar.manager')->sortTabs($items, $first_tabs);
}
/**
* Implements hook_preprocess_HOOK().
*/
function seeds_toolbar_preprocess_html(&$variables) {
// Default width to fix the jumping issue.
if (\Drupal::currentUser()->hasPermission('access toolbar')) {
$config = \Drupal::config('seeds_toolbar.settings');
$settings = $config->get();
$variables['attributes'] = new Attribute($variables['attributes']);
$variables['attributes']->addClass('seeds-toolbar', 'seeds-toolbar--' . $config->get('style'));
$variables["attributes"]->removeClass("toolbar-horizontal", "toolbar-tray-open");
$dir = \Drupal::service('seeds_toolbar.manager')->getDirection();
if (!$settings['compact']) {
$variables['attributes']->setAttribute('style', "margin-{$dir}:245px");
}
else {
$variables['attributes']->setAttribute('style', "margin-{$dir}:55px");
}
if (!$config->get('compact')) {
$variables['attributes']->addClass('seeds-toolbar-open');
}
}
}
/**
* Implements hook_preprocess_hook().
*/
function seeds_toolbar_preprocess_seeds_toolbar(&$variables) {
global $base_url;
$config = \Drupal::config('seeds_toolbar.settings');
// Clear render cache when saving config.
\Drupal::service('renderer')->addCacheableDependency($variables, $config);
$variables['attributes']['class'][] = 'seeds-toolbar--' . $config->get('style');
/* hoverIntents on Admin Toolbar version 3 does not work
* because of a different selector.
* This code will help fix this issue by adding the required class.
* I still don't like how we are adding 'toolbar-tray-horizontal' when
* the toolbar is clearly vertical.
*/
/** @var \Drupal\Core\Extension\ModuleExtensionList $module_extension_list */
$module_extension_list = \Drupal::service('extension.list.module');
$admin_toolbar_info = $module_extension_list->getExtensionInfo('admin_toolbar');
$version = str_replace('8.x-', '', $admin_toolbar_info['version']);
if (version_compare($version, '3.0.0', '>=')) {
$variables['attributes']['class'][] = 'toolbar-tray-horizontal';
$variables["trays"]["administration"]["attributes"]['class'][] = 'is-active toolbar-tray-horizontal';
}
$settings = $config->get();
if (!empty($settings[$settings['style'] . '_icon'])) {
$variables['icon_link'] = \Drupal::service('file_url_generator')->generateString($base_url . '/' . $settings[$settings['style'] . '_icon']);
}
else {
$variables['icon_link'] = \Drupal::service('file_url_generator')->generateString($base_url . '/' . \Drupal::service('extension.list.module')->getPath('seeds_toolbar') . '/assets/icons/logo/logo.svg');
}
}
/**
* Implements hook_preprocess_hook().
*/
function seeds_toolbar_preprocess_seeds_add(&$variables) {
// @todo Find a more dynamic way to build menus.
$seeds_manager = \Drupal::service('seeds_toolbar.manager');
$variables['content_links'] = $seeds_manager->buildMenu('node_type', 'node.add');
$variables['content_collection'] = [
'#type' => 'link',
'#title' => t('Content'),
'#url' => Url::fromRoute('system.admin_content'),
];
$variables['taxonomy_links'] = $seeds_manager->buildMenu('taxonomy_vocabulary', 'entity.taxonomy_term.add_form');
$variables['taxonomy_collection'] = [
'#type' => 'link',
'#title' => t('Taxonomies'),
'#url' => Url::fromRoute('entity.taxonomy_vocabulary.collection'),
];
$variables['media_links'] = $seeds_manager->buildMenu('media_type', 'entity.media.add_form');
$variables['media_collection'] = [
'#type' => 'link',
'#title' => t('Media'),
'#url' => Url::fromRoute('entity.media.collection'),
];
$variables['block_links'] = $seeds_manager->buildMenu('block_content_type', 'block_content.add_form');
$variables['block_collection'] = [
'#type' => 'link',
'#title' => t('Blocks'),
'#url' => Url::fromRoute('entity.block_content.collection'),
];
// Show/Hide search input.
$config = \Drupal::config('seeds_toolbar.settings');
$variables['search'] = $config->get('search');
}
/**
* Implements hook_preprocess_hook().
*/
function seeds_toolbar_preprocess_item_list__responsive_preview(&$variables) {
$variables['wrapper_attributes']->addClass('toolbar-tray')->removeClass('responsive-preview-item-list');
// We add a dummy item to mitigate the error in responsive-preview.js:485
// since we now control how the tabs behave.
$variables["items"]['dummy'] = [
'value' => [
'#type' => 'html_tag',
'#tag' => 'a',
'#value' => 'dummy',
'#attributes' => [
'class' => ['visually-hidden', 'responsive-preview-item-list'],
],
],
];
}
/**
* Implements hook_preprocess_hook().
*/
function seeds_toolbar_preprocess_seeds_toolbar_menu(&$variables) {
global $base_url;
$config = \Drupal::config('seeds_toolbar.settings');
$settings = $config->get();
if (!empty($settings[$settings['style'] . '_logo'])) {
$variables['logo_link'] = \Drupal::service('file_url_generator')->generateString($base_url . '/' . $settings[$settings['style'] . '_logo']);
}
else {
$variables['logo_link'] = \Drupal::service('file_url_generator')->generateString($base_url . '/' . \Drupal::service('extension.list.module')->getPath('seeds_toolbar') . '/assets/icons/logo/drupal.svg');
}
// Create links to use for searching.
$menu_tree = \Drupal::service('toolbar.menu_tree');
$parameters = new MenuTreeParameters();
$max_depth = \Drupal::config('admin_toolbar.settings')->get('menu_depth');
$parameters->setRoot('system.admin')->excludeRoot()->setMaxDepth($max_depth)->onlyEnabledLinks();
$tree = $menu_tree->load('admin', $parameters);
$manipulators = [
['callable' => 'menu.default_tree_manipulators:checkAccess'],
['callable' => 'menu.default_tree_manipulators:generateIndexAndSort'],
['callable' => 'toolbar_tools_menu_navigation_links'],
];
$tree = $menu_tree->transform($tree, $manipulators);
$admin_items = $menu_tree->build($tree)['#items'] ?? [];
$serach_links = _seeds_toolbar_search_links($admin_items);
$variables['search_items'] = $serach_links;
$variables['use_admin_search'] = \Drupal::currentUser()->hasPermission('use admin search') && \Drupal::config('seeds_toolbar.settings')->get('search');
}
/**
* Search and return all links in the toolbar.
*/
function _seeds_toolbar_search_links(array $items, $level = 0, $parent_title = "", $parent_id = "") {
$search_links = [];
$ignore_parent_titles = [
"admin_toolbar_tools.flush",
];
foreach ($items as $item) {
$item_id = "";
$actual_title = $item['title'];
if ($level >= 1) {
if (!in_array($parent_id, $ignore_parent_titles)) {
// Remove anything between ( and ) in title.
$title_without_old_parent = trim(preg_replace("/\([^)]+\)/", "", $parent_title));
$item['title'] = "{$item['title']} ($title_without_old_parent)";
}
}
$url = $item['url'] ?? NULL;
if ($url instanceof Url) {
$link = $url->getInternalPath();
$terms = explode('/', $link);
$terms = [strtolower($item['title'])] + $terms;
$terms[] = $item_id = $url->getRouteName();
$attributes = $url->getOption('attributes') ?? [];
unset($attributes['class']);
$attributes['data-search'] = implode(',', $terms);
$attributes['data-level'] = $level;
$attributes['data-title'] = $actual_title;
$url->setOption('attributes', $attributes);
$search_links[] = $item;
}
if (!empty($item['below']) && \Drupal::currentUser()->hasPermission('use admin search') && \Drupal::config('seeds_toolbar.settings')->get('search')) {
$below_search_links = _seeds_toolbar_search_links($item['below'], $level + 1, $item['title'] ?? "", $item_id) ?? [];
$search_links = array_merge($search_links, $below_search_links);
}
}
return $search_links;
}
/**
* Implements hook_preprocess_hook().
*/
function seeds_toolbar_preprocess_seeds_local_task(&$variables) {
// Get the current route and parameters.
$route_name = \Drupal::service('current_route_match')->getRouteName();
$local_task_manager = \Drupal::service('plugin.manager.menu.local_task');
/** @var \Drupal\Core\Cache\CacheableMetadata $cacheability */
$cacheability = $local_task_manager->getLocalTasks($route_name)['cacheability'];
$cacheability->applyTo($variables);
$variables['items'] = $local_task_manager->getLocalTasks($route_name)['tabs'];
}
