updated contrib modules

This commit is contained in:
Bachir Soussi Chiadmi
2017-11-14 16:12:58 +01:00
parent c2b4e25be4
commit b32fe9ef14
317 changed files with 4672 additions and 13347 deletions
@@ -6,8 +6,8 @@ type: module
dependencies:
- toolbar
# Information added by Drupal.org packaging script on 2017-04-06
version: '8.x-1.19'
# Information added by Drupal.org packaging script on 2017-09-12
version: '8.x-1.20'
core: '8.x'
project: 'admin_toolbar'
datestamp: 1491487686
datestamp: 1505199847
@@ -3,6 +3,7 @@ toolbar.tree:
theme:
css/admin.toolbar.css: {}
js:
js/jquery.hoverIntent.js: {}
js/admin_toolbar.js: {}
dependencies:
- core/jquery
@@ -13,7 +13,7 @@ use Drupal\Core\Url;
* Implements hook_toolbar_alter().
*/
function admin_toolbar_toolbar_alter(&$items) {
$items['administration']['tray']['toolbar_administration']['#pre_render'] = array('admin_toolbar_prerender_toolbar_administration_tray');
$items['administration']['tray']['toolbar_administration']['#pre_render'] = ['admin_toolbar_prerender_toolbar_administration_tray'];
$items['administration']['#attached']['library'][] = 'admin_toolbar/toolbar.tree';
}
@@ -25,7 +25,7 @@ function admin_toolbar_help($route_name, RouteMatchInterface $route_match) {
case 'help.page.admin_toolbar':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Admin Toolbar module enhances the <a href=":toolbar">Toolbar</a> module by providing fast access to all the administrative links at the top of your site. Admin Toolbar remains a very "lightweight" module by closely integrating with all Toolbar functionality. It can be used in conjunction with all the sub or complimentary modules, listed on <a href="https://www.drupal.org/project/admin_toolbar">Admin Toolbar</a>, for quick access to system commands such as Flush all caches, <a href=":automated_cron">Run cron</a>, Run Updates, etc... For more information, see <a href=":admin_toolbar_documentation">the online documentation for the Admin Toolbar module</a>.', array(':toolbar' => Url::fromRoute('help.page', array('name' => 'toolbar'))->toString(), ':automated_cron' => (\Drupal::moduleHandler()->moduleExists('automated_cron')) ? Url::fromRoute('help.page', array('name' => 'automated_cron'))->toString() : '#', ':admin_toolbar_documentation' => 'https://www.drupal.org/node/2713693')) . '</p>';
$output .= '<p>' . t('The Admin Toolbar module enhances the <a href=":toolbar">Toolbar</a> module by providing fast access to all the administrative links at the top of your site. Admin Toolbar remains a very "lightweight" module by closely integrating with all Toolbar functionality. It can be used in conjunction with all the sub or complimentary modules, listed on <a href="https://www.drupal.org/project/admin_toolbar">Admin Toolbar</a>, for quick access to system commands such as Flush all caches, <a href=":automated_cron">Run cron</a>, Run Updates, etc... For more information, see <a href=":admin_toolbar_documentation">the online documentation for the Admin Toolbar module</a>.', [':toolbar' => Url::fromRoute('help.page', ['name' => 'toolbar'])->toString(), ':automated_cron' => (\Drupal::moduleHandler()->moduleExists('automated_cron')) ? Url::fromRoute('help.page', ['name' => 'automated_cron'])->toString() : '#', ':admin_toolbar_documentation' => 'https://www.drupal.org/node/2713693']) . '</p>';
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<p>' . t('The Admin Toolbar greatly improves the user experience for those who regularly interact with the Drupal Toolbar by providing fast, full access to all links in the Drupal Toolbar without having to click to get there.') . '</p>';
@@ -52,11 +52,11 @@ function admin_toolbar_prerender_toolbar_administration_tray(array $element) {
$parameters = new MenuTreeParameters();
$parameters->setRoot('system.admin')->excludeRoot()->setMaxDepth(4)->onlyEnabledLinks();
$tree = $menu_tree->load(NULL, $parameters);
$manipulators = array(
array('callable' => 'menu.default_tree_manipulators:checkAccess'),
array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
array('callable' => 'toolbar_tools_menu_navigation_links'),
);
$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);
$element['administration_menu'] = $menu_tree->build($tree);
@@ -83,7 +83,7 @@ function toolbar_tools_menu_navigation_links(array $tree) {
$definition = $link->getPluginDefinition();
$element->options['attributes']['class'][] = 'toolbar-icon';
$element->options['attributes']['class'][] = 'toolbar-icon-' . strtolower(str_replace(array('.', ' ', '_'), array('-', '-', '-'), $definition['id']));
$element->options['attributes']['class'][] = 'toolbar-icon-' . strtolower(str_replace(['.', ' ', '_'], ['-', '-', '-'], $definition['id']));
$element->options['attributes']['title'] = $link->getDescription();
}
return $tree;
@@ -6,8 +6,8 @@ type: module
dependencies:
- admin_toolbar
# Information added by Drupal.org packaging script on 2017-04-06
version: '8.x-1.19'
# Information added by Drupal.org packaging script on 2017-09-12
version: '8.x-1.20'
core: '8.x'
project: 'admin_toolbar'
datestamp: 1491487686
datestamp: 1505199847
@@ -11,18 +11,17 @@ use Drupal\Core\Routing\RouteMatchInterface;
* Implements hook_toolbar().
*/
function admin_toolbar_tools_toolbar() {
$items = array();
$items['admin_toolbar_tools'] = array(
$items = [];
$items['admin_toolbar_tools'] = [
'#type' => 'toolbar_item',
'tab' => array(
'tab' => [
'#type' => 'link',
'#attributes' => array(
'class' => array('toolbar-icon', 'toolbar-icon-admin-toolbar-tools-help'),
),
),
'#attached' => array('library' => array('admin_toolbar_tools/toolbar.icon'),
),
);
'#attributes' => [
'class' => ['toolbar-icon', 'toolbar-icon-admin-toolbar-tools-help'],
],
],
'#attached' => ['library' => ['admin_toolbar_tools/toolbar.icon']],
];
return $items;
}
@@ -49,19 +48,19 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
$moduleHandler = \Drupal::moduleHandler();
$entityTypeManager = \Drupal::entityTypeManager();
$routeProvider = \Drupal::service('router.route_provider');
$routes = array();
$routes = [];
foreach ($routeProvider->getAllRoutes() as $route_name => $route) {
$routes[] = $route_name;
}
$entityTypes = $entityTypeManager->getDefinitions();
$content_entities = array();
$content_entities = [];
foreach ($entityTypes as $key => $entityType) {
if ($entityType->getBundleEntityType() && ($entityType->get('field_ui_base_route') != '')) {
$content_entities[$key] = array(
$content_entities[$key] = [
'content_entity' => $key,
'content_entity_bundle' => $entityType->getBundleEntityType(),
);
];
}
}
@@ -75,23 +74,23 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
if (in_array('entity.' . $content_entity_bundle . '.overview_form', $routes)) {
// 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] = array(
'title' => $bundle->label(),
$links[$content_entity_bundle_root] = [
'title' => t($bundle->label()),
'route_name' => 'entity.' . $content_entity_bundle . '.overview_form',
'menu_name' => 'admin',
'parent' => 'entity.' . $content_entity_bundle . '.collection',
'route_parameters' => array($content_entity_bundle => $machine_name),
);
'route_parameters' => [$content_entity_bundle => $machine_name],
];
}
if (in_array('entity.' . $content_entity_bundle . '.edit_form', $routes)) {
$key = 'entity.' . $content_entity_bundle . '.edit_form.' . $machine_name;
$links[$key] = array(
'title' => $bundle->label(),
$links[$key] = [
'title' => t($bundle->label()),
'route_name' => 'entity.' . $content_entity_bundle . '.edit_form',
'menu_name' => 'admin',
'parent' => 'entity.' . $content_entity_bundle . '.collection',
'route_parameters' => array($content_entity_bundle => $machine_name),
);
'route_parameters' => [$content_entity_bundle => $machine_name],
];
if (empty($content_entity_bundle_root)) {
$content_entity_bundle_root = $key;
}
@@ -102,396 +101,413 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
}
if ($moduleHandler->moduleExists('field_ui')) {
if (in_array('entity.' . $content_entity . '.field_ui_fields', $routes)) {
$links['entity.' . $content_entity . '.field_ui_fields' . $machine_name] = array(
$links['entity.' . $content_entity . '.field_ui_fields' . $machine_name] = [
'title' => t('Manage fields'),
'route_name' => 'entity.' . $content_entity . '.field_ui_fields',
'menu_name' => 'admin',
'parent' => $content_entity_bundle_root,
'route_parameters' => array($content_entity_bundle => $machine_name),
'route_parameters' => [$content_entity_bundle => $machine_name],
'weight' => 1,
);
];
}
if (in_array('entity.entity_form_display.' . $content_entity . '.default', $routes)) {
$links['entity.entity_form_display.' . $content_entity . '.default' . $machine_name] = array(
$links['entity.entity_form_display.' . $content_entity . '.default' . $machine_name] = [
'title' => t('Manage form display'),
'route_name' => 'entity.entity_form_display.' . $content_entity . '.default',
'menu_name' => 'admin',
'parent' => $content_entity_bundle_root,
'route_parameters' => array($content_entity_bundle => $machine_name),
'route_parameters' => [$content_entity_bundle => $machine_name],
'weight' => 2,
);
];
}
if (in_array('entity.entity_view_display.' . $content_entity . '.default', $routes)) {
$links['entity.entity_view_display.' . $content_entity . '.default.' . $machine_name] = array(
$links['entity.entity_view_display.' . $content_entity . '.default.' . $machine_name] = [
'title' => t('Manage display'),
'route_name' => 'entity.entity_view_display.' . $content_entity . '.default',
'menu_name' => 'admin',
'parent' => $content_entity_bundle_root,
'route_parameters' => array($content_entity_bundle => $machine_name),
'route_parameters' => [$content_entity_bundle => $machine_name],
'weight' => 3,
);
];
}
}
if ($moduleHandler->moduleExists('devel') && in_array('entity.' . $content_entity_bundle . '.devel_load', $routes)) {
$links['entity.' . $content_entity_bundle . '.devel_load.' . $machine_name] = array(
$links['entity.' . $content_entity_bundle . '.devel_load.' . $machine_name] = [
'title' => t('Devel'),
'route_name' => 'entity.' . $content_entity_bundle . '.devel_load',
'menu_name' => 'admin',
'parent' => $content_entity_bundle_root,
'route_parameters' => array($content_entity_bundle => $machine_name),
'route_parameters' => [$content_entity_bundle => $machine_name],
'weight' => 4,
);
];
}
if (in_array('entity.' . $content_entity_bundle . '.delete_form', $routes)) {
$links['entity.' . $content_entity_bundle . '.delete_form.' . $machine_name] = array(
$links['entity.' . $content_entity_bundle . '.delete_form.' . $machine_name] = [
'title' => t('Delete'),
'route_name' => 'entity.' . $content_entity_bundle . '.delete_form',
'menu_name' => 'admin',
'parent' => $content_entity_bundle_root,
'route_parameters' => array($content_entity_bundle => $machine_name),
'route_parameters' => [$content_entity_bundle => $machine_name],
'weight' => 5,
);
];
}
}
}
// Add user links.
$links['user.admin_create'] = array(
$links['user.admin_create'] = [
'title' => t('Add a new user'),
'route_name' => 'user.admin_create',
'menu_name' => 'admin',
'parent' => 'entity.user.collection',
);
$links['user.admin_permissions'] = array(
];
$links['user.admin_permissions'] = [
'title' => t('Permissions'),
'route_name' => 'user.admin_permissions',
'menu_name' => 'admin',
'parent' => 'entity.user.collection',
);
$links['entity.user_role.collection'] = array(
];
$links['entity.user_role.collection'] = [
'title' => t('Roles'),
'route_name' => 'entity.user_role.collection',
'menu_name' => 'admin',
'parent' => 'entity.user.collection',
);
$links['admin_toolbar_tools.user.logout'] = array(
];
$links['admin_toolbar_tools.user.logout'] = [
'title' => t('Logout'),
'route_name' => 'user.logout',
'parent' => 'admin_toolbar_tools.help',
'weight' => 10,
);
$links['user.role_add'] = array(
];
$links['user.role_add'] = [
'title' => t('Add a new role'),
'route_name' => 'user.role_add',
'menu_name' => 'admin',
'parent' => 'entity.user_role.collection',
'weight' => -5,
);
];
if ($moduleHandler->moduleExists('field_ui')) {
$links['entity.user.field_ui_fields_'] = array(
$links['entity.user.field_ui_fields_'] = [
'title' => t('Manage fields'),
'route_name' => 'entity.user.field_ui_fields',
'menu_name' => 'admin',
'parent' => 'entity.user.admin_form',
);
$links['entity.entity_form_display.user.default_'] = array(
];
$links['entity.entity_form_display.user.default_'] = [
'title' => t('Manage form display'),
'route_name' => 'entity.entity_form_display.user.default',
'menu_name' => 'admin',
'parent' => 'entity.user.admin_form',
);
$links['entity.entity_view_display.user.default_'] = array(
];
$links['entity.entity_view_display.user.default_'] = [
'title' => t('Manage display'),
'route_name' => 'entity.entity_view_display.user.default',
'menu_name' => 'admin',
'parent' => 'entity.user.admin_form',
);
];
}
foreach (user_roles() as $role) {
$links['entity.user_role.edit_form.' . $role->id()] = array(
'title' => $role->label(),
$links['entity.user_role.edit_form.' . $role->id()] = [
'title' => t($role->label()),
'route_name' => 'entity.user_role.edit_form',
'menu_name' => 'admin',
'parent' => 'entity.user_role.collection',
'route_parameters' => array('user_role' => $role->id()),
);
$links['entity.user_role.edit_permissions_form.' . $role->id()] = array(
'route_parameters' => ['user_role' => $role->id()],
];
$links['entity.user_role.edit_permissions_form.' . $role->id()] = [
'title' => t('Edit permissions'),
'route_name' => 'entity.user_role.edit_permissions_form',
'menu_name' => 'admin',
'parent' => 'entity.user_role.edit_form.' . $role->id(),
'route_parameters' => array('user_role' => $role->id()),
);
$links['entity.user_role.delete_form.' . $role->id()] = array(
'route_parameters' => ['user_role' => $role->id()],
];
$links['entity.user_role.delete_form.' . $role->id()] = [
'title' => t('Delete'),
'route_name' => 'entity.user_role.delete_form',
'menu_name' => 'admin',
'parent' => 'entity.user_role.edit_form.' . $role->id(),
'route_parameters' => array('user_role' => $role->id()),
);
'route_parameters' => ['user_role' => $role->id()],
];
if ($moduleHandler->moduleExists('devel')) {
$links['entity.user_role.devel_load.' . $role->id()] = array(
$links['entity.user_role.devel_load.' . $role->id()] = [
'title' => t('Devel'),
'route_name' => 'entity.user_role.devel_load',
'menu_name' => 'admin',
'parent' => 'entity.user_role.edit_form.' . $role->id(),
'route_parameters' => array('user_role' => $role->id()),
);
'route_parameters' => ['user_role' => $role->id()],
];
}
}
if ($moduleHandler->moduleExists('node')) {
$links['node.add_page']['parent'] = 'system.admin_content';
$links['node.type_add'] = array(
$links['admin_toolbar_tools.add_content'] = $links['node.add_page'];
$links['admin_toolbar_tools.add_content']['parent'] = 'system.admin_content';
$links['node.type_add'] = [
'title' => t('Add content type'),
'route_name' => 'node.type_add',
'menu_name' => 'admin',
'parent' => 'entity.node_type.collection',
'weight' => -5,
);
];
// Add node links for each content type.
foreach (\Drupal::entityTypeManager()->getStorage('node_type')->loadMultiple() as $type) {
$links['node.add.' . $type->id()] = array(
$links['node.add.' . $type->id()] = [
'title' => t($type->label()),
'route_name' => 'node.add',
'parent' => 'node.add_page',
'route_parameters' => array('node_type' => $type->id()),
);
'parent' => 'admin_toolbar_tools.add_content',
'route_parameters' => ['node_type' => $type->id()],
];
}
}
if ($moduleHandler->moduleExists('field_ui')) {
$links['field_ui.entity_form_mode_add'] = array(
$links['field_ui.entity_form_mode_add'] = [
'title' => t('Add new form mode'),
'route_name' => 'field_ui.entity_form_mode_add',
'menu_name' => 'admin',
'parent' => 'entity.entity_form_mode.collection',
);
$links['field_ui.entity_view_mode_add'] = array(
];
$links['field_ui.entity_view_mode_add'] = [
'title' => t('Add new view mode'),
'route_name' => 'field_ui.entity_view_mode_add',
'menu_name' => 'admin',
'parent' => 'entity.entity_view_mode.collection',
);
];
}
if ($moduleHandler->moduleExists('taxonomy')) {
$links['entity.taxonomy_vocabulary.add_form'] = array(
$links['entity.taxonomy_vocabulary.add_form'] = [
'title' => t('Add vocabulary'),
'route_name' => 'entity.taxonomy_vocabulary.add_form',
'menu_name' => 'admin',
'parent' => 'entity.taxonomy_vocabulary.collection',
'weight' => -5,
);
];
}
if ($moduleHandler->moduleExists('menu_ui')) {
$links['entity.menu.add_form'] = array(
$links['entity.menu.add_form'] = [
'title' => t('Add menu'),
'route_name' => 'entity.menu.add_form',
'menu_name' => 'admin',
'parent' => 'entity.menu.collection',
'weight' => -50,
);
];
// Adds links to /admin/structure/menu.
foreach (menu_ui_get_menus() as $machine_name => $label) {
$links['entity.menu.edit_form.' . $machine_name] = array(
'title' => $label,
$links['entity.menu.edit_form.' . $machine_name] = [
'title' => t($label),
'route_name' => 'entity.menu.edit_form',
'menu_name' => 'admin',
'parent' => 'entity.menu.collection',
'route_parameters' => array('menu' => $machine_name),
);
$links['entity.menu.delete_form.' . $machine_name] = array(
'route_parameters' => ['menu' => $machine_name],
];
$links['entity.menu.delete_form.' . $machine_name] = [
'title' => t('Delete'),
'route_name' => 'entity.menu.delete_form',
'menu_name' => 'admin',
'parent' => 'entity.menu.edit_form.' . $machine_name,
'route_parameters' => array('menu' => $machine_name),
);
'route_parameters' => ['menu' => $machine_name],
];
if ($moduleHandler->moduleExists('devel')) {
$links['entity.menu.devel_load.' . $machine_name] = array(
$links['entity.menu.devel_load.' . $machine_name] = [
'title' => t('Devel'),
'route_name' => 'entity.menu.devel_load',
'menu_name' => 'admin',
'parent' => 'entity.menu.edit_form.' . $machine_name,
'route_parameters' => array('menu' => $machine_name),
);
'route_parameters' => ['menu' => $machine_name],
];
}
$links['entity.menu.add_link_form.' . $machine_name] = array(
$links['entity.menu.add_link_form.' . $machine_name] = [
'title' => t('Add link'),
'route_name' => 'entity.menu.add_link_form',
'menu_name' => 'admin',
'parent' => 'entity.menu.edit_form.' . $machine_name,
'route_parameters' => array('menu' => $machine_name),
);
'route_parameters' => ['menu' => $machine_name],
];
}
}
// If module block_content is enabled.
if ($moduleHandler->moduleExists('block_content')) {
$links['block_content.add_page'] = array(
$links['block_content.add_page'] = [
'title' => t('Add custom block'),
'route_name' => 'block_content.add_page',
'menu_name' => 'admin',
'parent' => 'block.admin_display',
'weight' => -100,
);
$links['entity.block_content.collection'] = array(
];
$links['entity.block_content.collection'] = [
'title' => t('Custom block library'),
'route_name' => 'entity.block_content.collection',
'menu_name' => 'admin',
'parent' => 'block.admin_display',
);
$links['entity.block_content_type.collection'] = array(
];
$links['entity.block_content_type.collection'] = [
'title' => t('Types'),
'route_name' => 'entity.block_content_type.collection',
'menu_name' => 'admin',
'parent' => 'block.admin_display',
);
];
}
// If module Contact is enabled.
if ($moduleHandler->moduleExists('contact')) {
$links['contact.form_add'] = array(
$links['contact.form_add'] = [
'title' => t('Add contact form'),
'route_name' => 'contact.form_add',
'menu_name' => 'admin',
'parent' => 'entity.contact_form.collection',
'weight' => -5,
);
];
}
// If module Update Manager is enabled.
if ($moduleHandler->moduleExists('update')) {
$links['update.module_update'] = array(
$links['update.module_update'] = [
'title' => t('Update'),
'route_name' => 'update.module_update',
'menu_name' => 'admin',
'parent' => 'system.modules_list',
);
$links['update.module_install'] = array(
];
$links['update.module_install'] = [
'title' => t('Install new module'),
'route_name' => 'update.module_install',
'menu_name' => 'admin',
'parent' => 'system.modules_list',
);
];
}
// If module Devel is enabled.
if ($moduleHandler->moduleExists('devel')) {
$links['admin_development'] = array(
$links['admin_development'] = [
'title' => t('Development'),
'route_name' => 'system.admin_config_development',
'menu_name' => 'admin',
'parent' => 'admin_toolbar_tools.help',
'weight' => '-8',
);
$links['admin_toolbar_tools.devel.admin_settings'] = array(
];
$links['admin_toolbar_tools.devel.admin_settings'] = [
'title' => t('Devel settings'),
'route_name' => 'devel.admin_settings',
'menu_name' => 'admin',
'parent' => 'admin_development',
'weight' => '-1',
);
$links['admin_toolbar_tools.devel.configs_list'] = array(
];
if ($moduleHandler->moduleExists('webprofiler')) {
$links['admin_menu_tools.devel.webprofiler'] = [
'title' => t('Web Profiler settings'),
'route_name' => 'webprofiler.settings',
'menu_name' => 'admin',
'parent' => 'admin_development',
];
}
$links['admin_toolbar_tools.devel.configs_list'] = [
'title' => t('Config editor'),
'route_name' => 'devel.configs_list',
'menu_name' => 'admin',
'parent' => 'admin_development',
);
$links['admin_toolbar_tools.devel.reinstall'] = array(
];
$links['admin_toolbar_tools.devel.reinstall'] = [
'title' => t('Reinstall modules'),
'route_name' => 'devel.reinstall',
'parent' => 'admin_development',
);
$links['admin_toolbar_tools.devel.menu_rebuild'] = array(
];
$links['admin_toolbar_tools.devel.menu_rebuild'] = [
'title' => t('Rebuild menu'),
'route_name' => 'devel.menu_rebuild',
'menu_name' => 'admin',
'parent' => 'admin_development',
);
$links['admin_toolbar_tools.devel.state_system_page'] = array(
];
$links['admin_toolbar_tools.devel.state_system_page'] = [
'title' => t('State editor'),
'route_name' => 'devel.state_system_page',
'menu_name' => 'admin',
'parent' => 'admin_development',
);
$links['admin_toolbar_tools.devel.theme_registry'] = array(
];
$links['admin_toolbar_tools.devel.theme_registry'] = [
'title' => t('Theme registry'),
'route_name' => 'devel.theme_registry',
'menu_name' => 'admin',
'parent' => 'admin_development',
);
$links['admin_toolbar_tools.devel.entity_info_page'] = array(
];
$links['admin_toolbar_tools.devel.entity_info_page'] = [
'title' => t('Entity Info'),
'route_name' => 'devel.entity_info_page',
'menu_name' => 'admin',
'parent' => 'admin_development',
);
$links['admin_toolbar_tools.devel.execute_php'] = array(
];
$links['admin_toolbar_tools.devel.execute_php'] = [
'title' => t('Execute PHP Code'),
'route_name' => 'devel.execute_php',
'menu_name' => 'admin',
'parent' => 'admin_development',
);
$links['admin_toolbar_tools.devel.session'] = array(
];
$links['admin_toolbar_tools.devel.session'] = [
'title' => t('Session viewer'),
'route_name' => 'devel.session',
'menu_name' => 'admin',
'parent' => 'admin_development',
);
$links['admin_toolbar_tools.devel.elements_page'] = array(
];
$links['admin_toolbar_tools.devel.elements_page'] = [
'title' => t('Form API field types'),
'route_name' => 'devel.elements_page',
'menu_name' => 'admin',
'parent' => 'admin_development',
);
];
}
// If module Views Ui enabled.
if ($moduleHandler->moduleExists('views_ui')) {
$links['views_ui.add'] = array(
$links['views_ui.add'] = [
'title' => t('Add new view'),
'route_name' => 'views_ui.add',
'menu_name' => 'admin',
'parent' => 'entity.view.collection',
'weight' => -5,
);
];
}
$links['system.theme_settings_'] = array(
$links['system.theme_settings_'] = [
'title' => t('Settings'),
'route_name' => 'system.theme_settings',
'menu_name' => 'admin',
'parent' => 'system.themes_page',
);
];
if ($moduleHandler->moduleExists('webprofiler')) {
$links['admin_menu_tools.devel.webprofiler'] = [
'title' => t('Webprofiler settings'),
'route_name' => 'webprofiler.settings',
'menu_name' => 'admin',
'parent' => 'admin_development',
];
}
if ($moduleHandler->moduleExists('update')) {
$links['update.theme_install_'] = array(
$links['update.theme_install_'] = [
'title' => t('Install new theme'),
'route_name' => 'update.theme_install',
'menu_name' => 'admin',
'parent' => 'system.themes_page',
);
$links['update.theme_update_'] = array(
];
$links['update.theme_update_'] = [
'title' => t('Update'),
'route_name' => 'update.theme_update',
'menu_name' => 'admin',
'parent' => 'system.themes_page',
);
];
// Lists installed themes.
$installed_themes = admin_toolbar_tools_installed_themes();
foreach ($installed_themes as $key_theme => $label_theme) {
$links['system.theme_settings_theme.' . $key_theme] = array(
$links['system.theme_settings_theme.' . $key_theme] = [
'title' => t($label_theme),
'route_name' => 'system.theme_settings_theme',
'menu_name' => 'admin',
'parent' => 'system.theme_settings_',
'route_parameters' => array(
'route_parameters' => [
'theme' => $key_theme,
),
);
],
];
}
}
}
@@ -503,11 +519,12 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
* An array of friendly theme names, keyed by the machine name.
*/
function admin_toolbar_tools_installed_themes() {
$all_themes = \Drupal::service('theme_handler')->listInfo();
$themes_installed = array();
$themeHandler = \Drupal::service('theme_handler');
$all_themes = $themeHandler->listInfo();
$themes_installed = [];
foreach ($all_themes as $key_theme => $theme) {
if (\Drupal::service('theme_handler')->hasUi($key_theme)) {
$themes_installed[$key_theme] = $theme->getName();
if ($themeHandler->hasUi($key_theme)) {
$themes_installed[$key_theme] = $themeHandler->getName($key_theme);
}
}
@@ -6,6 +6,7 @@ use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\CronInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Component\Datetime\Time;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Core\Menu\ContextualLinkManager;
@@ -31,6 +32,7 @@ class ToolbarController extends ControllerBase {
protected $localTaskLinkManager;
protected $localActionLinkManager;
protected $cacheRender;
protected $time;
/**
* Constructs a CronController object.
@@ -43,13 +45,15 @@ class ToolbarController extends ControllerBase {
ContextualLinkManager $contextualLinkManager,
LocalTaskManager $localTaskLinkManager,
LocalActionManager $localActionLinkManager,
CacheBackendInterface $cacheRender) {
CacheBackendInterface $cacheRender,
Time $time) {
$this->cron = $cron;
$this->menuLinkManager = $menuLinkManager;
$this->contextualLinkManager = $contextualLinkManager;
$this->localTaskLinkManager = $localTaskLinkManager;
$this->localActionLinkManager = $localActionLinkManager;
$this->cacheRender = $cacheRender;
$this->time = $time;
}
/**
@@ -62,7 +66,8 @@ class ToolbarController extends ControllerBase {
$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('cache.render'),
$container->get('datetime.time')
);
}
@@ -93,7 +98,7 @@ class ToolbarController extends ControllerBase {
*/
public function flush_js_css() {
\Drupal::state()
->set('system.css_js_query_string', base_convert(REQUEST_TIME, 10, 36));
->set('system.css_js_query_string', base_convert($this->time->getCurrentTime(), 10, 36));
drupal_set_message($this->t('CSS and JavaScript cache cleared.'));
return new RedirectResponse($this->reload_page());
}
@@ -34,6 +34,7 @@ class AdminToolbarToolsAlterTest extends WebTestBase {
$this->adminUser = $this->drupalCreateUser([
'access toolbar',
'access administration pages',
'administer site configuration',
]);
$this->drupalLogin($this->adminUser);
}
@@ -1,4 +1,7 @@
/*---------------------- menu horizontal hover---- Krout Fethi FrontEnd Developer-----*/
#toolbar-bar {
z-index: 9999;
}
.toolbar-tray-horizontal .menu-item:hover {
background: #fff;
}
@@ -33,20 +36,20 @@
border-top: 1px solid #dddddd;
}
.toolbar-tray-horizontal li.menu-item--expanded:hover ul ul,
.toolbar-tray-horizontal li.menu-item--expanded:hover ul ul ul,
.toolbar-tray-horizontal li.menu-item--expanded:hover ul ul ul ul,
.toolbar-tray-horizontal li.menu-item--expanded:hover ul ul ul ul ul {
.toolbar-tray-horizontal li.menu-item--expanded.hover-intent ul ul,
.toolbar-tray-horizontal li.menu-item--expanded.hover-intent ul ul ul,
.toolbar-tray-horizontal li.menu-item--expanded.hover-intent ul ul ul ul,
.toolbar-tray-horizontal li.menu-item--expanded.hover-intent ul ul ul ul ul {
display: none;
left: -999em; /* LTR */
}
/* Lists nested under hovered list items */
.toolbar-tray-horizontal li.menu-item--expanded:hover ul,
.toolbar-tray-horizontal li li.menu-item--expanded:hover ul,
.toolbar-tray-horizontal li li li.menu-item--expanded:hover ul,
.toolbar-tray-horizontal li li li li.menu-item--expanded:hover ul,
.toolbar-tray-horizontal li li li li li.menu-item--expanded:hover ul {
.toolbar-tray-horizontal li.menu-item--expanded.hover-intent ul,
.toolbar-tray-horizontal li li.menu-item--expanded.hover-intent ul,
.toolbar-tray-horizontal li li li.menu-item--expanded.hover-intent ul,
.toolbar-tray-horizontal li li li li.menu-item--expanded.hover-intent ul,
.toolbar-tray-horizontal li li li li li.menu-item--expanded.hover-intent ul {
display: block;
left: auto; /* LTR */
}
@@ -56,7 +59,7 @@
padding: 12px 15px 12px 12px;
}
.toolbar-tray-horizontal ul li.menu-item--expanded:hover ul {
.toolbar-tray-horizontal ul li.menu-item--expanded.hover-intent ul {
display: block;
position: absolute;
width: 200px;
@@ -74,12 +77,12 @@
background-repeat: no-repeat;
}
.toolbar-tray-horizontal ul li.menu-item--expanded .menu-item:hover ul {
.toolbar-tray-horizontal ul li.menu-item--expanded .menu-item.hover-intent ul {
display: block;
margin: -40px 0 0 197px;
}
.toolbar-tray-horizontal li:hover ul li {
.toolbar-tray-horizontal li.hover-intent ul li {
float: none;
}
@@ -1,5 +1,18 @@
(function($) {
$(document).ready(function() {
(function ($) {
$(document).ready(function () {
$('a.toolbar-icon').removeAttr('title');
$('.toolbar-tray-horizontal li.menu-item--expanded, .toolbar-tray-horizontal ul li.menu-item--expanded .menu-item').hoverIntent({
over: function () {
// At the current depth, we should delete all "hover-intent" classes.
// Other wise we get unwanted behaviour where menu items are expanded while already in hovering other ones.
$(this).parent().find('li').removeClass('hover-intent');
$(this).addClass('hover-intent');
},
out: function () {
$(this).removeClass('hover-intent');
},
timeout: 500
});
});
})(jQuery);
@@ -0,0 +1,158 @@
/*!
* hoverIntent v1.8.1 // 2014.08.11 // jQuery v1.9.1+
* http://briancherne.github.io/jquery-hoverIntent/
*
* You may use hoverIntent under the terms of the MIT license. Basically that
* means you are free to use hoverIntent as long as this header is left intact.
* Copyright 2007, 2014 Brian Cherne
*/
/* hoverIntent is similar to jQuery's built-in "hover" method except that
* instead of firing the handlerIn function immediately, hoverIntent checks
* to see if the user's mouse has slowed down (beneath the sensitivity
* threshold) before firing the event. The handlerOut function is only
* called after a matching handlerIn.
*
* // basic usage ... just like .hover()
* .hoverIntent( handlerIn, handlerOut )
* .hoverIntent( handlerInOut )
*
* // basic usage ... with event delegation!
* .hoverIntent( handlerIn, handlerOut, selector )
* .hoverIntent( handlerInOut, selector )
*
* // using a basic configuration object
* .hoverIntent( config )
*
* @param handlerIn function OR configuration object
* @param handlerOut function OR selector for delegation OR undefined
* @param selector selector OR undefined
* @author Brian Cherne <brian(at)cherne(dot)net>
*/
;(function(factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else if (jQuery && !jQuery.fn.hoverIntent) {
factory(jQuery);
}
})(function($) {
'use strict';
// default configuration values
var _cfg = {
interval: 100,
sensitivity: 6,
timeout: 0
};
// counter used to generate an ID for each instance
var INSTANCE_COUNT = 0;
// current X and Y position of mouse, updated during mousemove tracking (shared across instances)
var cX, cY;
// saves the current pointer position coordinates based on the given mousemove event
var track = function(ev) {
cX = ev.pageX;
cY = ev.pageY;
};
// compares current and previous mouse positions
var compare = function(ev,$el,s,cfg) {
// compare mouse positions to see if pointer has slowed enough to trigger `over` function
if ( Math.sqrt( (s.pX-cX)*(s.pX-cX) + (s.pY-cY)*(s.pY-cY) ) < cfg.sensitivity ) {
$el.off(s.event,track);
delete s.timeoutId;
// set hoverIntent state as active for this element (permits `out` handler to trigger)
s.isActive = true;
// overwrite old mouseenter event coordinates with most recent pointer position
ev.pageX = cX; ev.pageY = cY;
// clear coordinate data from state object
delete s.pX; delete s.pY;
return cfg.over.apply($el[0],[ev]);
} else {
// set previous coordinates for next comparison
s.pX = cX; s.pY = cY;
// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
s.timeoutId = setTimeout( function(){compare(ev, $el, s, cfg);} , cfg.interval );
}
};
// triggers given `out` function at configured `timeout` after a mouseleave and clears state
var delay = function(ev,$el,s,out) {
delete $el.data('hoverIntent')[s.id];
return out.apply($el[0],[ev]);
};
$.fn.hoverIntent = function(handlerIn,handlerOut,selector) {
// instance ID, used as a key to store and retrieve state information on an element
var instanceId = INSTANCE_COUNT++;
// extend the default configuration and parse parameters
var cfg = $.extend({}, _cfg);
if ( $.isPlainObject(handlerIn) ) {
cfg = $.extend(cfg, handlerIn);
if ( !$.isFunction(cfg.out) ) {
cfg.out = cfg.over;
}
} else if ( $.isFunction(handlerOut) ) {
cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } );
} else {
cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } );
}
// A private function for handling mouse 'hovering'
var handleHover = function(e) {
// cloned event to pass to handlers (copy required for event object to be passed in IE)
var ev = $.extend({},e);
// the current target of the mouse event, wrapped in a jQuery object
var $el = $(this);
// read hoverIntent data from element (or initialize if not present)
var hoverIntentData = $el.data('hoverIntent');
if (!hoverIntentData) { $el.data('hoverIntent', (hoverIntentData = {})); }
// read per-instance state from element (or initialize if not present)
var state = hoverIntentData[instanceId];
if (!state) { hoverIntentData[instanceId] = state = { id: instanceId }; }
// state properties:
// id = instance ID, used to clean up data
// timeoutId = timeout ID, reused for tracking mouse position and delaying "out" handler
// isActive = plugin state, true after `over` is called just until `out` is called
// pX, pY = previously-measured pointer coordinates, updated at each polling interval
// event = string representing the namespaced event used for mouse tracking
// clear any existing timeout
if (state.timeoutId) { state.timeoutId = clearTimeout(state.timeoutId); }
// namespaced event used to register and unregister mousemove tracking
var mousemove = state.event = 'mousemove.hoverIntent.hoverIntent'+instanceId;
// handle the event, based on its type
if (e.type === 'mouseenter') {
// do nothing if already active
if (state.isActive) { return; }
// set "previous" X and Y position based on initial entry point
state.pX = ev.pageX; state.pY = ev.pageY;
// update "current" X and Y position based on mousemove
$el.off(mousemove,track).on(mousemove,track);
// start polling interval (self-calling timeout) to compare mouse coordinates over time
state.timeoutId = setTimeout( function(){compare(ev,$el,state,cfg);} , cfg.interval );
} else { // "mouseleave"
// do nothing if not already active
if (!state.isActive) { return; }
// unbind expensive mousemove event
$el.off(mousemove,track);
// if hoverIntent state is true, then call the mouseOut function after the specified delay
state.timeoutId = setTimeout( function(){delay(ev,$el,state,cfg.out);} , cfg.timeout );
}
};
// listen for mouseenter and mouseleave
return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector);
};
});
@@ -7,7 +7,7 @@ Configuration Update Base: A base module providing functionality related to
updating and computing differences between configuration versions. No
user interface; used by other modules such as Features.
Configuration Update Reports (in the config_ui sub-directory of this project):
Adds an updates report and revert functionality to configuration management.
Depends on Configuration Update Base. For more information, see the
README.txt file in the subdirectory.
Configuration Update Reports (in the config_update_ui sub-directory of this
project): Adds an updates report and revert functionality to configuration
management. Depends on Configuration Update Base. For more information, see
the README.txt file in the subdirectory.
@@ -5,8 +5,8 @@ description: 'Provides basic revert and update functionality for other modules'
dependencies:
- drupal:config
# Information added by Drupal.org packaging script on 2017-01-18
version: '8.x-1.3'
# Information added by Drupal.org packaging script on 2017-09-18
version: '8.x-1.4'
core: '8.x'
project: 'config_update'
datestamp: 1484770686
datestamp: 1505755746
@@ -8,9 +8,24 @@
*/
if (!function_exists('drush_print')) {
function drush_print() {}
/**
* Stub for drush_print() function for testing.
*/
function drush_print() {
}
}
if (!function_exists('dt')) {
function dt($text) { return $text; }
/**
* Stub for dt() function for testing.
*/
function dt($text) {
return $text;
}
}
defined('STDERR') or define('STDERR', 25);
@@ -7,8 +7,8 @@ dependencies:
- config_update:config_update
- drupal:config
# Information added by Drupal.org packaging script on 2017-01-18
version: '8.x-1.3'
# Information added by Drupal.org packaging script on 2017-09-18
version: '8.x-1.4'
core: '8.x'
project: 'config_update'
datestamp: 1484770686
datestamp: 1505755746
@@ -26,7 +26,7 @@ function config_update_ui_help($route_name, RouteMatchInterface $route_match) {
case 'config_update_ui.report':
$output = '';
$output .= '<p>' . t('This report shows which default configuration items provided by the current versions of your installed modules, themes, and install profile differ from the active configuration of your site. You can generate the report for all configuration of a certain type, or for a particular installed module, theme, or your install profile (only modules, themes, and install profiles that actually provide configuration are listed).') . '</p>';
$output .= '<p>' . t('This report shows which default configuration items provided by the current versions of your installed modules, themes, and install profile differ from the active configuration of your site. You can generate the report for all configuration of a certain type; for a particular installed module, theme, or your install profile (only modules, themes, and install profiles that actually provide configuration are listed); or for all configuration.') . '</p>';
$output .= '<p>' . t('Some configuration provided by modules has dependencies, and is only added to your system when all the dependencies are satisfied. This is known as <em>optional</em> configuration.') . '</p>';
$output .= '<p>' . t('Differences, including missing and added configuration, can be due to either an updated module or theme providing different configuration from when you installed it, or to changes made by site administrators. This report does not differentiate between these two sources for differences, and note that an install profile can also silently override module/theme configuration. Overrides (such as those in your settings.php file) and translations are not considered when looking at differences.') . '</p>';
return $output;
@@ -3,6 +3,7 @@
namespace Drupal\config_update_ui\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Diff\DiffFormatter;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Extension\ThemeHandlerInterface;
@@ -60,6 +61,13 @@ class ConfigUpdateController extends ControllerBase {
*/
protected $themeHandler;
/**
* The config factory.
*
* @var \Drupal\Core\config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* Constructs a ConfigUpdateController object.
*
@@ -75,8 +83,10 @@ class ConfigUpdateController extends ControllerBase {
* The module handler.
* @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
* The theme handler.
* @param \drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
*/
public function __construct(ConfigDiffInterface $config_diff, ConfigListByProviderInterface $config_list, ConfigRevertInterface $config_update, DiffFormatter $diff_formatter, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler) {
public function __construct(ConfigDiffInterface $config_diff, ConfigListByProviderInterface $config_list, ConfigRevertInterface $config_update, DiffFormatter $diff_formatter, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, ConfigFactoryInterface $config_factory) {
$this->configDiff = $config_diff;
$this->configList = $config_list;
$this->configRevert = $config_update;
@@ -84,6 +94,7 @@ class ConfigUpdateController extends ControllerBase {
$this->diffFormatter->show_header = FALSE;
$this->moduleHandler = $module_handler;
$this->themeHandler = $theme_handler;
$this->configFactory = $config_factory;
}
/**
@@ -96,7 +107,8 @@ class ConfigUpdateController extends ControllerBase {
$container->get('config_update.config_update'),
$container->get('diff.formatter'),
$container->get('module_handler'),
$container->get('theme_handler')
$container->get('theme_handler'),
$container->get('config.factory')
);
}
@@ -238,6 +250,22 @@ class ConfigUpdateController extends ControllerBase {
'#rows' => [],
];
// Full report of all configuration.
$links['report_full'] = [
'title' => $this->t('Everything'),
'url' => Url::fromRoute('config_update_ui.report', ['report_type' => 'type', 'name' => 'system.all']),
];
$build['links']['#rows'][] = [
$this->t('Full report'),
[
'data' => [
'#type' => 'operations',
'#links' => $links,
],
],
];
// Reports by configuration type.
$definitions = $this->configList->listTypes();
$links = [];
foreach ($definitions as $entity_type => $definition) {
@@ -250,10 +278,6 @@ class ConfigUpdateController extends ControllerBase {
uasort($links, [$this, 'sortLinks']);
$links = [
'report_type_all' => [
'title' => $this->t('All types'),
'url' => Url::fromRoute('config_update_ui.report', ['report_type' => 'type', 'name' => 'system.all']),
],
'report_type_system.simple' => [
'title' => $this->t('Simple configuration'),
'url' => Url::fromRoute('config_update_ui.report', ['report_type' => 'type', 'name' => 'system.simple']),
@@ -261,7 +285,7 @@ class ConfigUpdateController extends ControllerBase {
] + $links;
$build['links']['#rows'][] = [
$this->t('Configuration type'),
$this->t('Single configuration type'),
[
'data' => [
'#type' => 'operations',
@@ -271,7 +295,7 @@ class ConfigUpdateController extends ControllerBase {
];
// Make a list of installed modules.
$profile = Settings::get('install_profile');
$profile = $this->getProfileName();
$modules = $this->moduleHandler->getModuleList();
$links = [];
foreach ($modules as $machine_name => $module) {
@@ -285,7 +309,7 @@ class ConfigUpdateController extends ControllerBase {
uasort($links, [$this, 'sortLinks']);
$build['links']['#rows'][] = [
$this->t('Module'),
$this->t('Single module'),
[
'data' => [
'#type' => 'operations',
@@ -308,7 +332,7 @@ class ConfigUpdateController extends ControllerBase {
uasort($links, [$this, 'sortLinks']);
$build['links']['#rows'][] = [
$this->t('Theme'),
$this->t('Single theme'),
[
'data' => [
'#type' => 'operations',
@@ -393,7 +417,7 @@ class ConfigUpdateController extends ControllerBase {
break;
case 'profile':
$profile = Settings::get('install_profile');
$profile = $this->getProfileName();
$label = $this->t('@name profile', ['@name' => $this->moduleHandler->getName($profile)]);
break;
@@ -449,7 +473,8 @@ class ConfigUpdateController extends ControllerBase {
$build['different'] = [
'#caption' => $this->t('Changed configuration items'),
'#empty' => $this->t('None: no active configuration items differ from their current provided versions.'),
] + $this->makeReportTable($different, 'active', ['diff', 'export', 'revert']);
] + $this->makeReportTable($different, 'active',
['diff', 'export', 'revert']);
return $build;
}
@@ -468,13 +493,13 @@ class ConfigUpdateController extends ControllerBase {
* - revert
* - export
* - import
* - delete
* - delete.
*
* @return array
* Render array for the table, not including the #empty and #prefix
* properties.
*/
protected function makeReportTable($names, $storage, $actions) {
protected function makeReportTable(array $names, $storage, array $actions) {
$build = [];
$build['#type'] = 'table';
@@ -544,7 +569,7 @@ class ConfigUpdateController extends ControllerBase {
$provider = $this->configList->getConfigProvider($name);
$provider_name = '';
if (!empty($provider)) {
switch($provider[0]) {
switch ($provider[0]) {
case 'profile':
$provider_name = $this->moduleHandler->getName($provider[1]);
if ($provider_name) {
@@ -574,7 +599,6 @@ class ConfigUpdateController extends ControllerBase {
$provider_name = '';
}
break;
break;
}
}
$row[] = $provider_name;
@@ -627,4 +651,26 @@ class ConfigUpdateController extends ControllerBase {
return ($title1 < $title2) ? -1 : 1;
}
/**
* Returns the name of the install profile.
*
* For backwards compatibility with pre/post 8.3.x, tries to get it from
* either configuration or settings.
*
* @return string
* The name of the install profile.
*/
protected function getProfileName() {
// Code adapted from DrupalKernel::getInstalProfile() in Core.
// In Core 8.3.x or later, read from config.
$profile = $this->configFactory->get('core.extension')->get('profile');
if (!empty($profile)) {
return $profile;
}
else {
// If system_update_8300() has not yet run, use settings.
return Settings::get('install_profile');
}
}
}
@@ -0,0 +1,97 @@
<?php
namespace Drupal\config_update_ui\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Verify config reports, reverts, and diffs with profile overrides.
*
* @group config
*/
class ConfigProfileOverridesTest extends WebTestBase {
/**
* Use the Standard profile, so that there are profile config overrides.
*
* @var string
*/
protected $profile = 'standard';
/**
* Modules to enable.
*
* @var array
*/
public static $modules = [
'config',
'config_update',
'config_update_ui',
];
/**
* The admin user that will be created.
*
* @var object
*/
protected $adminUser;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create user and log in.
$this->adminUser = $this->drupalCreateUser([
'access administration pages',
'administer themes',
'view config updates report',
'synchronize configuration',
'export configuration',
'import configuration',
'revert configuration',
'delete configuration',
]);
$this->drupalLogin($this->adminUser);
}
/**
* Tests that config overrides work as expected.
*/
public function testConfigOverrides() {
// The Standard install profile contains a system.theme.yml file that
// sets up bartik/seven as the default/admin theme. The default config
// from the System module has no admin theme and stark as the default
// theme. So first, run the report on simple configuration and verify
// that system.theme is not shown (it should not be missing, or added,
// or overridden).
$this->drupalGet('admin/config/development/configuration/report/type/system.simple');
$this->assertNoRaw('system.theme');
// Go to the Appearance page and change the theme to whatever is currently
// disabled. Return to the report and verify that system.theme is there,
// since it is now overridden.
$this->drupalGet('admin/appearance');
$this->clickLink('Install and set as default');
$this->drupalGet('admin/config/development/configuration/report/type/system.simple');
$this->assertText('system.theme');
// Look at the differences for system.theme and verify it's against
// the standard profile version, not default version. The line for
// default should show bartik as the source; if it's against the system
// version, the word bartik would not be there.
$this->drupalGet('admin/config/development/configuration/report/diff/system.simple/system.theme');
$this->assertText('bartik');
// Revert and verify that it reverted to the profile version, not the
// system module version.
$this->drupalGet('admin/config/development/configuration/report/revert/system.simple/system.theme');
$this->drupalPostForm(NULL, [], 'Revert');
$this->drupalGet('admin/config/development/configuration/single/export/system.simple/system.theme');
$this->assertText('admin: seven');
$this->assertText('default: bartik');
}
}
@@ -17,12 +17,25 @@ class ConfigUpdateTest extends WebTestBase {
* Use the Search module because it has two included config items in its
* config/install, assuming node and user are also enabled.
*
* @var array.
* @var array
*/
public static $modules = ['config', 'config_update', 'config_update_ui', 'search', 'node', 'user', 'block', 'text', 'field', 'filter'];
public static $modules = [
'config',
'config_update',
'config_update_ui',
'search',
'node',
'user',
'block',
'text',
'field',
'filter',
];
/**
* The admin user that will be created.
*
* @var object
*/
protected $adminUser;
@@ -33,7 +46,17 @@ class ConfigUpdateTest extends WebTestBase {
parent::setUp();
// Create user and log in.
$this->adminUser = $this->drupalCreateUser(['access administration pages', 'administer search', 'view config updates report', 'synchronize configuration', 'export configuration', 'import configuration', 'revert configuration', 'delete configuration', 'administer filters']);
$this->adminUser = $this->drupalCreateUser([
'access administration pages',
'administer search',
'view config updates report',
'synchronize configuration',
'export configuration',
'import configuration',
'revert configuration',
'delete configuration',
'administer filters',
]);
$this->drupalLogin($this->adminUser);
// Make sure local tasks and page title are showing.
@@ -99,7 +122,13 @@ class ConfigUpdateTest extends WebTestBase {
$this->drupalGet('admin/config/development/configuration/report/module/user');
$this->assertReport('User module', [], [], [], $inactive, ['added', 'changed']);
$this->assertDrushReports('module', 'user', [], [], [],
['rdf.mapping.user.user', 'search.page.user_search', 'views.view.user_admin_people', 'views.view.who_s_new', 'views.view.who_s_online' ], ['changed']);
[
'rdf.mapping.user.user',
'search.page.user_search',
'views.view.user_admin_people',
'views.view.who_s_new',
'views.view.who_s_online',
], ['changed']);
// Use the import link to get it back. Do this from the search page
// report to make sure we are importing the right config.
@@ -314,7 +343,7 @@ class ConfigUpdateTest extends WebTestBase {
* @param string[] $skip
* Array of report sections to skip checking.
*/
protected function assertReport($title, $missing, $added, $changed, $inactive, $skip = []) {
protected function assertReport($title, array $missing, array $added, array $changed, array $inactive, array $skip = []) {
$this->assertText('Configuration updates report for ' . $title);
$this->assertText('Generate new report');
@@ -393,7 +422,7 @@ class ConfigUpdateTest extends WebTestBase {
* @param string[] $skip
* Array of report sections to skip checking.
*/
protected function assertDrushReports($type, $name, $missing, $added, $changed, $inactive, $skip = []) {
protected function assertDrushReports($type, $name, array $missing, array $added, array $changed, array $inactive, array $skip = []) {
if (!in_array('missing', $skip)) {
$output = drush_config_update_ui_config_missing_report($type, $name);
$this->assertEqual(count($output), count($missing), 'Drush missing report has correct number of items');
@@ -442,9 +471,10 @@ class ConfigUpdateTest extends WebTestBase {
*/
protected function assertNoReport() {
$this->assertText('Report type');
$this->assertText('Configuration type');
$this->assertText('Module');
$this->assertText('Theme');
$this->assertText('Full report');
$this->assertText('Single configuration type');
$this->assertText('Single module');
$this->assertText('Single theme');
$this->assertText('Installation profile');
$this->assertText('Updates report');
$this->assertNoText('Missing configuration items');
@@ -454,7 +484,6 @@ class ConfigUpdateTest extends WebTestBase {
// Verify that certain report links are shown or not shown. For extensions,
// only extensions that have configuration should be shown.
// Modules.
$this->assertLink('Search');
$this->assertLink('Field');
@@ -469,7 +498,7 @@ class ConfigUpdateTest extends WebTestBase {
$this->assertLink('Testing');
// Configuration types.
$this->assertLink('All types');
$this->assertLink('Everything');
$this->assertLink('Simple configuration');
$this->assertLink('Search page');
}
@@ -14,9 +14,9 @@ interface ConfigDiffInterface {
* have the same keys and values. It is up to the particular implementing
* class to decide what normalizing means.
*
* @param array $source
* @param array|null $source
* Source config.
* @param array $target
* @param array|null $target
* Target config.
*
* @return bool
@@ -32,9 +32,9 @@ interface ConfigDiffInterface {
* differences. It is up to the particular implementing class to decide what
* normalizing means.
*
* @param array $source
* @param array|null $source
* Source config.
* @param array $target
* @param array|null $target
* Target config.
*
* @return \Drupal\Component\Diff\Diff
@@ -43,7 +43,7 @@ class ConfigDiffer implements ConfigDiffInterface {
/**
* Constructs a ConfigDiffer.
*
* @param TranslationInterface $translation
* @param \Drupal\Core\StringTranslation\TranslationInterface $translation
* String translation service.
* @param string[] $ignore
* Config components to ignore.
@@ -52,7 +52,7 @@ class ConfigDiffer implements ConfigDiffInterface {
* @param string $value_prefix
* Prefix to use in diffs for array value.
*/
public function __construct(TranslationInterface $translation, $ignore = ['uuid', '_core'], $hierarchy_prefix = '::', $value_prefix = ' : ') {
public function __construct(TranslationInterface $translation, array $ignore = ['uuid', '_core'], $hierarchy_prefix = '::', $value_prefix = ' : ') {
$this->stringTranslation = $translation;
$this->hierarchyPrefix = $hierarchy_prefix;
$this->valuePrefix = $value_prefix;
@@ -66,7 +66,7 @@ class ConfigDiffer implements ConfigDiffInterface {
* as well as empty array values, and sorts at each level by array key, so
* that config from different storage can be compared meaningfully.
*
* @param array $config
* @param array|null $config
* Configuration array to normalize.
*
* @return array
@@ -109,7 +109,7 @@ class ConfigDiffer implements ConfigDiffInterface {
public function same($source, $target) {
$source = $this->normalize($source);
$target = $this->normalize($target);
return $source == $target;
return $source === $target;
}
/**
@@ -136,15 +136,15 @@ class ConfigDiffer implements ConfigDiffInterface {
* (optional) When called recursively, the prefix to put on each line. Omit
* when initially calling this function.
*
* @return string[] Array of config lines formatted so that a line-by-line
* diff will show the context in each line, and meaningful differences will
* be computed.
* @return string[]
* Array of config lines formatted so that a line-by-line diff will show the
* context in each line, and meaningful differences will be computed.
*
* @see ConfigDiffer::normalize()
* @see ConfigDiffer::$hierarchyPrefix
* @see ConfigDiffer::$valuePrefix
*/
protected function format($config, $prefix = '') {
protected function format(array $config, $prefix = '') {
$lines = [];
foreach ($config as $key => $value) {
@@ -164,7 +164,7 @@ class ConfigLister implements ConfigListInterface {
break;
case 'profile':
$name = Settings::get('install_profile');
$name = $this->getProfileName();
// Intentional fall-through here to the 'module' or 'theme' case.
case 'module':
case 'theme':
@@ -220,4 +220,26 @@ class ConfigLister implements ConfigListInterface {
return array_values($list);
}
/**
* Returns the name of the install profile.
*
* For backwards compatibility with pre/post 8.3.x, tries to get it from
* either configuration or settings.
*
* @return string
* The name of the install profile.
*/
protected function getProfileName() {
// Code adapted from DrupalKernel::getInstalProfile() in Core.
// In Core 8.3.x or later, read from config.
$config = $this->activeConfigStorage->read('core.extension');
if (!empty($config['profile'])) {
return $config['profile'];
}
else {
// If system_update_8300() has not yet run, use settings.
return Settings::get('install_profile');
}
}
}
@@ -7,8 +7,6 @@ use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\Extension\Extension;
/**
* Provides methods related to config listing, including provider calculation.
@@ -88,12 +86,10 @@ class ConfigListerWithProviders extends ConfigLister implements ConfigListByProv
}
// Calculate if it hasn't been set up yet.
// List all of the profile, modules, and themes.
$extensionsToDo = [];
$profile = Settings::get('install_profile');
$profile = $this->getProfileName();
$extensionsToDo[] = ['profile', $profile];
$modules = $this->moduleHandler->getModuleList();
foreach ($modules as $machine_name => $module) {
if ($machine_name != $profile) {
@@ -114,14 +110,14 @@ class ConfigListerWithProviders extends ConfigLister implements ConfigListByProv
'theme' => [],
];
foreach($extensionsToDo as $item) {
foreach ($extensionsToDo as $item) {
$type = $item[0];
$name = $item[1];
$configs = array_merge($this->listProvidedItems($type, $name),
$this->listProvidedItems($type, $name, TRUE));
if (!empty($configs)) {
$this->extensionsWithConfig[$type][$name] = $name;
foreach($configs as $config) {
foreach ($configs as $config) {
$this->providers[$config] = [$type, $name];
}
}
@@ -0,0 +1,308 @@
<?php
namespace Drupal\Tests\config_update\Unit;
use Drupal\config_update\ConfigDiffer;
use Drupal\Tests\UnitTestCase;
/**
* Tests the \Drupal\config_update\ConfigDiffer class.
*
* @group config_update
*
* @coversDefaultClass \Drupal\config_update\ConfigDiffer
*/
class ConfigDifferTest extends UnitTestCase {
/**
* The mock translation object.
*
* @var \Drupal\Core\StringTranslation\TranslationInterface
*/
protected $stringTranslation;
/**
* The config differ to test.
*
* @var \Drupal\config_update\ConfigDiffer
*/
protected $configDiffer;
/**
* {@inheritdoc}
*/
protected function setUp() {
$this->stringTranslation = $this->getMockBuilder('Drupal\Core\StringTranslation\TranslationInterface')->getMock();
$this->stringTranslation
->method('t')
->will($this->returnArgument(0));
$this->configDiffer = new ConfigDiffer($this->stringTranslation);
}
/**
* @covers \Drupal\config_update\ConfigDiffer::same
* @dataProvider sameProvider
*/
public function testSame($a, $b, $expected) {
$this->assertEquals($expected, $this->configDiffer->same($a, $b));
}
/**
* Data provider for self:testSame().
*/
public function sameProvider() {
$base = [
'uuid' => 'bar',
'a' => 'a',
'b' => 0,
'c' => [
'd' => TRUE,
'e' => FALSE,
],
];
return [
[$base, $base, TRUE],
// Add _core, omit uuid. Should match.
[
$base,
[
'_core' => 'foo',
'a' => 'a',
'b' => 0,
'c' => [
'd' => TRUE,
'e' => FALSE,
],
],
TRUE,
],
// Change order. Should match.
[
$base,
[
'a' => 'a',
'uuid' => 'bar',
'b' => 0,
'c' => [
'd' => TRUE,
'e' => FALSE,
],
],
TRUE,
],
// Change order and add _core in deeper level. Should match.
[
$base,
[
'uuid' => 'bar',
'a' => 'a',
'b' => 0,
'c' => [
'e' => FALSE,
'_core' => 'foo',
'd' => TRUE,
],
],
TRUE,
],
// Omit a component. Should not match.
[
$base,
[
'uuid' => 'bar',
'a' => 'a',
'c' => [
'd' => TRUE,
'e' => FALSE,
],
],
FALSE,
],
// Add a component. Should not match.
[
$base,
[
'uuid' => 'bar',
'a' => 'a',
'b' => 0,
'c' => [
'd' => TRUE,
'e' => FALSE,
],
'f' => 'f',
],
FALSE,
],
// 0 should not match a string.
[
$base,
[
'_core' => 'foo',
'uuid' => 'bar',
'a' => 'a',
'b' => 'b',
'c' => [
'd' => TRUE,
'e' => FALSE,
],
],
FALSE,
],
// FALSE should not match a string.
[
$base,
[
'_core' => 'foo',
'uuid' => 'bar',
'a' => 'a',
'b' => 0,
'c' => [
'd' => TRUE,
'e' => 'e',
],
],
FALSE,
],
// TRUE should not match a string.
[
$base,
[
'_core' => 'foo',
'uuid' => 'bar',
'a' => 'a',
'b' => 0,
'c' => [
'd' => 'd',
'e' => FALSE,
],
],
FALSE,
],
];
}
/**
* @covers \Drupal\config_update\ConfigDiffer::diff
*/
public function testDiff() {
$configOne = [
'uuid' => '1234-5678-90',
'id' => 'test.config.id',
'id_to_remove' => 'test.remove.id',
'type' => 'old_type',
'true_value' => TRUE,
'nested_array' => [
'flat_array' => [
'value2',
'value1',
'value3',
],
'custom_key' => 'value',
],
];
$configTwo = [
'uuid' => '09-8765-4321',
'id' => 'test.config.id',
'type' => 'new_type',
'true_value' => FALSE,
'nested_array' => [
'flat_array' => [
'value2',
'value3',
],
'custom_key' => 'value',
'custom_key_2' => 'value2',
],
];
$edits = $this->configDiffer->diff($configOne, $configTwo)->getEdits();
$expectedEdits = [
[
'copy' => [
'orig' => [
'id : test.config.id',
],
'closing' => [
'id : test.config.id',
],
],
],
[
'delete' => [
'orig' => [
'id_to_remove : test.remove.id',
],
'closing' => FALSE,
],
],
[
'copy' => [
'orig' => [
'nested_array',
'nested_array::custom_key : value',
],
'closing' => [
'nested_array',
'nested_array::custom_key : value',
],
],
],
[
'add' => [
'orig' => FALSE,
'closing' => [
'nested_array::custom_key_2 : value2',
],
],
],
[
'copy' => [
'orig' => [
'nested_array::flat_array',
'nested_array::flat_array::0 : value2',
],
'closing' => [
'nested_array::flat_array',
'nested_array::flat_array::0 : value2',
],
],
],
[
'change' => [
'orig' => [
'nested_array::flat_array::1 : value1',
'nested_array::flat_array::2 : value3',
'true_value : 1',
'type : old_type',
],
'closing' => [
'nested_array::flat_array::1 : value3',
'true_value : ',
'type : new_type',
],
],
],
];
$this->assertEquals(count($expectedEdits), count($edits));
/** @var \Drupal\Component\Diff\Engine\DiffOp $diffOp */
foreach ($edits as $index => $diffOp) {
$this->assertEquals($expectedEdits[$index][$diffOp->type]['orig'], $diffOp->orig);
$this->assertEquals($expectedEdits[$index][$diffOp->type]['closing'], $diffOp->closing);
}
}
}