first commit

This commit is contained in:
2024-07-15 12:33:27 +02:00
commit ce50ae282b
22084 changed files with 2623791 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
# Admin Toolbar Tools
Admin Toolbar Extra Tools provides menu links to administration pages or actions
(eg. Flushing caches) that are not generated by Drupal core. It adds menu items
that are not generated by Drupal core. For example there are no menu items for
each content type by default or menu links to Manage fields on each entity
types. That's the purpose of Admin Toolbar Extra Tools to add them.
For a full description of the module, visit the
[project page](https://www.drupal.org/project/admin_toolbar).
Submit bug reports and feature suggestions, or track changes in the
[issue queue](https://www.drupal.org/project/issues/search/admin_toolbar).
## Table of contents
- Requirements
- Installation
- Configuration
- Maintainers
## Requirements
This module requires the following modules:
- [Admin Toolbar](https://www.drupal.org/project/admin_toolbar)
## Installation
Install as you would normally install a contributed Drupal module. For further
information, see
[Installing Drupal Modules](https://www.drupal.org/docs/extending-drupal/installing-drupal-modules).
## Configuration
No configuration is needed.
## Maintainers
Current maintainers:
- [Romain Jarraud (romainj)](https://www.drupal.org/u/romainj)
- [Adrian Cid Almaguer (adriancid)](https://www.drupal.org/u/adriancid)
- [Wilfrid Roze (eme)](https://www.drupal.org/u/eme)
- [bilel khalil (bolbol)](https://www.drupal.org/u/bolbol)
- [fethi.krout (fethi.krout)](https://www.drupal.org/u/fethi.krout)
- [Mohamed Anis Taktak (matio89)](https://www.drupal.org/u/matio89)
- [Thomas MUSA (Musa.thomas)](https://www.drupal.org/u/musathomas)
Supporting organizations:
- [emerya](https://www.drupal.org/emerya) Created this module for you!
- [Trained People](https://www.drupal.org/trained-people) Sponsored the module development
- [Drupiter](https://www.drupal.org/drupiter) Sponsored the module development
- [Dropteam](https://www.drupal.org/dropteam) Sponsored the module development
- [Alliance of Digital Builders (AODB)](https://www.drupal.org/alliance-of-digital-builders-aodb) Sponsored the module development

View File

@@ -0,0 +1,13 @@
name: Admin Toolbar Extra Tools
description: Adds menu links like Flush cache, Run cron, Run updates, and Logout under Drupal icon.
package: Administration
configure: admin_toolbar_tools.settings
type: module
core_version_requirement: ^9.2 || ^10
dependencies:
- admin_toolbar:admin_toolbar
# Information added by Drupal.org packaging script on 2023-09-29
version: '3.4.2'
project: 'admin_toolbar'
datestamp: 1696006156

View File

@@ -0,0 +1,34 @@
<?php
/**
* @file
* Install, update and uninstall functions for the Admin Toolbar Tools module.
*/
/**
* Install the Admin Toolbar Search module.
*/
function admin_toolbar_tools_update_8001() {
// Installing the Admin Toolbar Search module.
\Drupal::service('module_installer')->install(['admin_toolbar_search']);
}
/**
* Default setting for maximum number of bundles per entity type to display.
*/
function admin_toolbar_tools_update_8201() {
\Drupal::service('config.factory')
->getEditable('admin_toolbar_tools.settings')
->set('max_bundle_number', 20)
->save(TRUE);
}
/**
* Default setting for enable hoverintent.
*/
function admin_toolbar_tools_update_8202() {
\Drupal::service('config.factory')
->getEditable('admin_toolbar_tools.settings')
->set('hoverintent_functionality', TRUE)
->save(TRUE);
}

View File

@@ -0,0 +1,4 @@
toolbar.icon:
css:
theme:
css/tools.css: {}

View File

@@ -0,0 +1,92 @@
admin_toolbar_tools.help:
title: 'Tools'
route_name: <front>
menu_name: admin
parent: system.admin
weight: -100
system.admin_index:
title: 'Index'
route_name: system.admin_index
menu_name: admin
parent: admin_toolbar_tools.help
weight: -100
system.run_cron:
title: 'Run cron'
route_name: admin_toolbar.run.cron
menu_name: admin
parent: admin_toolbar_tools.help
weight: -8
system.db_update:
title: 'Run updates'
route_name: system.db_update
menu_name: admin
parent: admin_toolbar_tools.help
weight: -6
system.modules_uninstall:
title: 'Uninstall module'
route_name: system.modules_uninstall
menu_name: admin
parent: system.modules_list
admin_toolbar_tools.flush:
title: 'Flush all caches'
route_name: admin_toolbar_tools.flush
weight: -9
parent: admin_toolbar_tools.help
menu_name: admin
admin_toolbar_tools.cssjs:
title: 'Flush CSS and JavaScript'
route_name: admin_toolbar_tools.cssjs
parent: admin_toolbar_tools.flush
menu_name: admin
admin_toolbar_tools.plugin:
title: 'Flush plugins cache'
route_name: admin_toolbar_tools.plugin
parent: admin_toolbar_tools.flush
menu_name: admin
admin_toolbar_tools.flush_static:
title: 'Flush static cache'
route_name: admin_toolbar_tools.flush_static
parent: admin_toolbar_tools.flush
menu_name: admin
admin_toolbar_tools.flush_menu:
title: 'Flush routing and links cache'
route_name: admin_toolbar_tools.flush_menu
parent: admin_toolbar_tools.flush
menu_name: admin
admin_toolbar_tools.flush_twig:
title: 'Flush twig cache'
route_name: admin_toolbar_tools.flush_twig
parent: admin_toolbar_tools.flush
menu_name: admin
admin_toolbar_tools.flush_rendercache:
title: 'Flush render cache'
route_name: admin_toolbar_tools.flush_rendercache
parent: admin_toolbar_tools.flush
menu_name: admin
admin_toolbar_tools.theme_rebuild:
title: 'Rebuild theme registry'
route_name: admin_toolbar_tools.theme_rebuild
parent: admin_toolbar_tools.flush
menu_name: admin
admin_toolbar_tools.extra_links:
deriver: \Drupal\admin_toolbar_tools\Plugin\Derivative\ExtraLinks
menu_name: admin
admin_toolbar_tools.settings:
title: 'Admin Toolbar Tools'
description: 'Configure the Admin Toolbar Tools module.'
route_name: admin_toolbar_tools.settings
parent: system.admin_config_ui

View File

@@ -0,0 +1,99 @@
<?php
/**
* @file
* Provides extra menu links for the core drupal toolbar.
*/
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
/**
* Implements hook_toolbar().
*/
function admin_toolbar_tools_toolbar() {
$items = [];
$items['admin_toolbar_tools'] = [
'#type' => 'toolbar_item',
'tab' => [
'#type' => 'link',
'#attributes' => [
'class' => ['toolbar-icon', 'toolbar-icon-admin-toolbar-tools-help'],
],
],
'#attached' => ['library' => ['admin_toolbar_tools/toolbar.icon']],
];
// Toolbar item for primary local tasks.
$items['admin_toolbar_local_tasks'] = \Drupal::service('admin_toolbar_tools.helper')->buildLocalTasksToolbar();
return $items;
}
/**
* Implements hook_preprocess_html().
*/
function admin_toolbar_tools_preprocess_html(&$variables) {
if (\Drupal::currentUser()->hasPermission('access toolbar')) {
$variables['attributes']['class'][] = 'toolbar-icon-' . intval(\Drupal::VERSION);
}
}
/**
* Implements hook_help().
*/
function admin_toolbar_tools_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.admin_toolbar_tools':
$output = '';
$output .= '<p>';
$output .= t('The Admin Toolbar Extra Tools module comes packaged with the <a href=":admin-toolbar">Admin Toolbar</a> module and adds functionality to it. The additional functionality is accessed through extra links on the main administration Toolbar. Some links to Admin Toolbar Extra Tools administration pages are located at the bottom of this page.</a>', [':admin-toolbar' => Url::fromRoute('help.page', ['name' => 'admin_toolbar'])->toString()]);
$output .= '</p>';
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<p>' . t('To use Admin Toolbar Extra Tools just install it like any other module. There is no other configuration required.') . '</p>';
return $output;
}
}
/**
* Implements hook_entity_insert().
*/
function admin_toolbar_tools_entity_insert(EntityInterface $entity) {
// Skip rebuild during config sync because rebuild should
// always be a post-sync step.
if (!\Drupal::isConfigSyncing()) {
$entities = \Drupal::service('admin_toolbar_tools.helper')->getRebuildEntityTypes();
if (in_array($entity->getEntityTypeId(), $entities)) {
\Drupal::service('plugin.manager.menu.link')->rebuild();
}
}
}
/**
* Implements hook_entity_update().
*/
function admin_toolbar_tools_entity_update(EntityInterface $entity) {
// Skip rebuild during config sync because rebuild should
// always be a post-sync step.
if (!\Drupal::isConfigSyncing()) {
$entities = \Drupal::service('admin_toolbar_tools.helper')->getRebuildEntityTypes();
if (in_array($entity->getEntityTypeId(), $entities)) {
\Drupal::service('plugin.manager.menu.link')->rebuild();
}
}
}
/**
* Implements hook_entity_delete().
*/
function admin_toolbar_tools_entity_delete(EntityInterface $entity) {
// Skip rebuild during config sync because rebuild should
// always be a post-sync step.
if (!\Drupal::isConfigSyncing()) {
$entities = \Drupal::service('admin_toolbar_tools.helper')->getRebuildEntityTypes();
if (in_array($entity->getEntityTypeId(), $entities)) {
\Drupal::service('plugin.manager.menu.link')->rebuild();
}
}
}

View File

@@ -0,0 +1,13 @@
<?php
/**
* @file
* Post-update functions for the Admin Toolbar Tools module.
*/
/**
* Update container for admin_toolbar_tools.helper arguments.
*/
function admin_toolbar_tools_post_update_helper_added_config_factory() {
// Intentionally empty to trigger a service container rebuild.
}

View File

@@ -0,0 +1,97 @@
admin_toolbar_tools.flush:
path: '/admin/flush'
defaults:
_controller: '\Drupal\admin_toolbar_tools\Controller\ToolbarController::flushAll'
_title: 'Flush all caches'
requirements:
_permission: 'administer site configuration'
_csrf_token: 'TRUE'
admin_toolbar_tools.cssjs:
path: '/admin/flush/cssjs'
defaults:
_controller: '\Drupal\admin_toolbar_tools\Controller\ToolbarController::flushJsCss'
_title: 'Flush CSS and JavaScript'
requirements:
_permission: 'administer site configuration'
_csrf_token: 'TRUE'
admin_toolbar_tools.plugin:
path: '/admin/flush/plugin'
defaults:
_controller: '\Drupal\admin_toolbar_tools\Controller\ToolbarController::flushPlugins'
_title: 'Plugin'
requirements:
_permission: 'administer site configuration'
_csrf_token: 'TRUE'
admin_toolbar_tools.flush_static:
path: '/admin/flush/static-caches'
defaults:
_controller: '\Drupal\admin_toolbar_tools\Controller\ToolbarController::flushStatic'
_title: 'Static caches'
requirements:
_permission: 'administer site configuration'
_csrf_token: 'TRUE'
admin_toolbar_tools.flush_menu:
path: '/admin/flush/menu'
defaults:
_controller: '\Drupal\admin_toolbar_tools\Controller\ToolbarController::flushMenu'
_title: 'Menu'
requirements:
_permission: 'administer site configuration'
_csrf_token: 'TRUE'
admin_toolbar_tools.flush_rendercache:
path: '/admin/flush/rendercache'
defaults:
_controller: '\Drupal\admin_toolbar_tools\Controller\ToolbarController::cacheRender'
_title: 'Render cache'
requirements:
_permission: 'administer site configuration'
_csrf_token: 'TRUE'
admin_toolbar_tools.flush_views:
path: '/admin/flush/views'
defaults:
_controller: '\Drupal\admin_toolbar_tools\Controller\ToolbarController::flushViews'
_title: 'Views'
requirements:
_permission: 'administer site configuration'
_csrf_token: 'TRUE'
admin_toolbar_tools.flush_twig:
path: '/admin/flush/twig'
defaults:
_controller: '\Drupal\admin_toolbar_tools\Controller\ToolbarController::flushTwig'
_title: 'Twig'
requirements:
_permission: 'administer site configuration'
_csrf_token: 'TRUE'
admin_toolbar_tools.theme_rebuild:
path: '/admin/flush/theme_rebuild'
defaults:
_controller: '\Drupal\admin_toolbar_tools\Controller\ToolbarController::themeRebuild'
_title: 'Theme Rebuild'
requirements:
_permission: 'administer site configuration'
_csrf_token: 'TRUE'
admin_toolbar.run.cron:
path: '/run-cron'
defaults:
_controller: '\Drupal\admin_toolbar_tools\Controller\ToolbarController::runCron'
_title: 'Run cron'
requirements:
_permission: 'administer site configuration'
_csrf_token: 'TRUE'
admin_toolbar_tools.settings:
path: '/admin/config/user-interface/admin-toolbar-tools'
defaults:
_form: '\Drupal\admin_toolbar_tools\Form\AdminToolbarToolsSettingsForm'
_title: 'Admin Toolbar Tools settings'
requirements:
_permission: 'administer site configuration'

View File

@@ -0,0 +1,8 @@
services:
admin_toolbar_tools.helper:
class: Drupal\admin_toolbar_tools\AdminToolbarToolsHelper
arguments:
- '@entity_type.manager'
- '@plugin.manager.menu.local_task'
- '@current_route_match'
- '@config.factory'

View File

@@ -0,0 +1,47 @@
.toolbar-icon-admin-toolbar-tools-help {
text-indent: -9999px;
}
.toolbar-icon-9 .toolbar-icon-admin-toolbar-tools-help:before,
.toolbar-icon-10 .toolbar-icon-admin-toolbar-tools-help:before {
box-sizing: content-box;
background-image: url(../misc/icons/ffffff/drupal-9-logo.svg);
padding-bottom: 0;
padding-left: 2px;
padding-right: 2px;
padding-top: 2px;
margin-left: 4px;
}
.toolbar-icon-9 .toolbar-icon-admin-toolbar-tools-help:active:before,
.toolbar-icon-9 .toolbar-icon-admin-toolbar-tools-help.active:before,
.toolbar-icon-10 .toolbar-icon-admin-toolbar-tools-help:active:before,
.toolbar-icon-10 .toolbar-icon-admin-toolbar-tools-help.active:before {
background-image: url(../misc/icons/ffffff/drupal-9-logo.svg);
}
.toolbar-icon-8 .toolbar-icon-admin-toolbar-tools-help:before {
box-sizing: content-box;
background-image: url(../misc/icons/ffffff/drupal-8-logo.svg);
padding-bottom: 0;
padding-left: 4px;
padding-right: 8px;
padding-top: 2px;
}
.toolbar-icon-8 .toolbar-icon-admin-toolbar-tools-help:active:before,
.toolbar-icon-8 .toolbar-icon-admin-toolbar-tools-help.active:before {
background-image: url(../misc/icons/ffffff/drupal-8-logo.svg);
}
.toolbar-oriented .toolbar-bar .local-tasks-toolbar-tab {
float: right;
}
.toolbar-horizontal .local-tasks-toolbar-tab .toolbar-menu {
float: right;
}
.toolbar-bar .toolbar-icon-local-tasks:before {
background-image: url(../misc/icons/bebebe/tasks.svg);
}

View File

@@ -0,0 +1,4 @@
<svg fill="#bebebe" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z"/>
<path d="M0 0h24v24H0V0z" fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 434 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMinYMin" viewBox="0 0 611 646"><path fill="#2ba9e0" d="M 161.14248,607.07981 C 135.931,577.51327 120.7662,539.33875 120.7662,497.60876 c 0,-87.01545 66.15644,-158.68624 151.648,-168.60413 -14.59612,-20.95856 -23.31588,-46.40824 -23.31588,-73.72922 0,-71.85792 58.95316,-129.86822 131.7442,-129.86822 6.06592,0 11.94228,0.37426 17.62908,1.12278 C 355.44148,89.85249 312.41136,52.61362 278.48012,12.00641 295.73008,190.15417 114.1316,125.40719 46.8378,289.70733 1.91208,399.73977 42.47792,535.78328 161.14248,607.07981 Z m 143.1178,-351.8044 c 0,41.72999 34.31036,75.41339 76.39268,75.41339 42.08232,0 76.58224,-33.87053 76.58224,-75.41339 0,-41.72999 -34.31036,-75.41339 -76.39268,-75.41339 -42.08232,0 -76.58224,33.6834 -76.58224,75.41339 z m 112.97776,124.81571 c 29.57136,30.50219 47.76912,71.85792 47.76912,117.51764 0,57.82317 -29.19224,108.72253 -73.73884,139.41185 82.4586,-25.07542 150.7002,-86.26693 181.21936,-160.37041 42.27188,-102.54724 2.8434,-179.6448 -63.12348,-249.63142 2.08516,8.98224 3.22252,18.52587 3.22252,28.0695 -0.18956,59.50734 -40.37628,109.47105 -95.34868,125.00284 z m -124.35136,18.90013 c -55.16196,0 -99.89812,44.16268 -99.89812,98.61751 0,54.45483 44.73616,98.61751 99.89812,98.61751 55.16196,0 99.89812,-44.16268 99.89812,-98.61751 0,-54.45483 -44.73616,-98.61751 -99.89812,-98.61751 z" /></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 42.15 55.08"><defs><style>.cls-1{fill:#009cde;}</style></defs><title>Risorsa 23</title><g id="Livello_2" data-name="Livello 2"><g id="Livello_1-2" data-name="Livello 1"><path class="cls-1" d="M29.75,11.73C25.87,7.86,22.18,4.16,21.08,0,20,4.16,16.28,7.86,12.4,11.73,6.59,17.54,0,24.12,0,34a21.08,21.08,0,1,0,42.15,0C42.15,24.12,35.56,17.54,29.75,11.73ZM10.84,35.92a14.13,14.13,0,0,0-1.65,2.62.54.54,0,0,1-.36.3H8.65c-.47,0-1-.92-1-.92h0c-.14-.22-.27-.45-.4-.69l-.09-.19C5.94,34.25,7,30.28,7,30.28h0a17.42,17.42,0,0,1,2.52-5.41,31.53,31.53,0,0,1,2.28-3l1,1,4.72,4.82a.54.54,0,0,1,0,.72l-4.93,5.47h0ZM21.32,49.73a7.29,7.29,0,0,1-5.4-12.14c1.54-1.83,3.42-3.63,5.46-6,2.42,2.58,4,4.35,5.55,6.29a3.08,3.08,0,0,1,.32.48,7.15,7.15,0,0,1,1.3,4.12A7.23,7.23,0,0,1,21.32,49.73ZM35,38.14v0a.84.84,0,0,1-.67.58h-.14a1.22,1.22,0,0,1-.68-.55h0a37.77,37.77,0,0,0-4.28-5.31l-1.93-2-6.41-6.65a54,54,0,0,1-3.84-3.94,1.3,1.3,0,0,0-.1-.15,3.84,3.84,0,0,1-.51-1c0-.06,0-.13,0-.19a3.4,3.4,0,0,1,1-3c1.24-1.24,2.49-2.49,3.67-3.79,1.3,1.44,2.69,2.82,4.06,4.19v0a57.6,57.6,0,0,1,7.55,8.58A16,16,0,0,1,35.65,34,14.55,14.55,0,0,1,35,38.14Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,174 @@
<?php
namespace Drupal\admin_toolbar_tools;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Menu\LocalTaskManagerInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
/**
* Admin Toolbar Tools helper service.
*/
class AdminToolbarToolsHelper {
use StringTranslationTrait;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The local task manger.
*
* @var \Drupal\Core\Menu\LocalTaskManagerInterface
* The local task manager menu.
*/
protected $localTaskManager;
/**
* The route match interface.
*
* @var \Drupal\Core\Routing\RouteMatchInterface
* The route match.
*/
protected $routeMatch;
/**
* The configuration factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* Create an AdminToolbarToolsHelper object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Menu\LocalTaskManagerInterface $local_task_manager
* The local task manager.
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The route match.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The configuration factory.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, LocalTaskManagerInterface $local_task_manager, RouteMatchInterface $route_match, ConfigFactoryInterface $config_factory) {
$this->entityTypeManager = $entity_type_manager;
$this->localTaskManager = $local_task_manager;
$this->routeMatch = $route_match;
$this->configFactory = $config_factory;
}
/**
* Generate the toolbar tab and item for primary local tasks.
*
* @return array
* The toolbar render array.
*/
public function buildLocalTasksToolbar() {
$build = [];
$config = $this->configFactory->get('admin_toolbar_tools.settings');
$cacheability = CacheableMetadata::createFromObject($config);
if ($config->get('show_local_tasks')) {
$local_tasks = $this->localTaskManager->getLocalTasks($this->routeMatch->getRouteName());
$cacheability = $cacheability->merge($local_tasks['cacheability']);
$cacheability = $cacheability->merge(CacheableMetadata::createFromObject($this->localTaskManager));
if (!empty($local_tasks['tabs'])) {
$local_task_links = [
'#theme' => 'links',
'#links' => [],
'#attributes' => [
'class' => ['toolbar-menu'],
],
];
// Sort the links by weight.
Element::children($local_tasks['tabs'], TRUE);
// Only show the accessible local tasks.
foreach (Element::getVisibleChildren($local_tasks['tabs']) as $task) {
$local_task_links['#links'][$task] = $local_tasks['tabs'][$task]['#link'];
if ($local_tasks['tabs'][$task]['#active']) {
$local_task_links['#links'][$task]['attributes']['class'][] = 'is-active';
}
}
$build = [
'#type' => 'toolbar_item',
'#wrapper_attributes' => [
'class' => ['local-tasks-toolbar-tab'],
],
// Put it after contextual toolbar item so when float right is applied
// local tasks item will be first.
'#weight' => 10,
'tab' => [
// We can't use #lazy_builder here because
// ToolbarItem::preRenderToolbarItem will insert #attributes before
// lazy_builder callback and this will produce Exception.
// This means that for now we always render Local Tasks item even
// when the tray is empty.
'#type' => 'link',
'#title' => $this->t('Local Tasks'),
'#url' => Url::fromRoute('<none>'),
'#attributes' => [
'class' => [
'toolbar-icon',
'toolbar-icon-local-tasks',
],
],
],
'tray' => [
'local_tasks' => $local_task_links,
],
'#attached' => ['library' => ['admin_toolbar_tools/toolbar.icon']],
];
}
}
$cacheability->applyTo($build);
return $build;
}
/**
* Gets a list of content entities.
*
* @return array
* An array of metadata about content entities.
*/
public function getBundleableEntitiesList() {
$entity_types = $this->entityTypeManager->getDefinitions();
$content_entities = [];
foreach ($entity_types as $key => $entity_type) {
if ($entity_type->getBundleEntityType() && ($entity_type->get('field_ui_base_route') != '')) {
$content_entities[$key] = [
'content_entity' => $key,
'content_entity_bundle' => $entity_type->getBundleEntityType(),
];
}
}
return $content_entities;
}
/**
* Gets an array of entity types that should trigger a menu rebuild.
*
* @return array
* An array of entity machine names.
*/
public function getRebuildEntityTypes() {
$types = ['menu'];
$content_entities = $this->getBundleableEntitiesList();
$types = array_merge($types, array_column($content_entities, 'content_entity_bundle'));
return $types;
}
}

View File

@@ -0,0 +1,295 @@
<?php
namespace Drupal\admin_toolbar_tools\Controller;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\CronInterface;
use Drupal\Core\Menu\ContextualLinkManager;
use Drupal\Core\Menu\LocalActionManager;
use Drupal\Core\Menu\LocalTaskManager;
use Drupal\Core\Menu\MenuLinkManagerInterface;
use Drupal\Core\Plugin\CachedDiscoveryClearerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\Core\Template\TwigEnvironment;
use Drupal\Core\Theme\Registry;
/**
* Controller for AdminToolbar Tools.
*
* @package Drupal\admin_toolbar_tools\Controller
*/
class ToolbarController extends ControllerBase {
/**
* A cron instance.
*
* @var \Drupal\Core\CronInterface
*/
protected $cron;
/**
* A menu link manager instance.
*
* @var \Drupal\Core\Menu\MenuLinkManagerInterface
*/
protected $menuLinkManager;
/**
* A context link manager instance.
*
* @var \Drupal\Core\Menu\ContextualLinkManager
*/
protected $contextualLinkManager;
/**
* A local task manager instance.
*
* @var \Drupal\Core\Menu\LocalTaskManager
*/
protected $localTaskLinkManager;
/**
* A local action manager instance.
*
* @var \Drupal\Core\Menu\LocalActionManager
*/
protected $localActionLinkManager;
/**
* A cache backend interface instance.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cacheRender;
/**
* A date time instance.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
/**
* A request stack symfony instance.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* A plugin cache clear instance.
*
* @var \Drupal\Core\Plugin\CachedDiscoveryClearerInterface
*/
protected $pluginCacheClearer;
/**
* The cache menu instance.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cacheMenu;
/**
* A TwigEnvironment instance.
*
* @var \Drupal\Core\Template\TwigEnvironment
*/
protected $twig;
/**
* The search theme.registry service.
*
* @var \Drupal\Core\Theme\Registry
*/
protected $themeRegistry;
/**
* Constructs a ToolbarController object.
*
* @param \Drupal\Core\CronInterface $cron
* A cron instance.
* @param \Drupal\Core\Menu\MenuLinkManagerInterface $menuLinkManager
* A menu link manager instance.
* @param \Drupal\Core\Menu\ContextualLinkManager $contextualLinkManager
* A context link manager instance.
* @param \Drupal\Core\Menu\LocalTaskManager $localTaskLinkManager
* A local task manager instance.
* @param \Drupal\Core\Menu\LocalActionManager $localActionLinkManager
* A local action manager instance.
* @param \Drupal\Core\Cache\CacheBackendInterface $cacheRender
* A cache backend interface instance.
* @param \Drupal\Component\Datetime\TimeInterface $time
* A date time instance.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* A request stack symfony instance.
* @param \Drupal\Core\Plugin\CachedDiscoveryClearerInterface $plugin_cache_clearer
* A plugin cache clear instance.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache_menu
* A cache menu instance.
* @param \Drupal\Core\Template\TwigEnvironment $twig
* A TwigEnvironment instance.
* @param \Drupal\Core\Theme\Registry $theme_registry
* The theme.registry service.
*/
public function __construct(
CronInterface $cron,
MenuLinkManagerInterface $menuLinkManager,
ContextualLinkManager $contextualLinkManager,
LocalTaskManager $localTaskLinkManager,
LocalActionManager $localActionLinkManager,
CacheBackendInterface $cacheRender,
TimeInterface $time,
RequestStack $request_stack,
CachedDiscoveryClearerInterface $plugin_cache_clearer,
CacheBackendInterface $cache_menu,
TwigEnvironment $twig,
Registry $theme_registry
) {
$this->cron = $cron;
$this->menuLinkManager = $menuLinkManager;
$this->contextualLinkManager = $contextualLinkManager;
$this->localTaskLinkManager = $localTaskLinkManager;
$this->localActionLinkManager = $localActionLinkManager;
$this->cacheRender = $cacheRender;
$this->time = $time;
$this->requestStack = $request_stack;
$this->pluginCacheClearer = $plugin_cache_clearer;
$this->cacheMenu = $cache_menu;
$this->twig = $twig;
$this->themeRegistry = $theme_registry;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('cron'),
$container->get('plugin.manager.menu.link'),
$container->get('plugin.manager.menu.contextual_link'),
$container->get('plugin.manager.menu.local_task'),
$container->get('plugin.manager.menu.local_action'),
$container->get('cache.render'),
$container->get('datetime.time'),
$container->get('request_stack'),
$container->get('plugin.cache_clearer'),
$container->get('cache.menu'),
$container->get('twig'),
$container->get('theme.registry')
);
}
/**
* Reload the previous page.
*/
public function reloadPage() {
$request = $this->requestStack->getCurrentRequest();
if ($request->server->get('HTTP_REFERER')) {
return $request->server->get('HTTP_REFERER');
}
else {
return base_path();
}
}
/**
* Flushes all caches.
*/
public function flushAll() {
$this->messenger()->addMessage($this->t('All caches cleared.'));
drupal_flush_all_caches();
return new RedirectResponse($this->reloadPage());
}
/**
* Flushes css and javascript caches.
*/
public function flushJsCss() {
$this->state()
->set('system.css_js_query_string', base_convert($this->time->getCurrentTime(), 10, 36));
$this->messenger()->addMessage($this->t('CSS and JavaScript cache cleared.'));
return new RedirectResponse($this->reloadPage());
}
/**
* Flushes plugins caches.
*/
public function flushPlugins() {
$this->pluginCacheClearer->clearCachedDefinitions();
$this->messenger()->addMessage($this->t('Plugins cache cleared.'));
return new RedirectResponse($this->reloadPage());
}
/**
* Resets all static caches.
*/
public function flushStatic() {
drupal_static_reset();
$this->messenger()->addMessage($this->t('Static cache cleared.'));
return new RedirectResponse($this->reloadPage());
}
/**
* Clears all cached menu data.
*/
public function flushMenu() {
$this->cacheMenu->invalidateAll();
$this->menuLinkManager->rebuild();
$this->contextualLinkManager->clearCachedDefinitions();
$this->localTaskLinkManager->clearCachedDefinitions();
$this->localActionLinkManager->clearCachedDefinitions();
$this->messenger()->addMessage($this->t('Routing and links cache cleared.'));
return new RedirectResponse($this->reloadPage());
}
/**
* Clears all cached views data.
*/
public function flushViews() {
views_invalidate_cache();
$this->messenger()->addMessage($this->t('Views cache cleared.'));
return new RedirectResponse($this->reloadPage());
}
/**
* Clears the twig cache.
*/
public function flushTwig() {
$this->twig->invalidate();
$this->messenger()->addMessage($this->t('Twig cache cleared.'));
return new RedirectResponse($this->reloadPage());
}
/**
* Run the cron.
*/
public function runCron() {
$this->cron->run();
$this->messenger()->addMessage($this->t('Cron ran successfully.'));
return new RedirectResponse($this->reloadPage());
}
/**
* Clear the rendered cache.
*/
public function cacheRender() {
$this->cacheRender->invalidateAll();
$this->messenger()->addMessage($this->t('Render cache cleared.'));
return new RedirectResponse($this->reloadPage());
}
/**
* Rebuild the theme registry.
*/
public function themeRebuild() {
$this->themeRegistry->reset();
$this->messenger()->addMessage($this->t('Theme registry rebuilt.'));
return new RedirectResponse($this->reloadPage());
}
}

View File

@@ -0,0 +1,119 @@
<?php
namespace Drupal\admin_toolbar_tools\Form;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Menu\MenuLinkManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Settings form for AdminToolbar Tools.
*
* @package Drupal\admin_toolbar_tools\Form
*/
class AdminToolbarToolsSettingsForm extends ConfigFormBase {
/**
* The cache menu instance.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cacheMenu;
/**
* The menu link manager instance.
*
* @var \Drupal\Core\Menu\MenuLinkManagerInterface
*/
protected $menuLinkManager;
/**
* AdminToolbarToolsSettingsForm constructor.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The factory for configuration objects.
* @param \Drupal\Core\Menu\MenuLinkManagerInterface $menuLinkManager
* A menu link manager instance.
* @param \Drupal\Core\Cache\CacheBackendInterface $cacheMenu
* A cache menu instance.
*/
public function __construct(ConfigFactoryInterface $configFactory, MenuLinkManagerInterface $menuLinkManager, CacheBackendInterface $cacheMenu) {
parent::__construct($configFactory);
$this->cacheMenu = $cacheMenu;
$this->menuLinkManager = $menuLinkManager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory'),
$container->get('plugin.manager.menu.link'),
$container->get('cache.menu')
);
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
'admin_toolbar_tools.settings',
];
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'admin_toolbar_tools_settings';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('admin_toolbar_tools.settings');
$form['max_bundle_number'] = [
'#type' => 'number',
'#title' => $this->t('Maximum number of bundle sub-menus to display'),
'#description' => $this->t('Loading a large number of items can cause performance issues.'),
'#default_value' => $config->get('max_bundle_number'),
];
$form['hoverintent_functionality'] = [
'#type' => 'checkbox',
'#title' => $this->t('Enable/Disable the hoverintent functionality'),
'#description' => $this->t('Check it if you want to enable the hoverintent feature.'),
'#default_value' => $config->get('hoverintent_functionality'),
];
$form['show_local_tasks'] = [
'#type' => 'checkbox',
'#title' => $this->t('Enable/Disable local tasks display'),
'#description' => $this->t('Local tasks such as node edit and delete.'),
'#default_value' => $config->get('show_local_tasks'),
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('admin_toolbar_tools.settings')
->set('max_bundle_number', $form_state->getValue('max_bundle_number'))
->set('hoverintent_functionality', $form_state->getValue('hoverintent_functionality'))
->set('show_local_tasks', $form_state->getValue('show_local_tasks'))
->save();
parent::submitForm($form, $form_state);
$this->cacheMenu->invalidateAll();
$this->menuLinkManager->rebuild();
}
}

View File

@@ -0,0 +1,723 @@
<?php
namespace Drupal\admin_toolbar_tools\Plugin\Derivative;
use Drupal\system\Entity\Menu;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a default implementation for menu link plugins.
*/
class ExtraLinks extends DeriverBase implements ContainerDeriverInterface {
use StringTranslationTrait;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The route provider.
*
* @var \Drupal\Core\Routing\RouteProviderInterface
*/
protected $routeProvider;
/**
* The theme handler.
*
* @var \Drupal\Core\Extension\ThemeHandlerInterface
*/
protected $themeHandler;
/**
* The admin toolbar tools configuration.
*
* @var \Drupal\Core\Config\Config
*/
protected $config;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* {@inheritdoc}
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler, RouteProviderInterface $route_provider, ThemeHandlerInterface $theme_handler, ConfigFactoryInterface $config_factory, AccountInterface $current_user) {
$this->entityTypeManager = $entity_type_manager;
$this->moduleHandler = $module_handler;
$this->routeProvider = $route_provider;
$this->themeHandler = $theme_handler;
$this->config = $config_factory->get('admin_toolbar_tools.settings');
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $base_plugin_id) {
return new static(
$container->get('entity_type.manager'),
$container->get('module_handler'),
$container->get('router.route_provider'),
$container->get('theme_handler'),
$container->get('config.factory'),
$container->get('current_user')
);
}
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
$links = [];
$max_bundle_number = $this->config->get('max_bundle_number');
$entity_types = $this->entityTypeManager->getDefinitions();
$content_entities = [];
foreach ($entity_types as $key => $entity_type) {
if ($entity_type->getBundleEntityType() && ($entity_type->get('field_ui_base_route') != '')) {
$content_entities[$key] = [
'content_entity' => $key,
'content_entity_bundle' => $entity_type->getBundleEntityType(),
];
}
}
// Adds common links to entities.
foreach ($content_entities as $entities) {
$content_entity_bundle = $entities['content_entity_bundle'];
$content_entity = $entities['content_entity'];
$content_entity_bundle_storage = $this->entityTypeManager->getStorage($content_entity_bundle);
$bundles_ids = $content_entity_bundle_storage->getQuery()->sort('weight')->pager($max_bundle_number)->execute();
$bundles = $this->entityTypeManager->getStorage($content_entity_bundle)->loadMultiple($bundles_ids);
if (count($bundles) == $max_bundle_number && $this->routeExists('entity.' . $content_entity_bundle . '.collection')) {
$links[$content_entity_bundle . '.collection'] = [
'title' => $this->t('All types'),
'route_name' => 'entity.' . $content_entity_bundle . '.collection',
'parent' => 'entity.' . $content_entity_bundle . '.collection',
'weight' => -999,
] + $base_plugin_definition;
}
foreach ($bundles as $machine_name => $bundle) {
// Normally, the edit form for the bundle would be its root link.
$content_entity_bundle_root = NULL;
if ($this->routeExists('entity.' . $content_entity_bundle . '.overview_form')) {
// Some bundles have an overview/list form that make a better root
// link.
$content_entity_bundle_root = 'entity.' . $content_entity_bundle . '.overview_form.' . $machine_name;
$links[$content_entity_bundle_root] = [
'route_name' => 'entity.' . $content_entity_bundle . '.overview_form',
'parent' => 'entity.' . $content_entity_bundle . '.collection',
'route_parameters' => [$content_entity_bundle => $machine_name],
'class' => 'Drupal\admin_toolbar_tools\Plugin\Menu\MenuLinkEntity',
'metadata' => [
'entity_type' => $bundle->getEntityTypeId(),
'entity_id' => $bundle->id(),
],
] + $base_plugin_definition;
$weight = $bundles[$machine_name]->get('weight');
if (isset($weight) && is_numeric($weight)) {
$links[$content_entity_bundle_root]['weight'] = $weight;
}
}
if ($this->routeExists('entity.' . $content_entity_bundle . '.edit_form')) {
$key = 'entity.' . $content_entity_bundle . '.edit_form.' . $machine_name;
$links[$key] = [
'route_name' => 'entity.' . $content_entity_bundle . '.edit_form',
'parent' => 'entity.' . $content_entity_bundle . '.collection',
'route_parameters' => [$content_entity_bundle => $machine_name],
] + $base_plugin_definition;
if (empty($content_entity_bundle_root)) {
$content_entity_bundle_root = $key;
$links[$key]['parent'] = 'entity.' . $content_entity_bundle . '.collection';
// When not grouped by bundle, use bundle name as title.
$links[$key]['class'] = 'Drupal\admin_toolbar_tools\Plugin\Menu\MenuLinkEntity';
$links[$key]['metadata'] = [
'entity_type' => $bundle->getEntityTypeId(),
'entity_id' => $bundle->id(),
];
}
else {
$links[$key]['parent'] = $base_plugin_definition['id'] . ':' . $content_entity_bundle_root;
$links[$key]['title'] = $this->t('Edit');
}
}
if ($this->moduleHandler->moduleExists('field_ui')) {
if ($this->routeExists('entity.' . $content_entity . '.field_ui_fields')) {
$links['entity.' . $content_entity . '.field_ui_fields' . $machine_name] = [
'title' => $this->t('Manage fields'),
'route_name' => 'entity.' . $content_entity . '.field_ui_fields',
'parent' => $base_plugin_definition['id'] . ':' . $content_entity_bundle_root,
'route_parameters' => [$content_entity_bundle => $machine_name],
'weight' => 1,
] + $base_plugin_definition;
}
if ($this->routeExists('entity.entity_form_display.' . $content_entity . '.default')) {
$links['entity.entity_form_display.' . $content_entity . '.default' . $machine_name] = [
'title' => $this->t('Manage form display'),
'route_name' => 'entity.entity_form_display.' . $content_entity . '.default',
'parent' => $base_plugin_definition['id'] . ':' . $content_entity_bundle_root,
'route_parameters' => [$content_entity_bundle => $machine_name],
'weight' => 2,
] + $base_plugin_definition;
}
if ($this->routeExists('entity.entity_view_display.' . $content_entity . '.default')) {
$links['entity.entity_view_display.' . $content_entity . '.default.' . $machine_name] = [
'title' => $this->t('Manage display'),
'route_name' => 'entity.entity_view_display.' . $content_entity . '.default',
'parent' => $base_plugin_definition['id'] . ':' . $content_entity_bundle_root,
'route_parameters' => [$content_entity_bundle => $machine_name],
'weight' => 3,
] + $base_plugin_definition;
}
if ($this->routeExists('entity.' . $bundle->getEntityTypeId() . '.entity_permissions_form')) {
$links['entity.entity_permissions_form.' . $content_entity . '.default.' . $machine_name] = [
'title' => $this->t('Manage permissions'),
'route_name' => 'entity.' . $bundle->getEntityTypeId() . '.entity_permissions_form',
'parent' => $base_plugin_definition['id'] . ':' . $content_entity_bundle_root,
'route_parameters' => [
$bundle->getEntityTypeId() => $machine_name,
],
'weight' => 3,
] + $base_plugin_definition;
}
}
if ($this->moduleHandler->moduleExists('devel') && $this->routeExists('entity.' . $content_entity_bundle . '.devel_load')) {
$links['entity.' . $content_entity_bundle . '.devel_load.' . $machine_name] = [
'title' => $this->t('Devel'),
'route_name' => 'entity.' . $content_entity_bundle . '.devel_load',
'parent' => $base_plugin_definition['id'] . ':' . $content_entity_bundle_root,
'route_parameters' => [$content_entity_bundle => $machine_name],
'weight' => 4,
] + $base_plugin_definition;
}
if ($this->routeExists('entity.' . $content_entity_bundle . '.delete_form')) {
$links['entity.' . $content_entity_bundle . '.delete_form.' . $machine_name] = [
'title' => $this->t('Delete'),
'route_name' => 'entity.' . $content_entity_bundle . '.delete_form',
'parent' => $base_plugin_definition['id'] . ':' . $content_entity_bundle_root,
'route_parameters' => [$content_entity_bundle => $machine_name],
'weight' => 5,
] + $base_plugin_definition;
}
}
}
// Adds user links.
$links['user.admin_create'] = [
'title' => $this->t('Add user'),
'route_name' => 'user.admin_create',
'parent' => 'entity.user.collection',
] + $base_plugin_definition;
$links['user.admin_permissions'] = [
'title' => $this->t('Permissions'),
'route_name' => 'user.admin_permissions',
'parent' => 'entity.user.collection',
] + $base_plugin_definition;
$links['entity.user_role.collection'] = [
'title' => $this->t('Roles'),
'route_name' => 'entity.user_role.collection',
'parent' => 'entity.user.collection',
] + $base_plugin_definition;
$links['user.logout'] = [
'title' => $this->t('Logout'),
'route_name' => 'user.logout',
'parent' => 'admin_toolbar_tools.help',
'weight' => 10,
] + $base_plugin_definition;
$links['user.role_add'] = [
'title' => $this->t('Add role'),
'route_name' => 'user.role_add',
'parent' => $base_plugin_definition['id'] . ':entity.user_role.collection',
'weight' => -50,
] + $base_plugin_definition;
// Adds sub-links to Account settings link.
if ($this->moduleHandler->moduleExists('field_ui')) {
$links['entity.user.field_ui_fields_'] = [
'title' => $this->t('Manage fields'),
'route_name' => 'entity.user.field_ui_fields',
'parent' => 'entity.user.admin_form',
'weight' => 1,
] + $base_plugin_definition;
$links['entity.entity_form_display.user.default_'] = [
'title' => $this->t('Manage form display'),
'route_name' => 'entity.entity_form_display.user.default',
'parent' => 'entity.user.admin_form',
'weight' => 2,
] + $base_plugin_definition;
$links['entity.entity_view_display.user.default_'] = [
'title' => $this->t('Manage display'),
'route_name' => 'entity.entity_view_display.user.default',
'parent' => 'entity.user.admin_form',
'weight' => 3,
] + $base_plugin_definition;
}
foreach ($this->entityTypeManager->getStorage('user_role')->loadMultiple() as $role) {
$links['entity.user_role.edit_form.' . $role->id()] = [
'route_name' => 'entity.user_role.edit_form',
'parent' => $base_plugin_definition['id'] . ':entity.user_role.collection',
'weight' => $role->getWeight(),
'route_parameters' => ['user_role' => $role->id()],
'class' => 'Drupal\admin_toolbar_tools\Plugin\Menu\MenuLinkEntity',
'metadata' => [
'entity_type' => $role->getEntityTypeId(),
'entity_id' => $role->id(),
],
] + $base_plugin_definition;
$links['entity.user_role.edit_permissions_form.' . $role->id()] = [
'title' => $this->t('Edit permissions'),
'route_name' => 'entity.user_role.edit_permissions_form',
'parent' => $base_plugin_definition['id'] . ':entity.user_role.edit_form.' . $role->id(),
'route_parameters' => ['user_role' => $role->id()],
] + $base_plugin_definition;
if ($role->id() != 'anonymous' && $role->id() != 'authenticated') {
$links['entity.user_role.delete_form.' . $role->id()] = [
'title' => $this->t('Delete'),
'route_name' => 'entity.user_role.delete_form',
'parent' => $base_plugin_definition['id'] . ':entity.user_role.edit_form.' . $role->id(),
'route_parameters' => ['user_role' => $role->id()],
] + $base_plugin_definition;
}
if ($this->moduleHandler->moduleExists('devel')) {
$links['entity.user_role.devel_load.' . $role->id()] = [
'title' => $this->t('Devel'),
'route_name' => 'entity.user_role.devel_load',
'parent' => $base_plugin_definition['id'] . ':entity.user_role.edit_form.' . $role->id(),
'route_parameters' => ['user_role' => $role->id()],
] + $base_plugin_definition;
}
}
if ($this->moduleHandler->moduleExists('node')) {
$links['node.type_add'] = [
'title' => $this->t('Add content type'),
'route_name' => 'node.type_add',
'parent' => 'entity.node_type.collection',
'weight' => -2,
] + $base_plugin_definition;
$links['node.add'] = [
'title' => $this->t('Add content'),
'route_name' => 'node.add_page',
'parent' => 'system.admin_content',
] + $base_plugin_definition;
// Adds node links for each content type.
foreach ($this->entityTypeManager->getStorage('node_type')->loadMultiple() as $type) {
$links['node.add.' . $type->id()] = [
'route_name' => 'node.add',
'parent' => $base_plugin_definition['id'] . ':node.add',
'route_parameters' => ['node_type' => $type->id()],
'class' => 'Drupal\admin_toolbar_tools\Plugin\Menu\MenuLinkEntity',
'metadata' => [
'entity_type' => $type->getEntityTypeId(),
'entity_id' => $type->id(),
],
] + $base_plugin_definition;
}
}
if ($this->moduleHandler->moduleExists('field_ui')) {
$links['field_ui.entity_form_mode_add'] = [
'title' => $this->t('Add form mode'),
'route_name' => 'field_ui.entity_form_mode_add',
'parent' => 'entity.entity_form_mode.collection',
] + $base_plugin_definition;
$links['field_ui.entity_view_mode_add'] = [
'title' => $this->t('Add view mode'),
'route_name' => 'field_ui.entity_view_mode_add',
'parent' => 'entity.entity_view_mode.collection',
] + $base_plugin_definition;
}
if ($this->moduleHandler->moduleExists('taxonomy')) {
$links['entity.taxonomy_vocabulary.add_form'] = [
'title' => $this->t('Add vocabulary'),
'route_name' => 'entity.taxonomy_vocabulary.add_form',
'parent' => 'entity.taxonomy_vocabulary.collection',
'weight' => -998,
] + $base_plugin_definition;
}
if ($this->moduleHandler->moduleExists('menu_ui')) {
$links['entity.menu.add_form'] = [
'title' => $this->t('Add menu'),
'route_name' => 'entity.menu.add_form',
'parent' => 'entity.menu.collection',
'weight' => -2,
] + $base_plugin_definition;
// Adds links to /admin/structure/menu.
$menus = $this->entityTypeManager->getStorage('menu')->loadMultiple();
uasort($menus, [Menu::class, 'sort']);
$menus = array_slice($menus, 0, $max_bundle_number);
if (count($menus) == $max_bundle_number) {
$links['entity.menu.collection'] = [
'title' => $this->t('All menus'),
'route_name' => 'entity.menu.collection',
'parent' => 'entity.menu.collection',
'weight' => -1,
] + $base_plugin_definition;
}
$weight = 0;
foreach ($menus as $menu_id => $menu) {
$links['entity.menu.edit_form.' . $menu_id] = [
'route_name' => 'entity.menu.edit_form',
'parent' => 'entity.menu.collection',
'route_parameters' => ['menu' => $menu_id],
'weight' => $weight,
'class' => 'Drupal\admin_toolbar_tools\Plugin\Menu\MenuLinkEntity',
'metadata' => [
'entity_type' => $menu->getEntityTypeId(),
'entity_id' => $menu->id(),
],
] + $base_plugin_definition;
$links['entity.menu.add_link_form.' . $menu_id] = [
'title' => $this->t('Add link'),
'route_name' => 'entity.menu.add_link_form',
'parent' => $base_plugin_definition['id'] . ':entity.menu.edit_form.' . $menu_id,
'route_parameters' => ['menu' => $menu_id],
] + $base_plugin_definition;
// Un-deletable menus.
$un_deletable_menus = [
'admin',
'devel',
'footer',
'main',
'tools',
'account',
];
if (!in_array($menu_id, $un_deletable_menus)) {
$links['entity.menu.delete_form.' . $menu_id] = [
'title' => $this->t('Delete'),
'route_name' => 'entity.menu.delete_form',
'parent' => $base_plugin_definition['id'] . ':entity.menu.edit_form.' . $menu_id,
'route_parameters' => ['menu' => $menu_id],
] + $base_plugin_definition;
}
if ($this->moduleHandler->moduleExists('devel') && $this->routeExists('entity.menu.devel_load')) {
$links['entity.menu.devel_load.' . $menu_id] = [
'title' => $this->t('Devel'),
'route_name' => 'entity.menu.devel_load',
'parent' => $base_plugin_definition['id'] . ':entity.menu.edit_form.' . $menu_id,
'route_parameters' => ['menu' => $menu_id],
] + $base_plugin_definition;
}
$weight++;
}
}
// If module block_content is enabled.
if ($this->moduleHandler->moduleExists('block_content')) {
$links['block_content.add_page'] = [
'title' => $this->t('Add custom block'),
'route_name' => 'block_content.add_page',
'parent' => 'block.admin_display',
] + $base_plugin_definition;
$links['entity.block_content.collection'] = [
'title' => $this->t('Custom block library'),
'route_name' => 'entity.block_content.collection',
'parent' => 'block.admin_display',
] + $base_plugin_definition;
$links['entity.block_content_type.collection'] = [
'title' => $this->t('Block types'),
'route_name' => 'entity.block_content_type.collection',
'parent' => 'block.admin_display',
] + $base_plugin_definition;
}
// If module Contact is enabled.
if ($this->moduleHandler->moduleExists('contact')) {
$links['contact.form_add'] = [
'title' => $this->t('Add contact form'),
'route_name' => 'contact.form_add',
'parent' => 'entity.contact_form.collection',
'weight' => -5,
] + $base_plugin_definition;
}
// If module Update Manager is enabled.
if ($this->moduleHandler->moduleExists('update')) {
$links['update.module_install'] = [
'title' => $this->t('Install new module'),
'route_name' => 'update.module_install',
'parent' => 'system.modules_list',
] + $base_plugin_definition;
$links['update.module_update'] = [
'title' => $this->t('Update'),
'route_name' => 'update.module_update',
'parent' => 'system.modules_list',
] + $base_plugin_definition;
$links['update.theme_install'] = [
'title' => $this->t('Install new theme'),
'route_name' => 'update.theme_install',
'parent' => 'system.themes_page',
] + $base_plugin_definition;
$links['update.theme_update'] = [
'title' => $this->t('Update'),
'route_name' => 'update.theme_update',
'parent' => 'system.themes_page',
] + $base_plugin_definition;
}
// If module Devel is enabled.
if ($this->moduleHandler->moduleExists('devel')) {
$links['devel'] = [
'title' => $this->t('Development'),
'route_name' => 'system.admin_config_development',
'parent' => 'admin_toolbar_tools.help',
'weight' => '-8',
] + $base_plugin_definition;
$links['devel.admin_settings'] = [
'title' => $this->t('Devel settings'),
'route_name' => 'devel.admin_settings',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
$links['devel.configs_list'] = [
'title' => $this->t('Config editor'),
'route_name' => 'devel.configs_list',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
$links['devel.reinstall'] = [
'title' => $this->t('Reinstall modules'),
'route_name' => 'devel.reinstall',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
$links['devel.menu_rebuild'] = [
'title' => $this->t('Rebuild menu'),
'route_name' => 'devel.menu_rebuild',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
$links['devel.state_system_page'] = [
'title' => $this->t('State editor'),
'route_name' => 'devel.state_system_page',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
$links['devel.theme_registry'] = [
'title' => $this->t('Theme registry'),
'route_name' => 'devel.theme_registry',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
$links['devel.entity_info_page'] = [
'title' => $this->t('Entity info'),
'route_name' => 'devel.entity_info_page',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
$links['devel.session'] = [
'title' => $this->t('Session viewer'),
'route_name' => 'devel.session',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
$links['devel.element_info'] = [
'title' => $this->t('Element Info'),
'route_name' => 'devel.elements_page',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
// Menu link for the Toolbar module.
$links['devel.toolbar.settings'] = [
'title' => $this->t('Devel Toolbar Settings'),
'route_name' => 'devel.toolbar.settings_form',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
if ($this->moduleHandler->moduleExists('webprofiler')) {
$links['devel.webprofiler'] = [
'title' => $this->t('Webprofiler settings'),
'route_name' => 'webprofiler.settings',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
}
// If module Devel PHP is enabled.
if ($this->moduleHandler->moduleExists('devel_php') && $this->routeExists('devel_php.execute_php')) {
$links['devel.devel_php.execute_php'] = [
'title' => $this->t('Execute PHP Code'),
'route_name' => 'devel_php.execute_php',
'parent' => $base_plugin_definition['id'] . ':devel',
] + $base_plugin_definition;
}
}
// If module Views Ui enabled.
if ($this->moduleHandler->moduleExists('views_ui')) {
$links['views_ui.add'] = [
'title' => $this->t('Add view'),
'route_name' => 'views_ui.add',
'parent' => 'entity.view.collection',
'weight' => -5,
] + $base_plugin_definition;
$views = $this->entityTypeManager->getStorage('view')->loadMultiple();
foreach ($views as $view) {
$links['views_ui.' . $view->id()] = [
'title' => $view->label(),
'route_name' => 'entity.view.edit_form',
'route_parameters' => ['view' => $view->id()],
'parent' => 'entity.view.collection',
] + $base_plugin_definition;
}
$links['views_ui.field_list'] = [
'title' => $this->t('Used in views'),
'route_name' => 'views_ui.reports_fields',
'parent' => 'entity.field_storage_config.collection',
] + $base_plugin_definition;
}
// Adds theme management links.
$links['system.theme_settings'] = [
'title' => $this->t('Settings'),
'route_name' => 'system.theme_settings',
'parent' => 'system.themes_page',
] + $base_plugin_definition;
$installed_themes = $this->installedThemes();
foreach ($installed_themes as $key_theme => $label_theme) {
$links['system.theme_settings_theme.' . $key_theme] = [
'title' => $label_theme,
'route_name' => 'system.theme_settings_theme',
'parent' => $base_plugin_definition['id'] . ':system.theme_settings',
'route_parameters' => ['theme' => $key_theme],
] + $base_plugin_definition;
}
// If module Language enabled.
if ($this->moduleHandler->moduleExists('language')) {
$links['language.negotiation'] = [
'title' => $this->t('Detection and selection'),
'route_name' => 'language.negotiation',
'parent' => 'entity.configurable_language.collection',
] + $base_plugin_definition;
$links['language.add'] = [
'title' => $this->t('Add language'),
'route_name' => 'language.add',
'parent' => 'entity.configurable_language.collection',
] + $base_plugin_definition;
}
// If module Media enabled.
if ($this->moduleHandler->moduleExists('media')) {
$links['media.type_add'] = [
'title' => $this->t('Add media type'),
'route_name' => 'entity.media_type.add_form',
'parent' => 'entity.media_type.collection',
'weight' => -2,
] + $base_plugin_definition;
// Displays media link in toolbar.
$links['media_page'] = [
'title' => $this->t('Media'),
'route_name' => 'entity.media.collection',
'parent' => 'system.admin_content',
] + $base_plugin_definition;
if ($this->moduleHandler->moduleExists('media_library') && $this->routeExists('view.media_library.page')) {
$links['media_library'] = [
'title' => $this->t('Media library'),
'route_name' => 'view.media_library.page',
'parent' => $base_plugin_definition['id'] . ':media_page',
] + $base_plugin_definition;
}
$links['add_media'] = [
'title' => $this->t('Add media'),
'route_name' => 'entity.media.add_page',
'parent' => $base_plugin_definition['id'] . ':media_page',
] + $base_plugin_definition;
// Adds links for each media type.
foreach ($this->entityTypeManager->getStorage('media_type')->loadMultiple() as $type) {
$links['media.add.' . $type->id()] = [
'route_name' => 'entity.media.add_form',
'parent' => $base_plugin_definition['id'] . ':add_media',
'route_parameters' => ['media_type' => $type->id()],
'class' => 'Drupal\admin_toolbar_tools\Plugin\Menu\MenuLinkEntity',
'metadata' => [
'entity_type' => $type->getEntityTypeId(),
'entity_id' => $type->id(),
],
] + $base_plugin_definition;
}
}
// If module Config enabled.
if ($this->moduleHandler->moduleExists('config')) {
$links['config.import'] = [
'title' => $this->t('Import'),
'route_name' => 'config.import_full',
'parent' => 'config.sync',
'weight' => 1,
] + $base_plugin_definition;
$links['config.export'] = [
'title' => $this->t('Export'),
'route_name' => 'config.export_full',
'parent' => 'config.sync',
'weight' => 2,
] + $base_plugin_definition;
}
// Adds a menu link to clear Views cache.
if ($this->moduleHandler->moduleExists('views')) {
$links['flush_views'] = [
'title' => $this->t('Flush views cache'),
'route_name' => 'admin_toolbar_tools.flush_views',
'parent' => 'admin_toolbar_tools.flush',
] + $base_plugin_definition;
// Adding a menu link to Files.
if ($this->moduleHandler->moduleExists('file') && $this->routeExists('view.files.page_1')) {
$links['view.files'] = [
'title' => $this->t('Files'),
'route_name' => 'view.files.page_1',
'parent' => 'system.admin_content',
] + $base_plugin_definition;
}
}
return $links;
}
/**
* Determine if a route exists by name.
*
* @param string $route_name
* The name of the route to check.
*
* @return bool
* Whether a route with that route name exists.
*/
public function routeExists($route_name) {
return (count($this->routeProvider->getRoutesByNames([$route_name])) === 1);
}
/**
* Lists all installed themes.
*
* @return array
* The list of installed themes.
*/
public function installedThemes() {
$themeHandler = $this->themeHandler;
$all_themes = $themeHandler->listInfo();
$themes_installed = [];
foreach ($all_themes as $key_theme => $theme) {
if ($themeHandler->hasUi($key_theme)) {
$themes_installed[$key_theme] = $themeHandler->getName($key_theme);
}
}
return $themes_installed;
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace Drupal\admin_toolbar_tools\Plugin\Menu;
use Drupal\Core\Entity\EntityDescriptionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Menu\MenuLinkDefault;
use Drupal\Core\Menu\StaticMenuLinkOverridesInterface;
use Drupal\node\NodeTypeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a menu link plugins for configuration entities.
*/
class MenuLinkEntity extends MenuLinkDefault {
/**
* The entity represented in the menu link.
*
* @var \Drupal\Core\Entity\EntityInterface
*/
protected $entity;
/**
* Constructs a new MenuLinkEntity.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Menu\StaticMenuLinkOverridesInterface $static_override
* The static override storage.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, StaticMenuLinkOverridesInterface $static_override, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $static_override);
$this->entity = $entity_type_manager->getStorage($this->pluginDefinition['metadata']['entity_type'])->load($this->pluginDefinition['metadata']['entity_id']);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('menu_link.static.overrides'),
$container->get('entity_type.manager')
);
}
/**
* {@inheritdoc}
*/
public function getTitle() {
if ($this->entity) {
return (string) $this->entity->label();
}
return $this->pluginDefinition['title'] ?: $this->t('Missing');
}
/**
* {@inheritdoc}
*/
public function getDescription() {
// @todo Remove node_type special handling.
if ($this->entity instanceof EntityDescriptionInterface || $this->entity instanceof NodeTypeInterface) {
return $this->entity->getDescription();
}
return parent::getDescription();
}
/**
* {@inheritdoc}
*/
public function getCacheContexts() {
if ($this->entity) {
return $this->entity->getCacheContexts();
}
return parent::getCacheContexts();
}
/**
* {@inheritdoc}
*/
public function getCacheTags() {
if ($this->entity) {
return $this->entity->getCacheTags();
}
return parent::getCacheTags();
}
/**
* {@inheritdoc}
*/
public function getCacheMaxAge() {
if ($this->entity) {
return $this->entity->getCacheMaxAge();
}
return parent::getCacheMaxAge();
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Drupal\Tests\admin_toolbar_tools\Functional;
use Drupal\Tests\BrowserTestBase;
/**
* Tests for the existence of Admin Toolbar tools new links.
*
* @group admin_toolbar
*/
class AdminToolbarToolsAlterTest extends BrowserTestBase {
/**
* Modules to enable.
*
* @var array
*/
protected static $modules = [
'toolbar',
'admin_toolbar',
'admin_toolbar_tools',
];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* A test user with permission to access the administrative toolbar.
*
* @var \Drupal\user\UserInterface
*/
protected $adminUser;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
// Create and log in an administrative user.
$this->adminUser = $this->drupalCreateUser([
'access toolbar',
'access administration pages',
'administer site configuration',
]);
$this->drupalLogin($this->adminUser);
}
/**
* Tests for the hover of sub menus.
*/
public function testAdminToolbarTools() {
// Assert that special menu items are present in the HTML.
$this->assertSession()->responseContains('class="toolbar-icon toolbar-icon-admin-toolbar-tools-flush"');
}
}