contrib modules updates
This commit is contained in:
@@ -1,3 +1,21 @@
|
|||||||
|
Admin Toolbar 8.x-1.25, 2018-11-22
|
||||||
|
----------------------------------
|
||||||
|
Changes since 8.x-1.24:
|
||||||
|
|
||||||
|
- #3012102 by tikaszvince, Jody Lynn, adriancid, grahl, jigarius: Provider
|
||||||
|
property missing on link definition.
|
||||||
|
- #3010451 by epowelljr, adriancid: Improve the admin_toolbar module
|
||||||
|
description.
|
||||||
|
- #2958415 by adriancid, romainj, Prashant.c, harshita29: Replace usages of the
|
||||||
|
deprecated drupal_set_message() function.
|
||||||
|
- #2996485 by idebr, adriancid: Remove unused function
|
||||||
|
admin_toolbar_tools_get_links().
|
||||||
|
- #2989281 by JKerschner, adriancid: Consistently use $entityTypeManager.
|
||||||
|
- #2985106 by Eli-T, adriancid, eme: Add ability to hide Drupal.org links
|
||||||
|
exposed by admin_toolbar_tools from certain users.
|
||||||
|
- #2938884 by Spurlos, bdanin, romainj, purdy_nc, adriancid: A non-existent
|
||||||
|
route breaks the site.
|
||||||
|
|
||||||
Admin Toolbar 8.x-1.24, 2018-05-28
|
Admin Toolbar 8.x-1.24, 2018-05-28
|
||||||
----------------------------------
|
----------------------------------
|
||||||
Changes since 8.x-1.23:
|
Changes since 8.x-1.23:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: Admin Toolbar
|
name: Admin Toolbar
|
||||||
description: Provides a drop-down menu interface to the site Toolbar.
|
description: Provides an improved drop-down menu interface to the site Toolbar.
|
||||||
package: Administration
|
package: Administration
|
||||||
|
|
||||||
type: module
|
type: module
|
||||||
@@ -8,8 +8,8 @@ type: module
|
|||||||
dependencies:
|
dependencies:
|
||||||
- drupal:toolbar
|
- drupal:toolbar
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-05-28
|
# Information added by Drupal.org packaging script on 2019-02-03
|
||||||
version: '8.x-1.24'
|
version: '8.x-1.26'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'admin_toolbar'
|
project: 'admin_toolbar'
|
||||||
datestamp: 1527522484
|
datestamp: 1549218484
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Install, update and uninstall functions for the Admin Toolbar module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebuild routes to mitigate issue 2938884.
|
||||||
|
*
|
||||||
|
* @see https://www.drupal.org/project/admin_toolbar/issues/2938884
|
||||||
|
*/
|
||||||
|
function admin_toolbar_update_8001() {
|
||||||
|
// Rebuilding the route cache.
|
||||||
|
\Drupal::service("router.builder")->rebuild();
|
||||||
|
}
|
||||||
+3
-3
@@ -8,8 +8,8 @@ type: module
|
|||||||
dependencies:
|
dependencies:
|
||||||
- admin_toolbar:admin_toolbar
|
- admin_toolbar:admin_toolbar
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-05-28
|
# Information added by Drupal.org packaging script on 2019-02-03
|
||||||
version: '8.x-1.24'
|
version: '8.x-1.26'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'admin_toolbar'
|
project: 'admin_toolbar'
|
||||||
datestamp: 1527522484
|
datestamp: 1549218484
|
||||||
|
|||||||
+4
-4
@@ -7,10 +7,10 @@ type: module
|
|||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
- admin_toolbar:admin_toolbar
|
- admin_toolbar:admin_toolbar
|
||||||
- drupal:system (>=8.3)
|
- drupal:system (>=8.5)
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-05-28
|
# Information added by Drupal.org packaging script on 2019-02-03
|
||||||
version: '8.x-1.24'
|
version: '8.x-1.26'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'admin_toolbar'
|
project: 'admin_toolbar'
|
||||||
datestamp: 1527522484
|
datestamp: 1549218484
|
||||||
|
|||||||
-21
@@ -74,24 +74,3 @@ admin_toolbar_tools.flush_rendercache:
|
|||||||
route_name: admin_toolbar_tools.flush_rendercache
|
route_name: admin_toolbar_tools.flush_rendercache
|
||||||
parent: admin_toolbar_tools.flush
|
parent: admin_toolbar_tools.flush
|
||||||
menu_name: admin
|
menu_name: admin
|
||||||
|
|
||||||
admin_toolbar_tools.drupalorg:
|
|
||||||
title: 'Drupal.org'
|
|
||||||
weight: -5
|
|
||||||
url: https://www.drupal.org
|
|
||||||
parent: admin_toolbar_tools.help
|
|
||||||
menu_name: admin
|
|
||||||
|
|
||||||
admin_toolbar_tools.listchanges:
|
|
||||||
title: 'Change records for Drupal core'
|
|
||||||
weight: -6
|
|
||||||
url: https://www.drupal.org/list-changes
|
|
||||||
parent: admin_toolbar_tools.drupalorg
|
|
||||||
menu_name: admin
|
|
||||||
|
|
||||||
admin_toolbar_tools.doc:
|
|
||||||
title: 'D8 API documentation'
|
|
||||||
weight: -5
|
|
||||||
url: https://api.drupal.org/api/drupal/8
|
|
||||||
parent: admin_toolbar_tools.drupalorg
|
|
||||||
menu_name: admin
|
|
||||||
|
|||||||
+108
-38
@@ -48,13 +48,26 @@ function admin_toolbar_tools_help($route_name, RouteMatchInterface $route_match)
|
|||||||
* Implements hook_menu_links_discovered_alter().
|
* Implements hook_menu_links_discovered_alter().
|
||||||
*/
|
*/
|
||||||
function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
||||||
|
$languageManager = \Drupal::languageManager();
|
||||||
|
$config_override_language = $languageManager->getConfigOverrideLanguage();
|
||||||
|
$languageManager->setConfigOverrideLanguage($languageManager->getLanguage('en'));
|
||||||
|
|
||||||
$moduleHandler = \Drupal::moduleHandler();
|
$moduleHandler = \Drupal::moduleHandler();
|
||||||
$entityTypeManager = \Drupal::entityTypeManager();
|
$entityTypeManager = \Drupal::entityTypeManager();
|
||||||
$routeProvider = \Drupal::service('router.route_provider');
|
$routeProvider = \Drupal::service('router.route_provider');
|
||||||
$routes = [];
|
|
||||||
foreach ($routeProvider->getAllRoutes() as $route_name => $route) {
|
/**
|
||||||
$routes[] = $route_name;
|
* Determine if a route exists by name.
|
||||||
}
|
*
|
||||||
|
* @param $routeName
|
||||||
|
* The name of the route to check.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* Whether a route with that route name exists.
|
||||||
|
*/
|
||||||
|
$routeExists = function ($routeName) use ($routeProvider) {
|
||||||
|
return (count($routeProvider->getRoutesByNames([$routeName])) === 1);
|
||||||
|
};
|
||||||
|
|
||||||
$entityTypes = $entityTypeManager->getDefinitions();
|
$entityTypes = $entityTypeManager->getDefinitions();
|
||||||
$content_entities = [];
|
$content_entities = [];
|
||||||
@@ -71,14 +84,16 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('views')) {
|
if ($moduleHandler->moduleExists('views')) {
|
||||||
$links['admin_toolbar_tools.flush_views'] = [
|
$links['admin_toolbar_tools.flush_views'] = [
|
||||||
'title' => t('Flush views cache'),
|
'title' => t('Flush views cache'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'admin_toolbar_tools.flush_views',
|
'route_name' => 'admin_toolbar_tools.flush_views',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_toolbar_tools.flush',
|
'parent' => 'admin_toolbar_tools.flush',
|
||||||
];
|
];
|
||||||
// Adding a menu link to Files.
|
// Adding a menu link to Files.
|
||||||
if ($moduleHandler->moduleExists('file') && in_array('view.files.page_1', $routes)) {
|
if ($moduleHandler->moduleExists('file') && $routeExists('view.files.page_1')) {
|
||||||
$links['admin_toolbar_tools.view.files'] = [
|
$links['admin_toolbar_tools.view.files'] = [
|
||||||
'title' => t('Files'),
|
'title' => t('Files'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'view.files.page_1',
|
'route_name' => 'view.files.page_1',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'system.admin_content',
|
'parent' => 'system.admin_content',
|
||||||
@@ -93,21 +108,23 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
foreach ($entityTypeManager->getStorage($content_entity_bundle)->loadMultiple() as $machine_name => $bundle) {
|
foreach ($entityTypeManager->getStorage($content_entity_bundle)->loadMultiple() as $machine_name => $bundle) {
|
||||||
// Normally, the edit form for the bundle would be its root link.
|
// Normally, the edit form for the bundle would be its root link.
|
||||||
$content_entity_bundle_root = NULL;
|
$content_entity_bundle_root = NULL;
|
||||||
if (in_array('entity.' . $content_entity_bundle . '.overview_form', $routes)) {
|
if ($routeExists('entity.' . $content_entity_bundle . '.overview_form')) {
|
||||||
// Some bundles have an overview/list form that make a better root link.
|
// 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;
|
$content_entity_bundle_root = 'entity.' . $content_entity_bundle . '.overview_form.' . $machine_name;
|
||||||
$links[$content_entity_bundle_root] = [
|
$links[$content_entity_bundle_root] = [
|
||||||
'title' => t($bundle->label()),
|
'title' => t($bundle->label()),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.' . $content_entity_bundle . '.overview_form',
|
'route_name' => 'entity.' . $content_entity_bundle . '.overview_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.' . $content_entity_bundle . '.collection',
|
'parent' => 'entity.' . $content_entity_bundle . '.collection',
|
||||||
'route_parameters' => [$content_entity_bundle => $machine_name],
|
'route_parameters' => [$content_entity_bundle => $machine_name],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
if (in_array('entity.' . $content_entity_bundle . '.edit_form', $routes)) {
|
if ($routeExists('entity.' . $content_entity_bundle . '.edit_form')) {
|
||||||
$key = 'entity.' . $content_entity_bundle . '.edit_form.' . $machine_name;
|
$key = 'entity.' . $content_entity_bundle . '.edit_form.' . $machine_name;
|
||||||
$links[$key] = [
|
$links[$key] = [
|
||||||
'title' => t($bundle->label()),
|
'title' => t($bundle->label()),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.' . $content_entity_bundle . '.edit_form',
|
'route_name' => 'entity.' . $content_entity_bundle . '.edit_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.' . $content_entity_bundle . '.collection',
|
'parent' => 'entity.' . $content_entity_bundle . '.collection',
|
||||||
@@ -122,9 +139,10 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($moduleHandler->moduleExists('field_ui')) {
|
if ($moduleHandler->moduleExists('field_ui')) {
|
||||||
if (in_array('entity.' . $content_entity . '.field_ui_fields', $routes)) {
|
if ($routeExists('entity.' . $content_entity . '.field_ui_fields')) {
|
||||||
$links['entity.' . $content_entity . '.field_ui_fields' . $machine_name] = [
|
$links['entity.' . $content_entity . '.field_ui_fields' . $machine_name] = [
|
||||||
'title' => t('Manage fields'),
|
'title' => t('Manage fields'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.' . $content_entity . '.field_ui_fields',
|
'route_name' => 'entity.' . $content_entity . '.field_ui_fields',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => $content_entity_bundle_root,
|
'parent' => $content_entity_bundle_root,
|
||||||
@@ -132,9 +150,10 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
'weight' => 1,
|
'weight' => 1,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
if (in_array('entity.entity_form_display.' . $content_entity . '.default', $routes)) {
|
if ($routeExists('entity.entity_form_display.' . $content_entity . '.default')) {
|
||||||
$links['entity.entity_form_display.' . $content_entity . '.default' . $machine_name] = [
|
$links['entity.entity_form_display.' . $content_entity . '.default' . $machine_name] = [
|
||||||
'title' => t('Manage form display'),
|
'title' => t('Manage form display'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.entity_form_display.' . $content_entity . '.default',
|
'route_name' => 'entity.entity_form_display.' . $content_entity . '.default',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => $content_entity_bundle_root,
|
'parent' => $content_entity_bundle_root,
|
||||||
@@ -142,9 +161,10 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
'weight' => 2,
|
'weight' => 2,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
if (in_array('entity.entity_view_display.' . $content_entity . '.default', $routes)) {
|
if ($routeExists('entity.entity_view_display.' . $content_entity . '.default')) {
|
||||||
$links['entity.entity_view_display.' . $content_entity . '.default.' . $machine_name] = [
|
$links['entity.entity_view_display.' . $content_entity . '.default.' . $machine_name] = [
|
||||||
'title' => t('Manage display'),
|
'title' => t('Manage display'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.entity_view_display.' . $content_entity . '.default',
|
'route_name' => 'entity.entity_view_display.' . $content_entity . '.default',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => $content_entity_bundle_root,
|
'parent' => $content_entity_bundle_root,
|
||||||
@@ -153,9 +173,10 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($moduleHandler->moduleExists('devel') && in_array('entity.' . $content_entity_bundle . '.devel_load', $routes)) {
|
if ($moduleHandler->moduleExists('devel') && $routeExists('entity.' . $content_entity_bundle . '.devel_load')) {
|
||||||
$links['entity.' . $content_entity_bundle . '.devel_load.' . $machine_name] = [
|
$links['entity.' . $content_entity_bundle . '.devel_load.' . $machine_name] = [
|
||||||
'title' => t('Devel'),
|
'title' => t('Devel'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.' . $content_entity_bundle . '.devel_load',
|
'route_name' => 'entity.' . $content_entity_bundle . '.devel_load',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => $content_entity_bundle_root,
|
'parent' => $content_entity_bundle_root,
|
||||||
@@ -163,9 +184,10 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
'weight' => 4,
|
'weight' => 4,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
if (in_array('entity.' . $content_entity_bundle . '.delete_form', $routes)) {
|
if ($routeExists('entity.' . $content_entity_bundle . '.delete_form')) {
|
||||||
$links['entity.' . $content_entity_bundle . '.delete_form.' . $machine_name] = [
|
$links['entity.' . $content_entity_bundle . '.delete_form.' . $machine_name] = [
|
||||||
'title' => t('Delete'),
|
'title' => t('Delete'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.' . $content_entity_bundle . '.delete_form',
|
'route_name' => 'entity.' . $content_entity_bundle . '.delete_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => $content_entity_bundle_root,
|
'parent' => $content_entity_bundle_root,
|
||||||
@@ -179,30 +201,35 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
// Add user links.
|
// Add user links.
|
||||||
$links['user.admin_create'] = [
|
$links['user.admin_create'] = [
|
||||||
'title' => t('Add a new user'),
|
'title' => t('Add a new user'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'user.admin_create',
|
'route_name' => 'user.admin_create',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.user.collection',
|
'parent' => 'entity.user.collection',
|
||||||
];
|
];
|
||||||
$links['user.admin_permissions'] = [
|
$links['user.admin_permissions'] = [
|
||||||
'title' => t('Permissions'),
|
'title' => t('Permissions'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'user.admin_permissions',
|
'route_name' => 'user.admin_permissions',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.user.collection',
|
'parent' => 'entity.user.collection',
|
||||||
];
|
];
|
||||||
$links['entity.user_role.collection'] = [
|
$links['entity.user_role.collection'] = [
|
||||||
'title' => t('Roles'),
|
'title' => t('Roles'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.user_role.collection',
|
'route_name' => 'entity.user_role.collection',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.user.collection',
|
'parent' => 'entity.user.collection',
|
||||||
];
|
];
|
||||||
$links['admin_toolbar_tools.user.logout'] = [
|
$links['admin_toolbar_tools.user.logout'] = [
|
||||||
'title' => t('Logout'),
|
'title' => t('Logout'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'user.logout',
|
'route_name' => 'user.logout',
|
||||||
'parent' => 'admin_toolbar_tools.help',
|
'parent' => 'admin_toolbar_tools.help',
|
||||||
'weight' => 10,
|
'weight' => 10,
|
||||||
];
|
];
|
||||||
$links['user.role_add'] = [
|
$links['user.role_add'] = [
|
||||||
'title' => t('Add a new role'),
|
'title' => t('Add a new role'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'user.role_add',
|
'route_name' => 'user.role_add',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.user_role.collection',
|
'parent' => 'entity.user_role.collection',
|
||||||
@@ -211,18 +238,21 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('field_ui')) {
|
if ($moduleHandler->moduleExists('field_ui')) {
|
||||||
$links['entity.user.field_ui_fields_'] = [
|
$links['entity.user.field_ui_fields_'] = [
|
||||||
'title' => t('Manage fields'),
|
'title' => t('Manage fields'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.user.field_ui_fields',
|
'route_name' => 'entity.user.field_ui_fields',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.user.admin_form',
|
'parent' => 'entity.user.admin_form',
|
||||||
];
|
];
|
||||||
$links['entity.entity_form_display.user.default_'] = [
|
$links['entity.entity_form_display.user.default_'] = [
|
||||||
'title' => t('Manage form display'),
|
'title' => t('Manage form display'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.entity_form_display.user.default',
|
'route_name' => 'entity.entity_form_display.user.default',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.user.admin_form',
|
'parent' => 'entity.user.admin_form',
|
||||||
];
|
];
|
||||||
$links['entity.entity_view_display.user.default_'] = [
|
$links['entity.entity_view_display.user.default_'] = [
|
||||||
'title' => t('Manage display'),
|
'title' => t('Manage display'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.entity_view_display.user.default',
|
'route_name' => 'entity.entity_view_display.user.default',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.user.admin_form',
|
'parent' => 'entity.user.admin_form',
|
||||||
@@ -231,6 +261,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
foreach (user_roles() as $role) {
|
foreach (user_roles() as $role) {
|
||||||
$links['entity.user_role.edit_form.' . $role->id()] = [
|
$links['entity.user_role.edit_form.' . $role->id()] = [
|
||||||
'title' => t($role->label()),
|
'title' => t($role->label()),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.user_role.edit_form',
|
'route_name' => 'entity.user_role.edit_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.user_role.collection',
|
'parent' => 'entity.user_role.collection',
|
||||||
@@ -238,6 +269,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
];
|
];
|
||||||
$links['entity.user_role.edit_permissions_form.' . $role->id()] = [
|
$links['entity.user_role.edit_permissions_form.' . $role->id()] = [
|
||||||
'title' => t('Edit permissions'),
|
'title' => t('Edit permissions'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.user_role.edit_permissions_form',
|
'route_name' => 'entity.user_role.edit_permissions_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.user_role.edit_form.' . $role->id(),
|
'parent' => 'entity.user_role.edit_form.' . $role->id(),
|
||||||
@@ -245,6 +277,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
];
|
];
|
||||||
$links['entity.user_role.delete_form.' . $role->id()] = [
|
$links['entity.user_role.delete_form.' . $role->id()] = [
|
||||||
'title' => t('Delete'),
|
'title' => t('Delete'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.user_role.delete_form',
|
'route_name' => 'entity.user_role.delete_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.user_role.edit_form.' . $role->id(),
|
'parent' => 'entity.user_role.edit_form.' . $role->id(),
|
||||||
@@ -253,6 +286,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('devel')) {
|
if ($moduleHandler->moduleExists('devel')) {
|
||||||
$links['entity.user_role.devel_load.' . $role->id()] = [
|
$links['entity.user_role.devel_load.' . $role->id()] = [
|
||||||
'title' => t('Devel'),
|
'title' => t('Devel'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.user_role.devel_load',
|
'route_name' => 'entity.user_role.devel_load',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.user_role.edit_form.' . $role->id(),
|
'parent' => 'entity.user_role.edit_form.' . $role->id(),
|
||||||
@@ -266,6 +300,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
$links['admin_toolbar_tools.add_content']['parent'] = 'system.admin_content';
|
$links['admin_toolbar_tools.add_content']['parent'] = 'system.admin_content';
|
||||||
$links['node.type_add'] = [
|
$links['node.type_add'] = [
|
||||||
'title' => t('Add content type'),
|
'title' => t('Add content type'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'node.type_add',
|
'route_name' => 'node.type_add',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.node_type.collection',
|
'parent' => 'entity.node_type.collection',
|
||||||
@@ -275,6 +310,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
foreach ($entityTypeManager->getStorage('node_type')->loadMultiple() as $type) {
|
foreach ($entityTypeManager->getStorage('node_type')->loadMultiple() as $type) {
|
||||||
$links['node.add.' . $type->id()] = [
|
$links['node.add.' . $type->id()] = [
|
||||||
'title' => t($type->label()),
|
'title' => t($type->label()),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'node.add',
|
'route_name' => 'node.add',
|
||||||
'parent' => 'admin_toolbar_tools.add_content',
|
'parent' => 'admin_toolbar_tools.add_content',
|
||||||
'route_parameters' => ['node_type' => $type->id()],
|
'route_parameters' => ['node_type' => $type->id()],
|
||||||
@@ -285,12 +321,14 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('field_ui')) {
|
if ($moduleHandler->moduleExists('field_ui')) {
|
||||||
$links['field_ui.entity_form_mode_add'] = [
|
$links['field_ui.entity_form_mode_add'] = [
|
||||||
'title' => t('Add new form mode'),
|
'title' => t('Add new form mode'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'field_ui.entity_form_mode_add',
|
'route_name' => 'field_ui.entity_form_mode_add',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.entity_form_mode.collection',
|
'parent' => 'entity.entity_form_mode.collection',
|
||||||
];
|
];
|
||||||
$links['field_ui.entity_view_mode_add'] = [
|
$links['field_ui.entity_view_mode_add'] = [
|
||||||
'title' => t('Add new view mode'),
|
'title' => t('Add new view mode'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'field_ui.entity_view_mode_add',
|
'route_name' => 'field_ui.entity_view_mode_add',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.entity_view_mode.collection',
|
'parent' => 'entity.entity_view_mode.collection',
|
||||||
@@ -300,6 +338,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('taxonomy')) {
|
if ($moduleHandler->moduleExists('taxonomy')) {
|
||||||
$links['entity.taxonomy_vocabulary.add_form'] = [
|
$links['entity.taxonomy_vocabulary.add_form'] = [
|
||||||
'title' => t('Add vocabulary'),
|
'title' => t('Add vocabulary'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.taxonomy_vocabulary.add_form',
|
'route_name' => 'entity.taxonomy_vocabulary.add_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.taxonomy_vocabulary.collection',
|
'parent' => 'entity.taxonomy_vocabulary.collection',
|
||||||
@@ -310,6 +349,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('menu_ui')) {
|
if ($moduleHandler->moduleExists('menu_ui')) {
|
||||||
$links['entity.menu.add_form'] = [
|
$links['entity.menu.add_form'] = [
|
||||||
'title' => t('Add menu'),
|
'title' => t('Add menu'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.menu.add_form',
|
'route_name' => 'entity.menu.add_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.menu.collection',
|
'parent' => 'entity.menu.collection',
|
||||||
@@ -319,6 +359,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
foreach (menu_ui_get_menus() as $machine_name => $label) {
|
foreach (menu_ui_get_menus() as $machine_name => $label) {
|
||||||
$links['entity.menu.edit_form.' . $machine_name] = [
|
$links['entity.menu.edit_form.' . $machine_name] = [
|
||||||
'title' => t($label),
|
'title' => t($label),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.menu.edit_form',
|
'route_name' => 'entity.menu.edit_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.menu.collection',
|
'parent' => 'entity.menu.collection',
|
||||||
@@ -326,14 +367,16 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
];
|
];
|
||||||
$links['entity.menu.delete_form.' . $machine_name] = [
|
$links['entity.menu.delete_form.' . $machine_name] = [
|
||||||
'title' => t('Delete'),
|
'title' => t('Delete'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.menu.delete_form',
|
'route_name' => 'entity.menu.delete_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.menu.edit_form.' . $machine_name,
|
'parent' => 'entity.menu.edit_form.' . $machine_name,
|
||||||
'route_parameters' => ['menu' => $machine_name],
|
'route_parameters' => ['menu' => $machine_name],
|
||||||
];
|
];
|
||||||
if ($moduleHandler->moduleExists('devel')) {
|
if ($moduleHandler->moduleExists('devel') && $routeExists('entity.menu.devel_load')) {
|
||||||
$links['entity.menu.devel_load.' . $machine_name] = [
|
$links['entity.menu.devel_load.' . $machine_name] = [
|
||||||
'title' => t('Devel'),
|
'title' => t('Devel'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.menu.devel_load',
|
'route_name' => 'entity.menu.devel_load',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.menu.edit_form.' . $machine_name,
|
'parent' => 'entity.menu.edit_form.' . $machine_name,
|
||||||
@@ -342,6 +385,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
}
|
}
|
||||||
$links['entity.menu.add_link_form.' . $machine_name] = [
|
$links['entity.menu.add_link_form.' . $machine_name] = [
|
||||||
'title' => t('Add link'),
|
'title' => t('Add link'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.menu.add_link_form',
|
'route_name' => 'entity.menu.add_link_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.menu.edit_form.' . $machine_name,
|
'parent' => 'entity.menu.edit_form.' . $machine_name,
|
||||||
@@ -354,6 +398,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('block_content')) {
|
if ($moduleHandler->moduleExists('block_content')) {
|
||||||
$links['block_content.add_page'] = [
|
$links['block_content.add_page'] = [
|
||||||
'title' => t('Add custom block'),
|
'title' => t('Add custom block'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'block_content.add_page',
|
'route_name' => 'block_content.add_page',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'block.admin_display',
|
'parent' => 'block.admin_display',
|
||||||
@@ -361,12 +406,14 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
];
|
];
|
||||||
$links['entity.block_content.collection'] = [
|
$links['entity.block_content.collection'] = [
|
||||||
'title' => t('Custom block library'),
|
'title' => t('Custom block library'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.block_content.collection',
|
'route_name' => 'entity.block_content.collection',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'block.admin_display',
|
'parent' => 'block.admin_display',
|
||||||
];
|
];
|
||||||
$links['entity.block_content_type.collection'] = [
|
$links['entity.block_content_type.collection'] = [
|
||||||
'title' => t('Types'),
|
'title' => t('Types'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.block_content_type.collection',
|
'route_name' => 'entity.block_content_type.collection',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'block.admin_display',
|
'parent' => 'block.admin_display',
|
||||||
@@ -377,6 +424,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('contact')) {
|
if ($moduleHandler->moduleExists('contact')) {
|
||||||
$links['contact.form_add'] = [
|
$links['contact.form_add'] = [
|
||||||
'title' => t('Add contact form'),
|
'title' => t('Add contact form'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'contact.form_add',
|
'route_name' => 'contact.form_add',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.contact_form.collection',
|
'parent' => 'entity.contact_form.collection',
|
||||||
@@ -388,12 +436,14 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('update')) {
|
if ($moduleHandler->moduleExists('update')) {
|
||||||
$links['update.module_update'] = [
|
$links['update.module_update'] = [
|
||||||
'title' => t('Update'),
|
'title' => t('Update'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'update.module_update',
|
'route_name' => 'update.module_update',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'system.modules_list',
|
'parent' => 'system.modules_list',
|
||||||
];
|
];
|
||||||
$links['update.module_install'] = [
|
$links['update.module_install'] = [
|
||||||
'title' => t('Install new module'),
|
'title' => t('Install new module'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'update.module_install',
|
'route_name' => 'update.module_install',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'system.modules_list',
|
'parent' => 'system.modules_list',
|
||||||
@@ -404,6 +454,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('devel')) {
|
if ($moduleHandler->moduleExists('devel')) {
|
||||||
$links['admin_development'] = [
|
$links['admin_development'] = [
|
||||||
'title' => t('Development'),
|
'title' => t('Development'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'system.admin_config_development',
|
'route_name' => 'system.admin_config_development',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_toolbar_tools.help',
|
'parent' => 'admin_toolbar_tools.help',
|
||||||
@@ -411,6 +462,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
];
|
];
|
||||||
$links['admin_toolbar_tools.devel.admin_settings'] = [
|
$links['admin_toolbar_tools.devel.admin_settings'] = [
|
||||||
'title' => t('Devel settings'),
|
'title' => t('Devel settings'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'devel.admin_settings',
|
'route_name' => 'devel.admin_settings',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_development',
|
'parent' => 'admin_development',
|
||||||
@@ -419,6 +471,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('webprofiler')) {
|
if ($moduleHandler->moduleExists('webprofiler')) {
|
||||||
$links['admin_toolbar_tools.devel.webprofiler'] = [
|
$links['admin_toolbar_tools.devel.webprofiler'] = [
|
||||||
'title' => t('Web Profiler settings'),
|
'title' => t('Web Profiler settings'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'webprofiler.settings',
|
'route_name' => 'webprofiler.settings',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_development',
|
'parent' => 'admin_development',
|
||||||
@@ -426,53 +479,55 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
}
|
}
|
||||||
$links['admin_toolbar_tools.devel.configs_list'] = [
|
$links['admin_toolbar_tools.devel.configs_list'] = [
|
||||||
'title' => t('Config editor'),
|
'title' => t('Config editor'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'devel.configs_list',
|
'route_name' => 'devel.configs_list',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_development',
|
'parent' => 'admin_development',
|
||||||
];
|
];
|
||||||
$links['admin_toolbar_tools.devel.reinstall'] = [
|
$links['admin_toolbar_tools.devel.reinstall'] = [
|
||||||
'title' => t('Reinstall modules'),
|
'title' => t('Reinstall modules'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'devel.reinstall',
|
'route_name' => 'devel.reinstall',
|
||||||
'parent' => 'admin_development',
|
'parent' => 'admin_development',
|
||||||
];
|
];
|
||||||
$links['admin_toolbar_tools.devel.menu_rebuild'] = [
|
$links['admin_toolbar_tools.devel.menu_rebuild'] = [
|
||||||
'title' => t('Rebuild menu'),
|
'title' => t('Rebuild menu'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'devel.menu_rebuild',
|
'route_name' => 'devel.menu_rebuild',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_development',
|
'parent' => 'admin_development',
|
||||||
];
|
];
|
||||||
$links['admin_toolbar_tools.devel.state_system_page'] = [
|
$links['admin_toolbar_tools.devel.state_system_page'] = [
|
||||||
'title' => t('State editor'),
|
'title' => t('State editor'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'devel.state_system_page',
|
'route_name' => 'devel.state_system_page',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_development',
|
'parent' => 'admin_development',
|
||||||
];
|
];
|
||||||
$links['admin_toolbar_tools.devel.theme_registry'] = [
|
$links['admin_toolbar_tools.devel.theme_registry'] = [
|
||||||
'title' => t('Theme registry'),
|
'title' => t('Theme registry'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'devel.theme_registry',
|
'route_name' => 'devel.theme_registry',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_development',
|
'parent' => 'admin_development',
|
||||||
];
|
];
|
||||||
$links['admin_toolbar_tools.devel.entity_info_page'] = [
|
$links['admin_toolbar_tools.devel.entity_info_page'] = [
|
||||||
'title' => t('Entity Info'),
|
'title' => t('Entity Info'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'devel.entity_info_page',
|
'route_name' => 'devel.entity_info_page',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_development',
|
'parent' => 'admin_development',
|
||||||
];
|
];
|
||||||
$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'] = [
|
$links['admin_toolbar_tools.devel.session'] = [
|
||||||
'title' => t('Session viewer'),
|
'title' => t('Session viewer'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'devel.session',
|
'route_name' => 'devel.session',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_development',
|
'parent' => 'admin_development',
|
||||||
];
|
];
|
||||||
$links['admin_toolbar_tools.devel.elements_page'] = [
|
$links['admin_toolbar_tools.devel.elements_page'] = [
|
||||||
'title' => t('Form API field types'),
|
'title' => t('Form API field types'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'devel.elements_page',
|
'route_name' => 'devel.elements_page',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_development',
|
'parent' => 'admin_development',
|
||||||
@@ -480,16 +535,35 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
// Menu link for the Toolbar module.
|
// Menu link for the Toolbar module.
|
||||||
$links['admin_toolbar_tools.toolbar.settings'] = [
|
$links['admin_toolbar_tools.toolbar.settings'] = [
|
||||||
'title' => t('Toolbar settings'),
|
'title' => t('Toolbar settings'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'devel.toolbar.settings_form',
|
'route_name' => 'devel.toolbar.settings_form',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'devel.admin_settings',
|
'parent' => 'devel.admin_settings',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
// If module Devel PHP is enabled.
|
||||||
|
if ($moduleHandler->moduleExists('devel_php') && $routeExists('devel_php.execute_php')) {
|
||||||
|
$links['admin_toolbar_tools.devel_php.execute_php'] = [
|
||||||
|
'title' => t('Execute PHP Code'),
|
||||||
|
'route_name' => 'devel_php.execute_php',
|
||||||
|
'menu_name' => 'admin',
|
||||||
|
'parent' => 'admin_development',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
elseif ($moduleHandler->moduleExists('devel') && $routeExists('devel.execute_php')) {
|
||||||
|
$links['admin_toolbar_tools.devel.execute_php'] = [
|
||||||
|
'title' => t('Execute PHP Code'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
|
'route_name' => 'devel.execute_php',
|
||||||
|
'menu_name' => 'admin',
|
||||||
|
'parent' => 'admin_development',
|
||||||
|
];
|
||||||
|
}
|
||||||
// If module Views Ui enabled.
|
// If module Views Ui enabled.
|
||||||
if ($moduleHandler->moduleExists('views_ui')) {
|
if ($moduleHandler->moduleExists('views_ui')) {
|
||||||
$links['admin_toolbar_tools.views_ui.add'] = [
|
$links['admin_toolbar_tools.views_ui.add'] = [
|
||||||
'title' => t('Add new view'),
|
'title' => t('Add new view'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'views_ui.add',
|
'route_name' => 'views_ui.add',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.view.collection',
|
'parent' => 'entity.view.collection',
|
||||||
@@ -497,6 +571,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
];
|
];
|
||||||
$links['admin_toolbar_tools.views_ui.field_list'] = [
|
$links['admin_toolbar_tools.views_ui.field_list'] = [
|
||||||
'title' => t('Used in views'),
|
'title' => t('Used in views'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'views_ui.reports_fields',
|
'route_name' => 'views_ui.reports_fields',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.field_storage_config.collection',
|
'parent' => 'entity.field_storage_config.collection',
|
||||||
@@ -505,6 +580,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
|
|
||||||
$links['admin_toolbar_tools.system.theme_settings'] = [
|
$links['admin_toolbar_tools.system.theme_settings'] = [
|
||||||
'title' => t('Settings'),
|
'title' => t('Settings'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'system.theme_settings',
|
'route_name' => 'system.theme_settings',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'system.themes_page',
|
'parent' => 'system.themes_page',
|
||||||
@@ -513,6 +589,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('webprofiler')) {
|
if ($moduleHandler->moduleExists('webprofiler')) {
|
||||||
$links['admin_toolbar_tools.devel.webprofiler'] = [
|
$links['admin_toolbar_tools.devel.webprofiler'] = [
|
||||||
'title' => t('Webprofiler settings'),
|
'title' => t('Webprofiler settings'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'webprofiler.settings',
|
'route_name' => 'webprofiler.settings',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'admin_development',
|
'parent' => 'admin_development',
|
||||||
@@ -522,12 +599,14 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('update')) {
|
if ($moduleHandler->moduleExists('update')) {
|
||||||
$links['update.theme_install_'] = [
|
$links['update.theme_install_'] = [
|
||||||
'title' => t('Install new theme'),
|
'title' => t('Install new theme'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'update.theme_install',
|
'route_name' => 'update.theme_install',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'system.themes_page',
|
'parent' => 'system.themes_page',
|
||||||
];
|
];
|
||||||
$links['update.theme_update_'] = [
|
$links['update.theme_update_'] = [
|
||||||
'title' => t('Update'),
|
'title' => t('Update'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'update.theme_update',
|
'route_name' => 'update.theme_update',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'system.themes_page',
|
'parent' => 'system.themes_page',
|
||||||
@@ -537,6 +616,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
foreach ($installed_themes as $key_theme => $label_theme) {
|
foreach ($installed_themes as $key_theme => $label_theme) {
|
||||||
$links['system.theme_settings_theme.' . $key_theme] = [
|
$links['system.theme_settings_theme.' . $key_theme] = [
|
||||||
'title' => t($label_theme),
|
'title' => t($label_theme),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'system.theme_settings_theme',
|
'route_name' => 'system.theme_settings_theme',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'system.theme_settings_',
|
'parent' => 'system.theme_settings_',
|
||||||
@@ -551,6 +631,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('language')) {
|
if ($moduleHandler->moduleExists('language')) {
|
||||||
$links['admin_toolbar_tools.language.negotiation'] = [
|
$links['admin_toolbar_tools.language.negotiation'] = [
|
||||||
'title' => t('Detection and selection'),
|
'title' => t('Detection and selection'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'language.negotiation',
|
'route_name' => 'language.negotiation',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'entity.configurable_language.collection',
|
'parent' => 'entity.configurable_language.collection',
|
||||||
@@ -561,14 +642,16 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('media')) {
|
if ($moduleHandler->moduleExists('media')) {
|
||||||
$links['admin_toolbar_tools.add_media'] = [
|
$links['admin_toolbar_tools.add_media'] = [
|
||||||
'title' => t('Add media'),
|
'title' => t('Add media'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.media.add_page',
|
'route_name' => 'entity.media.add_page',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'system.admin_content',
|
'parent' => 'system.admin_content',
|
||||||
];
|
];
|
||||||
// Add node links for each media type.
|
// Add node links for each media type.
|
||||||
foreach (\Drupal::entityTypeManager()->getStorage('media_type')->loadMultiple() as $type) {
|
foreach ($entityTypeManager->getStorage('media_type')->loadMultiple() as $type) {
|
||||||
$links['media.add.' . $type->id()] = [
|
$links['media.add.' . $type->id()] = [
|
||||||
'title' => t($type->label()),
|
'title' => t($type->label()),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'entity.media.add_form',
|
'route_name' => 'entity.media.add_form',
|
||||||
'parent' => 'admin_toolbar_tools.add_media',
|
'parent' => 'admin_toolbar_tools.add_media',
|
||||||
'route_parameters' => ['media_type' => $type->id()],
|
'route_parameters' => ['media_type' => $type->id()],
|
||||||
@@ -580,6 +663,7 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
if ($moduleHandler->moduleExists('config')) {
|
if ($moduleHandler->moduleExists('config')) {
|
||||||
$links['admin_toolbar_tools.config.import'] = [
|
$links['admin_toolbar_tools.config.import'] = [
|
||||||
'title' => t('Import'),
|
'title' => t('Import'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'config.import_full',
|
'route_name' => 'config.import_full',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'config.sync',
|
'parent' => 'config.sync',
|
||||||
@@ -587,12 +671,15 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) {
|
|||||||
];
|
];
|
||||||
$links['admin_toolbar_tools.config.export'] = [
|
$links['admin_toolbar_tools.config.export'] = [
|
||||||
'title' => t('Export'),
|
'title' => t('Export'),
|
||||||
|
'provider' => 'admin_toolbar_tools',
|
||||||
'route_name' => 'config.export_full',
|
'route_name' => 'config.export_full',
|
||||||
'menu_name' => 'admin',
|
'menu_name' => 'admin',
|
||||||
'parent' => 'config.sync',
|
'parent' => 'config.sync',
|
||||||
'weight' => 2,
|
'weight' => 2,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$languageManager->setConfigOverrideLanguage($config_override_language);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -613,20 +700,3 @@ function admin_toolbar_tools_installed_themes() {
|
|||||||
|
|
||||||
return $themes_installed;
|
return $themes_installed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all links related to entity.
|
|
||||||
*
|
|
||||||
* @param string $entity_type_id
|
|
||||||
* The machine name for the entity type.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
* The links for the entity type.
|
|
||||||
*/
|
|
||||||
function admin_toolbar_tools_get_links($entity_type_id) {
|
|
||||||
$entity = \Drupal::entityTypeManager()->getDefinition($entity_type_id);
|
|
||||||
// Get all links related to entity.
|
|
||||||
$links = $entity->getLinkTemplates();
|
|
||||||
|
|
||||||
return $links;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -34,6 +34,6 @@
|
|||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"drupal/admin_toolbar": "^1",
|
"drupal/admin_toolbar": "^1",
|
||||||
"drupal/core": "~8.3"
|
"drupal/core": "~8.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -162,8 +162,8 @@ class ToolbarController extends ControllerBase {
|
|||||||
* Flushes all caches.
|
* Flushes all caches.
|
||||||
*/
|
*/
|
||||||
public function flushAll() {
|
public function flushAll() {
|
||||||
|
$this->messenger()->addMessage($this->t('All caches cleared.'));
|
||||||
drupal_flush_all_caches();
|
drupal_flush_all_caches();
|
||||||
drupal_set_message($this->t('All caches cleared.'));
|
|
||||||
return new RedirectResponse($this->reloadPage());
|
return new RedirectResponse($this->reloadPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ class ToolbarController extends ControllerBase {
|
|||||||
public function flushJsCss() {
|
public function flushJsCss() {
|
||||||
$this->state()
|
$this->state()
|
||||||
->set('system.css_js_query_string', base_convert($this->time->getCurrentTime(), 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.'));
|
$this->messenger()->addMessage($this->t('CSS and JavaScript cache cleared.'));
|
||||||
return new RedirectResponse($this->reloadPage());
|
return new RedirectResponse($this->reloadPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ class ToolbarController extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
public function flushPlugins() {
|
public function flushPlugins() {
|
||||||
$this->pluginCacheClearer->clearCachedDefinitions();
|
$this->pluginCacheClearer->clearCachedDefinitions();
|
||||||
drupal_set_message($this->t('Plugins cache cleared.'));
|
$this->messenger()->addMessage($this->t('Plugins cache cleared.'));
|
||||||
return new RedirectResponse($this->reloadPage());
|
return new RedirectResponse($this->reloadPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ class ToolbarController extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
public function flushStatic() {
|
public function flushStatic() {
|
||||||
drupal_static_reset();
|
drupal_static_reset();
|
||||||
drupal_set_message($this->t('Static cache cleared.'));
|
$this->messenger()->addMessage($this->t('Static cache cleared.'));
|
||||||
return new RedirectResponse($this->reloadPage());
|
return new RedirectResponse($this->reloadPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ class ToolbarController extends ControllerBase {
|
|||||||
$this->contextualLinkManager->clearCachedDefinitions();
|
$this->contextualLinkManager->clearCachedDefinitions();
|
||||||
$this->localTaskLinkManager->clearCachedDefinitions();
|
$this->localTaskLinkManager->clearCachedDefinitions();
|
||||||
$this->localActionLinkManager->clearCachedDefinitions();
|
$this->localActionLinkManager->clearCachedDefinitions();
|
||||||
drupal_set_message($this->t('Routing and links cache cleared.'));
|
$this->messenger()->addMessage($this->t('Routing and links cache cleared.'));
|
||||||
return new RedirectResponse($this->reloadPage());
|
return new RedirectResponse($this->reloadPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ class ToolbarController extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
public function flushViews() {
|
public function flushViews() {
|
||||||
views_invalidate_cache();
|
views_invalidate_cache();
|
||||||
drupal_set_message($this->t('Views cache cleared.'));
|
$this->messenger()->addMessage($this->t('Views cache cleared.'));
|
||||||
return new RedirectResponse($this->reloadPage());
|
return new RedirectResponse($this->reloadPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +224,7 @@ class ToolbarController extends ControllerBase {
|
|||||||
// @todo Update once Drupal 8.6 will be released.
|
// @todo Update once Drupal 8.6 will be released.
|
||||||
// @see https://www.drupal.org/node/2908461
|
// @see https://www.drupal.org/node/2908461
|
||||||
PhpStorageFactory::get('twig')->deleteAll();
|
PhpStorageFactory::get('twig')->deleteAll();
|
||||||
drupal_set_message($this->t('Twig cache cleared.'));
|
$this->messenger()->addMessage($this->t('Twig cache cleared.'));
|
||||||
return new RedirectResponse($this->reloadPage());
|
return new RedirectResponse($this->reloadPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ class ToolbarController extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
public function runCron() {
|
public function runCron() {
|
||||||
$this->cron->run();
|
$this->cron->run();
|
||||||
drupal_set_message($this->t('Cron ran successfully.'));
|
$this->messenger()->addMessage($this->t('Cron ran successfully.'));
|
||||||
return new RedirectResponse($this->reloadPage());
|
return new RedirectResponse($this->reloadPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ class ToolbarController extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
public function cacheRender() {
|
public function cacheRender() {
|
||||||
$this->cacheRender->invalidateAll();
|
$this->cacheRender->invalidateAll();
|
||||||
drupal_set_message($this->t('Render cache cleared.'));
|
$this->messenger()->addMessage($this->t('Render cache cleared.'));
|
||||||
return new RedirectResponse($this->reloadPage());
|
return new RedirectResponse($this->reloadPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ description: 'Provides basic revert and update functionality for other modules'
|
|||||||
dependencies:
|
dependencies:
|
||||||
- drupal:config
|
- drupal:config
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2017-12-05
|
# Information added by Drupal.org packaging script on 2018-12-17
|
||||||
version: '8.x-1.5'
|
version: '8.x-1.6'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'config_update'
|
project: 'config_update'
|
||||||
datestamp: 1512514387
|
datestamp: 1545090489
|
||||||
|
|||||||
+6
-1
@@ -285,8 +285,13 @@ function drush_config_update_ui_config_revert($name) {
|
|||||||
|
|
||||||
// The revert command needs the type and the unprefixed name.
|
// The revert command needs the type and the unprefixed name.
|
||||||
$type = $lister->getTypeNameByConfigName($name);
|
$type = $lister->getTypeNameByConfigName($name);
|
||||||
|
// The lister gives NULL if simple configuration, but the reverter expects
|
||||||
|
// 'system.simple' so we convert it.
|
||||||
|
if ($type === NULL) {
|
||||||
|
$type = 'system.simple';
|
||||||
|
}
|
||||||
$shortname = $name;
|
$shortname = $name;
|
||||||
if ($type && $type != 'system.simple') {
|
if ($type != 'system.simple') {
|
||||||
$definition = $manager->getDefinition($type);
|
$definition = $manager->getDefinition($type);
|
||||||
$prefix = $definition->getConfigPrefix() . '.';
|
$prefix = $definition->getConfigPrefix() . '.';
|
||||||
if (strpos($name, $prefix) === 0) {
|
if (strpos($name, $prefix) === 0) {
|
||||||
|
|||||||
+3
-3
@@ -7,8 +7,8 @@ dependencies:
|
|||||||
- config_update:config_update
|
- config_update:config_update
|
||||||
- drupal:config
|
- drupal:config
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2017-12-05
|
# Information added by Drupal.org packaging script on 2018-12-17
|
||||||
version: '8.x-1.5'
|
version: '8.x-1.6'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'config_update'
|
project: 'config_update'
|
||||||
datestamp: 1512514387
|
datestamp: 1545090489
|
||||||
|
|||||||
+17
@@ -35,3 +35,20 @@ function config_update_ui_help($route_name, RouteMatchInterface $route_match) {
|
|||||||
return '<p>' . t('Most configuration is organized into a hierarchy of settings; at a minimum, it is a one-level hierarchy where each setting has a name and a value, and the hierarchy comes in when some of the settings have multiple components.') . '</p><p>' . t('Configuration items are normalized and formatted before computing differences. The normalization step alphabetizes the components at each level of the hierarchy, and removes a few components whose differences should be ignored, such as the UUID. The formatting step shows the full hierarchy of each configuration value with :: separators for the hierarchy levels, and a : separator between the lowest-level setting name and the value, so that in a line-by-line diff you can always see which values are actually different. Green lines with + signs have been added, and yellow lines with - signs have been removed.') . '</p><p>' . t('Note that differences are considering the base configuration, without overrides from your settings.php file, or translations.') . '</p>';
|
return '<p>' . t('Most configuration is organized into a hierarchy of settings; at a minimum, it is a one-level hierarchy where each setting has a name and a value, and the hierarchy comes in when some of the settings have multiple components.') . '</p><p>' . t('Configuration items are normalized and formatted before computing differences. The normalization step alphabetizes the components at each level of the hierarchy, and removes a few components whose differences should be ignored, such as the UUID. The formatting step shows the full hierarchy of each configuration value with :: separators for the hierarchy levels, and a : separator between the lowest-level setting name and the value, so that in a line-by-line diff you can always see which values are actually different. Green lines with + signs have been added, and yellow lines with - signs have been removed.') . '</p><p>' . t('Note that differences are considering the base configuration, without overrides from your settings.php file, or translations.') . '</p>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_menu_links_discovered_alter().
|
||||||
|
*/
|
||||||
|
function config_update_ui_menu_links_discovered_alter(&$links) {
|
||||||
|
if (\Drupal::moduleHandler()->moduleExists('admin_toolbar_tools')) {
|
||||||
|
// Add the Updates report link to the Tools menu, but only if the
|
||||||
|
// Admin Toolbar Extra Tools module is present.
|
||||||
|
$links['admin_toolbar_tools.config.update'] = [
|
||||||
|
'title' => t('Updates report'),
|
||||||
|
'route_name' => 'config_update_ui.report',
|
||||||
|
'menu_name' => 'admin',
|
||||||
|
'parent' => 'config.sync',
|
||||||
|
'weight' => 3,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -137,7 +137,7 @@ class ConfigDeleteConfirmForm extends ConfirmFormBase {
|
|||||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||||
$this->configRevert->delete($this->type, $this->name);
|
$this->configRevert->delete($this->type, $this->name);
|
||||||
|
|
||||||
drupal_set_message($this->t('The configuration was deleted.'));
|
$this->messenger()->addMessage($this->t('The configuration %item has been deleted.', ['%item' => $this->name]));
|
||||||
$form_state->setRedirectUrl($this->getCancelUrl());
|
$form_state->setRedirectUrl($this->getCancelUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -139,7 +139,7 @@ class ConfigImportConfirmForm extends ConfirmFormBase {
|
|||||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||||
$this->configRevert->import($this->type, $this->name);
|
$this->configRevert->import($this->type, $this->name);
|
||||||
|
|
||||||
drupal_set_message($this->t('The configuration was imported from its source.'));
|
$this->messenger()->addMessage($this->t('The configuration %item has been imported from its source.', ['%item' => $this->name]));
|
||||||
$form_state->setRedirectUrl($this->getCancelUrl());
|
$form_state->setRedirectUrl($this->getCancelUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -139,7 +139,7 @@ class ConfigRevertConfirmForm extends ConfirmFormBase {
|
|||||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||||
$this->configRevert->revert($this->type, $this->name);
|
$this->configRevert->revert($this->type, $this->name);
|
||||||
|
|
||||||
drupal_set_message($this->t('The configuration was reverted to its source.'));
|
$this->messenger()->addMessage($this->t('The configuration %item has been reverted to its source.', ['%item' => $this->name]));
|
||||||
$form_state->setRedirectUrl($this->getCancelUrl());
|
$form_state->setRedirectUrl($this->getCancelUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-10
@@ -1,15 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Drupal\config_update_ui\Tests;
|
namespace Drupal\Tests\config_update_ui\Functional;
|
||||||
|
|
||||||
use Drupal\simpletest\WebTestBase;
|
use Drupal\Tests\BrowserTestBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify config reports, reverts, and diffs with profile overrides.
|
* Verify config reports, reverts, and diffs with profile overrides.
|
||||||
*
|
*
|
||||||
* @group config
|
* @group config_update
|
||||||
*/
|
*/
|
||||||
class ConfigProfileOverridesTest extends WebTestBase {
|
class ConfigProfileOverridesTest extends BrowserTestBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the Standard profile, so that there are profile config overrides.
|
* Use the Standard profile, so that there are profile config overrides.
|
||||||
@@ -43,7 +43,7 @@ class ConfigProfileOverridesTest extends WebTestBase {
|
|||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
// Create user and log in.
|
// Create user and log in.
|
||||||
$this->adminUser = $this->drupalCreateUser([
|
$this->adminUser = $this->createUser([
|
||||||
'access administration pages',
|
'access administration pages',
|
||||||
'administer themes',
|
'administer themes',
|
||||||
'view config updates report',
|
'view config updates report',
|
||||||
@@ -68,7 +68,8 @@ class ConfigProfileOverridesTest extends WebTestBase {
|
|||||||
// that system.theme is not shown (it should not be missing, or added,
|
// that system.theme is not shown (it should not be missing, or added,
|
||||||
// or overridden).
|
// or overridden).
|
||||||
$this->drupalGet('admin/config/development/configuration/report/type/system.simple');
|
$this->drupalGet('admin/config/development/configuration/report/type/system.simple');
|
||||||
$this->assertNoRaw('system.theme');
|
$session = $this->assertSession();
|
||||||
|
$session->responseNotContains('system.theme');
|
||||||
|
|
||||||
// Go to the Appearance page and change the theme to whatever is currently
|
// 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,
|
// disabled. Return to the report and verify that system.theme is there,
|
||||||
@@ -76,22 +77,25 @@ class ConfigProfileOverridesTest extends WebTestBase {
|
|||||||
$this->drupalGet('admin/appearance');
|
$this->drupalGet('admin/appearance');
|
||||||
$this->clickLink('Install and set as default');
|
$this->clickLink('Install and set as default');
|
||||||
$this->drupalGet('admin/config/development/configuration/report/type/system.simple');
|
$this->drupalGet('admin/config/development/configuration/report/type/system.simple');
|
||||||
$this->assertText('system.theme');
|
$session = $this->assertSession();
|
||||||
|
$session->pageTextContains('system.theme');
|
||||||
|
|
||||||
// Look at the differences for system.theme and verify it's against
|
// Look at the differences for system.theme and verify it's against
|
||||||
// the standard profile version, not default version. The line for
|
// the standard profile version, not default version. The line for
|
||||||
// default should show bartik as the source; if it's against the system
|
// default should show bartik as the source; if it's against the system
|
||||||
// version, the word bartik would not be there.
|
// version, the word bartik would not be there.
|
||||||
$this->drupalGet('admin/config/development/configuration/report/diff/system.simple/system.theme');
|
$this->drupalGet('admin/config/development/configuration/report/diff/system.simple/system.theme');
|
||||||
$this->assertText('bartik');
|
$session = $this->assertSession();
|
||||||
|
$session->pageTextContains('bartik');
|
||||||
|
|
||||||
// Revert and verify that it reverted to the profile version, not the
|
// Revert and verify that it reverted to the profile version, not the
|
||||||
// system module version.
|
// system module version.
|
||||||
$this->drupalGet('admin/config/development/configuration/report/revert/system.simple/system.theme');
|
$this->drupalGet('admin/config/development/configuration/report/revert/system.simple/system.theme');
|
||||||
$this->drupalPostForm(NULL, [], 'Revert');
|
$this->drupalPostForm(NULL, [], 'Revert');
|
||||||
$this->drupalGet('admin/config/development/configuration/single/export/system.simple/system.theme');
|
$this->drupalGet('admin/config/development/configuration/single/export/system.simple/system.theme');
|
||||||
$this->assertText('admin: seven');
|
$session = $this->assertSession();
|
||||||
$this->assertText('default: bartik');
|
$session->pageTextContains('admin: seven');
|
||||||
|
$session->pageTextContains('default: bartik');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+120
-97
@@ -1,15 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Drupal\config_update_ui\Tests;
|
namespace Drupal\Tests\config_update_ui\Functional;
|
||||||
|
|
||||||
use Drupal\simpletest\WebTestBase;
|
use Drupal\Tests\BrowserTestBase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify the config revert report and its links.
|
* Verify the config revert report and its links.
|
||||||
*
|
*
|
||||||
* @group config
|
* @group config_update
|
||||||
*/
|
*/
|
||||||
class ConfigUpdateTest extends WebTestBase {
|
class ConfigUpdateTest extends BrowserTestBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modules to enable.
|
* Modules to enable.
|
||||||
@@ -46,7 +46,7 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
// Create user and log in.
|
// Create user and log in.
|
||||||
$this->adminUser = $this->drupalCreateUser([
|
$this->adminUser = $this->createUser([
|
||||||
'access administration pages',
|
'access administration pages',
|
||||||
'administer search',
|
'administer search',
|
||||||
'view config updates report',
|
'view config updates report',
|
||||||
@@ -60,8 +60,8 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
$this->drupalLogin($this->adminUser);
|
$this->drupalLogin($this->adminUser);
|
||||||
|
|
||||||
// Make sure local tasks and page title are showing.
|
// Make sure local tasks and page title are showing.
|
||||||
$this->drupalPlaceBlock('local_tasks_block');
|
$this->placeBlock('local_tasks_block');
|
||||||
$this->drupalPlaceBlock('page_title_block');
|
$this->placeBlock('page_title_block');
|
||||||
|
|
||||||
// Load the Drush include file so that its functions can be tested, plus
|
// Load the Drush include file so that its functions can be tested, plus
|
||||||
// the Drush testing include file.
|
// the Drush testing include file.
|
||||||
@@ -103,13 +103,15 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
$this->assertReport('Testing profile', [], [], [], $inactive, ['added']);
|
$this->assertReport('Testing profile', [], [], [], $inactive, ['added']);
|
||||||
// The locale.settings line should show that the Testing profile is the
|
// The locale.settings line should show that the Testing profile is the
|
||||||
// provider.
|
// provider.
|
||||||
$this->assertText('Testing profile');
|
$session = $this->assertSession();
|
||||||
|
$session->pageTextContains('Testing profile');
|
||||||
$this->assertDrushReports('profile', '', [], [], [], array_keys($inactive));
|
$this->assertDrushReports('profile', '', [], [], [], array_keys($inactive));
|
||||||
|
|
||||||
// Verify that the user search page cannot be imported (because it already
|
// Verify that the user search page cannot be imported (because it already
|
||||||
// exists).
|
// exists).
|
||||||
$this->drupalGet('admin/config/development/configuration/report/import/search_page/user_search');
|
$this->drupalGet('admin/config/development/configuration/report/import/search_page/user_search');
|
||||||
$this->assertResponse(404);
|
$session = $this->assertSession();
|
||||||
|
$session->statusCodeEquals(404);
|
||||||
|
|
||||||
// Delete the user search page from the search UI and verify report for
|
// Delete the user search page from the search UI and verify report for
|
||||||
// both the search page config type and user module.
|
// both the search page config type and user module.
|
||||||
@@ -121,7 +123,8 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
$this->assertReport('Search page', [], [], [], $inactive);
|
$this->assertReport('Search page', [], [], [], $inactive);
|
||||||
// The search.page.user_search line should show that the User module is the
|
// The search.page.user_search line should show that the User module is the
|
||||||
// provider.
|
// provider.
|
||||||
$this->assertText('User module');
|
$session = $this->assertSession();
|
||||||
|
$session->pageTextContains('User module');
|
||||||
$this->assertDrushReports('type', 'search_page', [], [], [], array_keys($inactive));
|
$this->assertDrushReports('type', 'search_page', [], [], [], array_keys($inactive));
|
||||||
|
|
||||||
$this->drupalGet('admin/config/development/configuration/report/module/user');
|
$this->drupalGet('admin/config/development/configuration/report/module/user');
|
||||||
@@ -138,17 +141,20 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
// Verify that the user search page cannot be reverted (because it does
|
// Verify that the user search page cannot be reverted (because it does
|
||||||
// not already exist).
|
// not already exist).
|
||||||
$this->drupalGet('admin/config/development/configuration/report/revert/search_page/user_search');
|
$this->drupalGet('admin/config/development/configuration/report/revert/search_page/user_search');
|
||||||
$this->assertResponse(404);
|
$session = $this->assertSession();
|
||||||
|
$session->statusCodeEquals(404);
|
||||||
// Verify that the delete URL doesn't work either.
|
// Verify that the delete URL doesn't work either.
|
||||||
$this->drupalGet('admin/config/development/configuration/report/delete/search_page/user_search');
|
$this->drupalGet('admin/config/development/configuration/report/delete/search_page/user_search');
|
||||||
$this->assertResponse(404);
|
$session = $this->assertSession();
|
||||||
|
$session->statusCodeEquals(404);
|
||||||
|
|
||||||
// Use the import link to get it back. Do this from the search page
|
// Use the import link to get it back. Do this from the search page
|
||||||
// report to make sure we are importing the right config.
|
// report to make sure we are importing the right config.
|
||||||
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
||||||
$this->clickLink('Import from source');
|
$this->clickLink('Import from source');
|
||||||
$this->drupalPostForm(NULL, [], 'Import');
|
$this->drupalPostForm(NULL, [], 'Import');
|
||||||
$this->assertText('The configuration was imported');
|
$session = $this->assertSession();
|
||||||
|
$session->pageTextContains('has been imported');
|
||||||
$this->assertNoReport();
|
$this->assertNoReport();
|
||||||
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
||||||
$this->assertReport('Search page', [], [], [], []);
|
$this->assertReport('Search page', [], [], [], []);
|
||||||
@@ -156,8 +162,9 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
|
|
||||||
// Verify that after import, there is no config hash generated.
|
// Verify that after import, there is no config hash generated.
|
||||||
$this->drupalGet('admin/config/development/configuration/single/export/search_page/user_search');
|
$this->drupalGet('admin/config/development/configuration/single/export/search_page/user_search');
|
||||||
$this->assertText('id: user_search');
|
$session = $this->assertSession();
|
||||||
$this->assertNoText('default_config_hash:');
|
$session->pageTextContains('id: user_search');
|
||||||
|
$session->pageTextNotContains('default_config_hash:');
|
||||||
|
|
||||||
// Test importing again, this time using the Drush import command.
|
// Test importing again, this time using the Drush import command.
|
||||||
$this->drupalGet('admin/config/search/pages');
|
$this->drupalGet('admin/config/search/pages');
|
||||||
@@ -184,10 +191,11 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
|
|
||||||
// Test the show differences link.
|
// Test the show differences link.
|
||||||
$this->clickLink('Show differences');
|
$this->clickLink('Show differences');
|
||||||
$this->assertText('Content');
|
$session = $this->assertSession();
|
||||||
$this->assertText('New label');
|
$session->pageTextContains('Content');
|
||||||
$this->assertText('node');
|
$session->pageTextContains('New label');
|
||||||
$this->assertText('new_path');
|
$session->pageTextContains('node');
|
||||||
|
$session->pageTextContains('new_path');
|
||||||
|
|
||||||
// Test the show differences Drush command.
|
// Test the show differences Drush command.
|
||||||
$output = drush_config_update_ui_config_diff('search.page.node_search');
|
$output = drush_config_update_ui_config_diff('search.page.node_search');
|
||||||
@@ -203,36 +211,39 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
// Test the export link.
|
// Test the export link.
|
||||||
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
||||||
$this->clickLink('Export');
|
$this->clickLink('Export');
|
||||||
$this->assertText('Here is your configuration:');
|
$session = $this->assertSession();
|
||||||
$this->assertText('id: node_search');
|
$session->pageTextContains('Here is your configuration:');
|
||||||
$this->assertText('New label');
|
$session->pageTextContains('id: node_search');
|
||||||
$this->assertText('path: new_path');
|
$session->pageTextContains('New label');
|
||||||
$this->assertText('search.page.node_search.yml');
|
$session->pageTextContains('path: new_path');
|
||||||
|
$session->pageTextContains('search.page.node_search.yml');
|
||||||
|
|
||||||
// Grab the uuid and hash lines for the next test.
|
// Grab the uuid and hash lines from the exported config for the next test.
|
||||||
$text = $this->getTextContent();
|
$text = strip_tags($this->getSession()->getPage()->find('css', 'textarea')->getHtml());
|
||||||
$matches = [];
|
$matches = [];
|
||||||
preg_match('|^.*uuid:.*$|m', $text, $matches);
|
preg_match('|^.*uuid:.*$|m', $text, $matches);
|
||||||
$uuid_line = $matches[0];
|
$uuid_line = trim($matches[0]);
|
||||||
preg_match('|^.*default_config_hash:.*$|m', $text, $matches);
|
preg_match('|^.*default_config_hash:.*$|m', $text, $matches);
|
||||||
$hash_line = $matches[0];
|
$hash_line = trim($matches[0]);
|
||||||
|
|
||||||
// Test reverting.
|
// Test reverting.
|
||||||
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
||||||
$this->clickLink('Revert to source');
|
$this->clickLink('Revert to source');
|
||||||
$this->assertText('Are you sure you want to revert');
|
$session = $this->assertSession();
|
||||||
$this->assertText('Search page');
|
$session->pageTextContains('Are you sure you want to revert');
|
||||||
$this->assertText('node_search');
|
$session->pageTextContains('Search page');
|
||||||
$this->assertText('Customizations will be lost. This action cannot be undone');
|
$session->pageTextContains('node_search');
|
||||||
|
$session->pageTextContains('Customizations will be lost. This action cannot be undone');
|
||||||
$this->drupalPostForm(NULL, [], 'Revert');
|
$this->drupalPostForm(NULL, [], 'Revert');
|
||||||
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
||||||
$this->assertReport('Search page', [], [], [], []);
|
$this->assertReport('Search page', [], [], [], []);
|
||||||
|
|
||||||
// Verify that the uuid and hash keys were retained in the revert.
|
// Verify that the uuid and hash keys were retained in the revert.
|
||||||
$this->drupalGet('admin/config/development/configuration/single/export/search_page/node_search');
|
$this->drupalGet('admin/config/development/configuration/single/export/search_page/node_search');
|
||||||
$this->assertText('id: node_search');
|
$session = $this->assertSession();
|
||||||
$this->assertText($uuid_line);
|
$session->pageTextContains('id: node_search');
|
||||||
$this->assertText($hash_line);
|
$session->pageTextContains($uuid_line);
|
||||||
|
$session->pageTextContains($hash_line);
|
||||||
|
|
||||||
// Test reverting again, this time using Drush single revert command.
|
// Test reverting again, this time using Drush single revert command.
|
||||||
$this->drupalGet('admin/config/search/pages');
|
$this->drupalGet('admin/config/search/pages');
|
||||||
@@ -278,19 +289,22 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
|
|
||||||
// Test the export link.
|
// Test the export link.
|
||||||
$this->clickLink('Export');
|
$this->clickLink('Export');
|
||||||
$this->assertText('Here is your configuration:');
|
$session = $this->assertSession();
|
||||||
$this->assertText('id: test');
|
$session->pageTextContains('Here is your configuration:');
|
||||||
$this->assertText('label: test');
|
$session->pageTextContains('id: test');
|
||||||
$this->assertText('path: test');
|
$session->pageTextContains('label: test');
|
||||||
$this->assertText('search.page.test.yml');
|
$session->pageTextContains('path: test');
|
||||||
|
$session->pageTextContains('search.page.test.yml');
|
||||||
|
|
||||||
// Test the delete link.
|
// Test the delete link.
|
||||||
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
||||||
$this->clickLink('Delete');
|
$this->clickLink('Delete');
|
||||||
$this->assertText('Are you sure');
|
$session = $this->assertSession();
|
||||||
$this->assertText('cannot be undone');
|
$session->pageTextContains('Are you sure');
|
||||||
|
$session->pageTextContains('cannot be undone');
|
||||||
$this->drupalPostForm(NULL, [], 'Delete');
|
$this->drupalPostForm(NULL, [], 'Delete');
|
||||||
$this->assertText('The configuration was deleted');
|
$session = $this->assertSession();
|
||||||
|
$session->pageTextContains('has been deleted');
|
||||||
|
|
||||||
// And verify the report again.
|
// And verify the report again.
|
||||||
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
$this->drupalGet('admin/config/development/configuration/report/type/search_page');
|
||||||
@@ -306,18 +320,20 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
$this->assertReport('Search module', [], [], $changed, [], ['added']);
|
$this->assertReport('Search module', [], [], $changed, [], ['added']);
|
||||||
|
|
||||||
$this->clickLink('Show differences');
|
$this->clickLink('Show differences');
|
||||||
$this->assertText('Config difference for Simple configuration search.settings');
|
$session = $this->assertSession();
|
||||||
$this->assertText('index::minimum_word_size');
|
$session->pageTextContains('Config difference for Simple configuration search.settings');
|
||||||
$this->assertText('4');
|
$session->pageTextContains('index::minimum_word_size');
|
||||||
|
$session->pageTextContains('4');
|
||||||
|
|
||||||
$this->drupalGet('admin/config/development/configuration/report/module/search');
|
$this->drupalGet('admin/config/development/configuration/report/module/search');
|
||||||
$this->clickLink('Export');
|
$this->clickLink('Export');
|
||||||
$this->assertText('minimum_word_size: 4');
|
$session = $this->assertSession();
|
||||||
|
$session->pageTextContains('minimum_word_size: 4');
|
||||||
// Grab the hash line for the next test.
|
// Grab the hash line for the next test.
|
||||||
$text = $this->getTextContent();
|
$text = strip_tags($this->getSession()->getPage()->find('css', 'textarea')->getHtml());
|
||||||
$matches = [];
|
$matches = [];
|
||||||
preg_match('|^.*default_config_hash:.*$|m', $text, $matches);
|
preg_match('|^.*default_config_hash:.*$|m', $text, $matches);
|
||||||
$hash_line = $matches[0];
|
$hash_line = trim($matches[0]);
|
||||||
|
|
||||||
$this->drupalGet('admin/config/development/configuration/report/module/search');
|
$this->drupalGet('admin/config/development/configuration/report/module/search');
|
||||||
$this->clickLink('Revert to source');
|
$this->clickLink('Revert to source');
|
||||||
@@ -325,7 +341,8 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
|
|
||||||
// Verify that the hash was retained in the revert.
|
// Verify that the hash was retained in the revert.
|
||||||
$this->drupalGet('admin/config/development/configuration/single/export/system.simple/search.settings');
|
$this->drupalGet('admin/config/development/configuration/single/export/system.simple/search.settings');
|
||||||
$this->assertText($hash_line);
|
$session = $this->assertSession();
|
||||||
|
$session->pageTextContains($hash_line);
|
||||||
|
|
||||||
$this->drupalGet('admin/config/development/configuration/report/module/search');
|
$this->drupalGet('admin/config/development/configuration/report/module/search');
|
||||||
$this->assertReport('Search module', [], [], [], [], ['added']);
|
$this->assertReport('Search module', [], [], [], [], ['added']);
|
||||||
@@ -338,6 +355,10 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
$changed = ['filter.format.plain_text' => 'New label'];
|
$changed = ['filter.format.plain_text' => 'New label'];
|
||||||
$this->drupalGet('admin/config/development/configuration/report/type/filter_format');
|
$this->drupalGet('admin/config/development/configuration/report/type/filter_format');
|
||||||
$this->assertReport('Text format', [], [], $changed, []);
|
$this->assertReport('Text format', [], [], $changed, []);
|
||||||
|
|
||||||
|
// Verify that we can revert non-entity configuration in Drush. Issue:
|
||||||
|
// https://www.drupal.org/project/config_update/issues/2935395
|
||||||
|
drush_config_update_ui_config_revert('system.date');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -359,62 +380,63 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
* Array of report sections to skip checking.
|
* Array of report sections to skip checking.
|
||||||
*/
|
*/
|
||||||
protected function assertReport($title, array $missing, array $added, array $changed, array $inactive, array $skip = []) {
|
protected function assertReport($title, array $missing, array $added, array $changed, array $inactive, array $skip = []) {
|
||||||
$this->assertText('Configuration updates report for ' . $title);
|
$session = $this->assertSession();
|
||||||
$this->assertText('Generate new report');
|
$session->pageTextContains('Configuration updates report for ' . $title);
|
||||||
|
$session->pageTextContains('Generate new report');
|
||||||
|
|
||||||
if (!in_array('missing', $skip)) {
|
if (!in_array('missing', $skip)) {
|
||||||
$this->assertText('Missing configuration items');
|
$session->pageTextContains('Missing configuration items');
|
||||||
if (count($missing)) {
|
if (count($missing)) {
|
||||||
foreach ($missing as $name => $label) {
|
foreach ($missing as $name => $label) {
|
||||||
$this->assertText($name);
|
$session->pageTextContains($name);
|
||||||
$this->assertText($label);
|
$session->pageTextContains($label);
|
||||||
}
|
}
|
||||||
$this->assertNoText('None: all provided configuration items are in your active configuration.');
|
$session->pageTextNotContains('None: all provided configuration items are in your active configuration.');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$this->assertText('None: all provided configuration items are in your active configuration.');
|
$session->pageTextContains('None: all provided configuration items are in your active configuration.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array('inactive', $skip)) {
|
if (!in_array('inactive', $skip)) {
|
||||||
$this->assertText('Inactive optional items');
|
$session->pageTextContains('Inactive optional items');
|
||||||
if (count($inactive)) {
|
if (count($inactive)) {
|
||||||
foreach ($inactive as $name => $label) {
|
foreach ($inactive as $name => $label) {
|
||||||
$this->assertText($name);
|
$session->pageTextContains($name);
|
||||||
$this->assertText($label);
|
$session->pageTextContains($label);
|
||||||
}
|
}
|
||||||
$this->assertNoText('None: all optional configuration items are in your active configuration.');
|
$session->pageTextNotContains('None: all optional configuration items are in your active configuration.');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$this->assertText('None: all optional configuration items are in your active configuration.');
|
$session->pageTextContains('None: all optional configuration items are in your active configuration.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array('added', $skip)) {
|
if (!in_array('added', $skip)) {
|
||||||
$this->assertText('Added configuration items');
|
$session->pageTextContains('Added configuration items');
|
||||||
if (count($added)) {
|
if (count($added)) {
|
||||||
foreach ($added as $name => $label) {
|
foreach ($added as $name => $label) {
|
||||||
$this->assertText($name);
|
$session->pageTextContains($name);
|
||||||
$this->assertText($label);
|
$session->pageTextContains($label);
|
||||||
}
|
}
|
||||||
$this->assertNoText('None: all active configuration items of this type were provided by modules, themes, or install profile.');
|
$session->pageTextNotContains('None: all active configuration items of this type were provided by modules, themes, or install profile.');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$this->assertText('None: all active configuration items of this type were provided by modules, themes, or install profile.');
|
$session->pageTextContains('None: all active configuration items of this type were provided by modules, themes, or install profile.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array('changed', $skip)) {
|
if (!in_array('changed', $skip)) {
|
||||||
$this->assertText('Changed configuration items');
|
$session->pageTextContains('Changed configuration items');
|
||||||
if (count($changed)) {
|
if (count($changed)) {
|
||||||
foreach ($changed as $name => $label) {
|
foreach ($changed as $name => $label) {
|
||||||
$this->assertText($name);
|
$session->pageTextContains($name);
|
||||||
$this->assertText($label);
|
$session->pageTextContains($label);
|
||||||
}
|
}
|
||||||
$this->assertNoText('None: no active configuration items differ from their current provided versions.');
|
$session->pageTextNotContains('None: no active configuration items differ from their current provided versions.');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$this->assertText('None: no active configuration items differ from their current provided versions.');
|
$session->pageTextContains('None: no active configuration items differ from their current provided versions.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -440,7 +462,7 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
protected function assertDrushReports($type, $name, array $missing, array $added, array $changed, array $inactive, array $skip = []) {
|
protected function assertDrushReports($type, $name, array $missing, array $added, array $changed, array $inactive, array $skip = []) {
|
||||||
if (!in_array('missing', $skip)) {
|
if (!in_array('missing', $skip)) {
|
||||||
$output = drush_config_update_ui_config_missing_report($type, $name);
|
$output = drush_config_update_ui_config_missing_report($type, $name);
|
||||||
$this->assertEqual(count($output), count($missing), 'Drush missing report has correct number of items');
|
$this->assertEquals(count($output), count($missing), 'Drush missing report has correct number of items');
|
||||||
if (count($missing)) {
|
if (count($missing)) {
|
||||||
foreach ($missing as $item) {
|
foreach ($missing as $item) {
|
||||||
$this->assertTrue(in_array($item, $output), "Item $item is in the Drush missing report");
|
$this->assertTrue(in_array($item, $output), "Item $item is in the Drush missing report");
|
||||||
@@ -450,7 +472,7 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
|
|
||||||
if (!in_array('added', $skip) && $type == 'type') {
|
if (!in_array('added', $skip) && $type == 'type') {
|
||||||
$output = drush_config_update_ui_config_added_report($name);
|
$output = drush_config_update_ui_config_added_report($name);
|
||||||
$this->assertEqual(count($output), count($added), 'Drush added report has correct number of items');
|
$this->assertEquals(count($output), count($added), 'Drush added report has correct number of items');
|
||||||
if (count($added)) {
|
if (count($added)) {
|
||||||
foreach ($added as $item) {
|
foreach ($added as $item) {
|
||||||
$this->assertTrue(in_array($item, $output), "Item $item is in the Drush added report");
|
$this->assertTrue(in_array($item, $output), "Item $item is in the Drush added report");
|
||||||
@@ -460,7 +482,7 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
|
|
||||||
if (!in_array('changed', $skip)) {
|
if (!in_array('changed', $skip)) {
|
||||||
$output = drush_config_update_ui_config_different_report($type, $name);
|
$output = drush_config_update_ui_config_different_report($type, $name);
|
||||||
$this->assertEqual(count($output), count($changed), 'Drush changed report has correct number of items');
|
$this->assertEquals(count($output), count($changed), 'Drush changed report has correct number of items');
|
||||||
if (count($changed)) {
|
if (count($changed)) {
|
||||||
foreach ($changed as $item) {
|
foreach ($changed as $item) {
|
||||||
$this->assertTrue(in_array($item, $output), "Item $item is in the Drush changed report");
|
$this->assertTrue(in_array($item, $output), "Item $item is in the Drush changed report");
|
||||||
@@ -470,7 +492,7 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
|
|
||||||
if (!in_array('inactive', $skip)) {
|
if (!in_array('inactive', $skip)) {
|
||||||
$output = drush_config_update_ui_config_inactive_report($type, $name);
|
$output = drush_config_update_ui_config_inactive_report($type, $name);
|
||||||
$this->assertEqual(count($output), count($inactive), 'Drush inactive report has correct number of items');
|
$this->assertEquals(count($output), count($inactive), 'Drush inactive report has correct number of items');
|
||||||
if (count($inactive)) {
|
if (count($inactive)) {
|
||||||
foreach ($inactive as $item) {
|
foreach ($inactive as $item) {
|
||||||
$this->assertTrue(in_array($item, $output), "Item $item is in the Drush inactive report");
|
$this->assertTrue(in_array($item, $output), "Item $item is in the Drush inactive report");
|
||||||
@@ -485,37 +507,38 @@ class ConfigUpdateTest extends WebTestBase {
|
|||||||
* Assumes you are already on the report form page.
|
* Assumes you are already on the report form page.
|
||||||
*/
|
*/
|
||||||
protected function assertNoReport() {
|
protected function assertNoReport() {
|
||||||
$this->assertText('Report type');
|
$session = $this->assertSession();
|
||||||
$this->assertText('Full report');
|
$session->pageTextContains('Report type');
|
||||||
$this->assertText('Single configuration type');
|
$session->pageTextContains('Full report');
|
||||||
$this->assertText('Single module');
|
$session->pageTextContains('Single configuration type');
|
||||||
$this->assertText('Single theme');
|
$session->pageTextContains('Single module');
|
||||||
$this->assertText('Installation profile');
|
$session->pageTextContains('Single theme');
|
||||||
$this->assertText('Updates report');
|
$session->pageTextContains('Installation profile');
|
||||||
$this->assertNoText('Missing configuration items');
|
$session->pageTextContains('Updates report');
|
||||||
$this->assertNoText('Added configuration items');
|
$session->pageTextNotContains('Missing configuration items');
|
||||||
$this->assertNoText('Changed configuration items');
|
$session->pageTextNotContains('Added configuration items');
|
||||||
$this->assertNoText('Unchanged configuration items');
|
$session->pageTextNotContains('Changed configuration items');
|
||||||
|
$session->pageTextNotContains('Unchanged configuration items');
|
||||||
|
|
||||||
// Verify that certain report links are shown or not shown. For extensions,
|
// Verify that certain report links are shown or not shown. For extensions,
|
||||||
// only extensions that have configuration should be shown.
|
// only extensions that have configuration should be shown.
|
||||||
// Modules.
|
// Modules.
|
||||||
$this->assertLink('Search');
|
$session->linkExists('Search');
|
||||||
$this->assertLink('Field');
|
$session->linkExists('Field');
|
||||||
$this->assertNoLink('Configuration Update Base');
|
$session->linkNotExists('Configuration Update Base');
|
||||||
$this->assertNoLink('Configuration Update Reports');
|
$session->linkNotExists('Configuration Update Reports');
|
||||||
|
|
||||||
// Themes.
|
// Themes.
|
||||||
$this->assertNoLink('Stark');
|
$session->linkNotExists('Stark');
|
||||||
$this->assertNoLink('Classy');
|
$session->linkNotExists('Classy');
|
||||||
|
|
||||||
// Profiles.
|
// Profiles.
|
||||||
$this->assertLink('Testing');
|
$session->linkExists('Testing');
|
||||||
|
|
||||||
// Configuration types.
|
// Configuration types.
|
||||||
$this->assertLink('Everything');
|
$session->linkExists('Everything');
|
||||||
$this->assertLink('Simple configuration');
|
$session->linkExists('Simple configuration');
|
||||||
$this->assertLink('Search page');
|
$session->linkExists('Search page');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# This is the DrupalCI testbot build file for Configuration Update Manager.
|
||||||
|
# Learn to make one for your own drupal.org project:
|
||||||
|
# https://www.drupal.org/drupalorg/docs/drupal-ci/customizing-drupalci-testing
|
||||||
|
build:
|
||||||
|
assessment:
|
||||||
|
validate_codebase:
|
||||||
|
phplint:
|
||||||
|
phpcs:
|
||||||
|
# phpcs will use core's specified version of Coder.
|
||||||
|
sniff-all-files: true
|
||||||
|
halt-on-fail: true
|
||||||
|
testing:
|
||||||
|
# run_tests task is executed several times in order of performance speeds.
|
||||||
|
# halt-on-fail can be set on the run_tests tasks in order to fail fast.
|
||||||
|
# suppress-deprecations is false in order to be alerted to usages of
|
||||||
|
# deprecated code.
|
||||||
|
run_tests.phpunit:
|
||||||
|
types: 'PHPUnit-Unit'
|
||||||
|
testgroups: '--all'
|
||||||
|
suppress-deprecations: false
|
||||||
|
halt-on-fail: false
|
||||||
|
run_tests.kernel:
|
||||||
|
types: 'PHPUnit-Kernel'
|
||||||
|
testgroups: '--all'
|
||||||
|
suppress-deprecations: false
|
||||||
|
halt-on-fail: false
|
||||||
|
run_tests.functional:
|
||||||
|
types: 'PHPUnit-Functional'
|
||||||
|
testgroups: '--all'
|
||||||
|
suppress-deprecations: false
|
||||||
|
halt-on-fail: false
|
||||||
|
run_tests.javascript:
|
||||||
|
concurrency: 15
|
||||||
|
types: 'PHPUnit-FunctionalJavascript'
|
||||||
|
testgroups: '--all'
|
||||||
|
suppress-deprecations: false
|
||||||
|
halt-on-fail: false
|
||||||
@@ -5,6 +5,7 @@ namespace Drupal\config_update;
|
|||||||
use Drupal\Component\Diff\Diff;
|
use Drupal\Component\Diff\Diff;
|
||||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||||
|
use Drupal\Core\Serialization\Yaml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides methods related to config differences.
|
* Provides methods related to config differences.
|
||||||
@@ -14,7 +15,7 @@ class ConfigDiffer implements ConfigDiffInterface {
|
|||||||
use StringTranslationTrait;
|
use StringTranslationTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of elements to ignore when comparing config.
|
* List of elements to ignore on top level when comparing config.
|
||||||
*
|
*
|
||||||
* @var string[]
|
* @var string[]
|
||||||
*
|
*
|
||||||
@@ -46,7 +47,7 @@ class ConfigDiffer implements ConfigDiffInterface {
|
|||||||
* @param \Drupal\Core\StringTranslation\TranslationInterface $translation
|
* @param \Drupal\Core\StringTranslation\TranslationInterface $translation
|
||||||
* String translation service.
|
* String translation service.
|
||||||
* @param string[] $ignore
|
* @param string[] $ignore
|
||||||
* Config components to ignore.
|
* Config components to ignore at the top level.
|
||||||
* @param string $hierarchy_prefix
|
* @param string $hierarchy_prefix
|
||||||
* Prefix to use in diffs for array hierarchy.
|
* Prefix to use in diffs for array hierarchy.
|
||||||
* @param string $value_prefix
|
* @param string $value_prefix
|
||||||
@@ -62,9 +63,9 @@ class ConfigDiffer implements ConfigDiffInterface {
|
|||||||
/**
|
/**
|
||||||
* Normalizes config for comparison.
|
* Normalizes config for comparison.
|
||||||
*
|
*
|
||||||
* Recursively removes elements in the ignore list from configuration,
|
* Removes elements in the ignore list from the top level of configuration,
|
||||||
* as well as empty array values, and sorts at each level by array key, so
|
* and at each level of the array, removes empty arrays and sorts by array
|
||||||
* that config from different storage can be compared meaningfully.
|
* key, so that config from different storage can be compared meaningfully.
|
||||||
*
|
*
|
||||||
* @param array|null $config
|
* @param array|null $config
|
||||||
* Configuration array to normalize.
|
* Configuration array to normalize.
|
||||||
@@ -80,27 +81,40 @@ class ConfigDiffer implements ConfigDiffInterface {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove "ignore" elements.
|
// Remove "ignore" elements, only at the top level.
|
||||||
foreach ($this->ignore as $element) {
|
foreach ($this->ignore as $element) {
|
||||||
unset($config[$element]);
|
unset($config[$element]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively normalize remaining elements, if they are arrays.
|
// Recursively normalize and return.
|
||||||
foreach ($config as $key => $value) {
|
return $this->normalizeArray($config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively sorts an array by key, and removes empty arrays.
|
||||||
|
*
|
||||||
|
* @param array $array
|
||||||
|
* An array to normalize.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* An array that is sorted by key, at each level of the array, with empty
|
||||||
|
* arrays removed.
|
||||||
|
*/
|
||||||
|
protected function normalizeArray(array $array) {
|
||||||
|
foreach ($array as $key => $value) {
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
$new = $this->normalize($value);
|
$new = $this->normalizeArray($value);
|
||||||
if (count($new)) {
|
if (count($new)) {
|
||||||
$config[$key] = $new;
|
$array[$key] = $new;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unset($config[$key]);
|
unset($array[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort and return.
|
ksort($array);
|
||||||
ksort($config);
|
return $array;
|
||||||
return $config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,11 +171,8 @@ class ConfigDiffer implements ConfigDiffInterface {
|
|||||||
$lines[] = $line;
|
$lines[] = $line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elseif (is_null($value)) {
|
|
||||||
$lines[] = $section_prefix . $this->valuePrefix . $this->t('(NULL)');
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
$lines[] = $section_prefix . $this->valuePrefix . $value;
|
$lines[] = $section_prefix . $this->valuePrefix . Yaml::encode($value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class ConfigLister implements ConfigListInterface {
|
|||||||
|
|
||||||
// Calculate and return the list.
|
// Calculate and return the list.
|
||||||
foreach ($this->entityManager->getDefinitions() as $entity_type => $definition) {
|
foreach ($this->entityManager->getDefinitions() as $entity_type => $definition) {
|
||||||
if ($definition->isSubclassOf('Drupal\Core\Config\Entity\ConfigEntityInterface')) {
|
if ($definition->entityClassImplements('Drupal\Core\Config\Entity\ConfigEntityInterface')) {
|
||||||
$this->definitions[$entity_type] = $definition;
|
$this->definitions[$entity_type] = $definition;
|
||||||
$prefix = $definition->getConfigPrefix();
|
$prefix = $definition->getConfigPrefix();
|
||||||
$this->typesByPrefix[$prefix] = $entity_type;
|
$this->typesByPrefix[$prefix] = $entity_type;
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ interface ConfigRevertInterface {
|
|||||||
* The name of the config item, without the prefix.
|
* The name of the config item, without the prefix.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* The configuration value.
|
* The configuration value, or FALSE if it is not found.
|
||||||
*/
|
*/
|
||||||
public function getFromActive($type, $name);
|
public function getFromActive($type, $name);
|
||||||
|
|
||||||
|
|||||||
@@ -87,11 +87,15 @@ class ConfigReverter implements ConfigRevertInterface, ConfigDeleteInterface {
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function import($type, $name) {
|
public function import($type, $name) {
|
||||||
// Read the config from the file.
|
// Read the config from the file. Note: Do not call getFromExtension() here
|
||||||
|
// because we need $full_name below.
|
||||||
$full_name = $this->getFullName($type, $name);
|
$full_name = $this->getFullName($type, $name);
|
||||||
$value = $this->extensionConfigStorage->read($full_name);
|
$value = FALSE;
|
||||||
if (!$value) {
|
if ($full_name) {
|
||||||
$value = $this->extensionOptionalConfigStorage->read($full_name);
|
$value = $this->extensionConfigStorage->read($full_name);
|
||||||
|
if (!$value) {
|
||||||
|
$value = $this->extensionOptionalConfigStorage->read($full_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!$value) {
|
if (!$value) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -118,36 +122,44 @@ class ConfigReverter implements ConfigRevertInterface, ConfigDeleteInterface {
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function revert($type, $name) {
|
public function revert($type, $name) {
|
||||||
// Read the config from the file.
|
// Read the config from the file. Note: Do not call getFromExtension() here
|
||||||
|
// because we need $full_name below.
|
||||||
|
$value = FALSE;
|
||||||
$full_name = $this->getFullName($type, $name);
|
$full_name = $this->getFullName($type, $name);
|
||||||
$value = $this->extensionConfigStorage->read($full_name);
|
if ($full_name) {
|
||||||
if (!$value) {
|
$value = $this->extensionConfigStorage->read($full_name);
|
||||||
$value = $this->extensionOptionalConfigStorage->read($full_name);
|
if (!$value) {
|
||||||
|
$value = $this->extensionOptionalConfigStorage->read($full_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!$value) {
|
if (!$value) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the configuration exists currently in active storage.
|
||||||
|
if (!$this->activeConfigStorage->read($full_name)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the current config and replace the value, retaining the config
|
||||||
|
// hash (which is part of the _core config key's value).
|
||||||
if ($type == 'system.simple') {
|
if ($type == 'system.simple') {
|
||||||
// Load the current config and replace the value, retaining the config
|
|
||||||
// hash (which is part of the _core config key's value).
|
|
||||||
$config = $this->configFactory->getEditable($full_name);
|
$config = $this->configFactory->getEditable($full_name);
|
||||||
$core = $config->get('_core');
|
$core = $config->get('_core');
|
||||||
$config->setData($value);
|
$config
|
||||||
$config->set('_core', $core);
|
->setData($value)
|
||||||
$config->save();
|
->set('_core', $core)
|
||||||
|
->save();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Load the current config entity and replace the value. Note that
|
|
||||||
// the uuid and _core/hash values are retained for entity-based config,
|
|
||||||
// since updateFromStorageRecord() only updates values that are part of
|
|
||||||
// the passed-in array, and doesn't remove or alter other values.
|
|
||||||
$definition = $this->entityManager->getDefinition($type);
|
$definition = $this->entityManager->getDefinition($type);
|
||||||
$id_key = $definition->getKey('id');
|
$id_key = $definition->getKey('id');
|
||||||
$id = $value[$id_key];
|
$id = $value[$id_key];
|
||||||
$entity_storage = $this->entityManager->getStorage($type);
|
$entity_storage = $this->entityManager->getStorage($type);
|
||||||
$entity = $entity_storage->load($id);
|
$entity = $entity_storage->load($id);
|
||||||
|
$core = $entity->get('_core');
|
||||||
$entity = $entity_storage->updateFromStorageRecord($entity, $value);
|
$entity = $entity_storage->updateFromStorageRecord($entity, $value);
|
||||||
|
$entity->set('_core', $core);
|
||||||
$entity->save();
|
$entity->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,11 +174,15 @@ class ConfigReverter implements ConfigRevertInterface, ConfigDeleteInterface {
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function delete($type, $name) {
|
public function delete($type, $name) {
|
||||||
|
$config = FALSE;
|
||||||
$full_name = $this->getFullName($type, $name);
|
$full_name = $this->getFullName($type, $name);
|
||||||
if (!$full_name) {
|
if ($full_name) {
|
||||||
return FALSE;
|
// Make sure the configuration exists currently in active storage.
|
||||||
|
if (!$this->activeConfigStorage->read($full_name)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
$config = $this->configFactory->getEditable($full_name);
|
||||||
}
|
}
|
||||||
$config = $this->configFactory->getEditable($full_name);
|
|
||||||
if (!$config) {
|
if (!$config) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -183,17 +199,23 @@ class ConfigReverter implements ConfigRevertInterface, ConfigDeleteInterface {
|
|||||||
*/
|
*/
|
||||||
public function getFromActive($type, $name) {
|
public function getFromActive($type, $name) {
|
||||||
$full_name = $this->getFullName($type, $name);
|
$full_name = $this->getFullName($type, $name);
|
||||||
return $this->activeConfigStorage->read($full_name);
|
if ($full_name) {
|
||||||
|
return $this->activeConfigStorage->read($full_name);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function getFromExtension($type, $name) {
|
public function getFromExtension($type, $name) {
|
||||||
|
$value = FALSE;
|
||||||
$full_name = $this->getFullName($type, $name);
|
$full_name = $this->getFullName($type, $name);
|
||||||
$value = $this->extensionConfigStorage->read($full_name);
|
if ($full_name) {
|
||||||
if (!$value) {
|
$value = $this->extensionConfigStorage->read($full_name);
|
||||||
$value = $this->extensionOptionalConfigStorage->read($full_name);
|
if (!$value) {
|
||||||
|
$value = $this->extensionOptionalConfigStorage->read($full_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
@@ -207,7 +229,7 @@ class ConfigReverter implements ConfigRevertInterface, ConfigDeleteInterface {
|
|||||||
* The config name, without prefix.
|
* The config name, without prefix.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
* The config item's full name.
|
* The config item's full name, or FALSE if there is an error.
|
||||||
*/
|
*/
|
||||||
protected function getFullName($type, $name) {
|
protected function getFullName($type, $name) {
|
||||||
if ($type == 'system.simple' || !$type) {
|
if ($type == 'system.simple' || !$type) {
|
||||||
@@ -215,8 +237,13 @@ class ConfigReverter implements ConfigRevertInterface, ConfigDeleteInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$definition = $this->entityManager->getDefinition($type);
|
$definition = $this->entityManager->getDefinition($type);
|
||||||
$prefix = $definition->getConfigPrefix() . '.';
|
if ($definition) {
|
||||||
return $prefix . $name;
|
$prefix = $definition->getConfigPrefix() . '.';
|
||||||
|
return $prefix . $name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace Drupal\Tests\config_update\Unit;
|
namespace Drupal\Tests\config_update\Unit;
|
||||||
|
|
||||||
use Drupal\config_update\ConfigDiffer;
|
use Drupal\config_update\ConfigDiffer;
|
||||||
use Drupal\Tests\UnitTestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the \Drupal\config_update\ConfigDiffer class.
|
* Tests the \Drupal\config_update\ConfigDiffer class.
|
||||||
@@ -12,14 +11,7 @@ use Drupal\Tests\UnitTestCase;
|
|||||||
*
|
*
|
||||||
* @coversDefaultClass \Drupal\config_update\ConfigDiffer
|
* @coversDefaultClass \Drupal\config_update\ConfigDiffer
|
||||||
*/
|
*/
|
||||||
class ConfigDifferTest extends UnitTestCase {
|
class ConfigDifferTest extends ConfigUpdateUnitTestBase {
|
||||||
|
|
||||||
/**
|
|
||||||
* The mock translation object.
|
|
||||||
*
|
|
||||||
* @var \Drupal\Core\StringTranslation\TranslationInterface
|
|
||||||
*/
|
|
||||||
protected $stringTranslation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The config differ to test.
|
* The config differ to test.
|
||||||
@@ -32,12 +24,7 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
$this->stringTranslation = $this->getMockBuilder('Drupal\Core\StringTranslation\TranslationInterface')->getMock();
|
$this->configDiffer = new ConfigDiffer($this->getTranslationMock());
|
||||||
$this->stringTranslation
|
|
||||||
->method('t')
|
|
||||||
->will($this->returnArgument(0));
|
|
||||||
|
|
||||||
$this->configDiffer = new ConfigDiffer($this->stringTranslation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,13 +46,14 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
'c' => [
|
'c' => [
|
||||||
'd' => TRUE,
|
'd' => TRUE,
|
||||||
'e' => FALSE,
|
'e' => FALSE,
|
||||||
|
'empty' => [],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
[$base, $base, TRUE],
|
[$base, $base, TRUE],
|
||||||
|
|
||||||
// Add _core, omit uuid. Should match.
|
// Add _core, omit uuid at top level. Should match, as both are removed
|
||||||
|
// in normalization process.
|
||||||
[
|
[
|
||||||
$base,
|
$base,
|
||||||
[
|
[
|
||||||
@@ -75,27 +63,30 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
'c' => [
|
'c' => [
|
||||||
'd' => TRUE,
|
'd' => TRUE,
|
||||||
'e' => FALSE,
|
'e' => FALSE,
|
||||||
|
'empty' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
TRUE,
|
TRUE,
|
||||||
],
|
],
|
||||||
|
|
||||||
// Change order. Should match.
|
// Change order in top and deep level. Should match.
|
||||||
[
|
[
|
||||||
$base,
|
$base,
|
||||||
[
|
[
|
||||||
'a' => 'a',
|
|
||||||
'uuid' => 'bar',
|
'uuid' => 'bar',
|
||||||
'b' => 0,
|
'b' => 0,
|
||||||
|
'a' => 'a',
|
||||||
'c' => [
|
'c' => [
|
||||||
'd' => TRUE,
|
|
||||||
'e' => FALSE,
|
'e' => FALSE,
|
||||||
|
'empty' => [],
|
||||||
|
'd' => TRUE,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
TRUE,
|
TRUE,
|
||||||
],
|
],
|
||||||
|
|
||||||
// Change order and add _core in deeper level. Should match.
|
// Add _core in deeper level. Should not match, as this is removed
|
||||||
|
// only at the top level during normalization.
|
||||||
[
|
[
|
||||||
$base,
|
$base,
|
||||||
[
|
[
|
||||||
@@ -103,12 +94,31 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
'a' => 'a',
|
'a' => 'a',
|
||||||
'b' => 0,
|
'b' => 0,
|
||||||
'c' => [
|
'c' => [
|
||||||
'e' => FALSE,
|
'_core' => 'do-not-use-this-key',
|
||||||
'_core' => 'foo',
|
|
||||||
'd' => TRUE,
|
'd' => TRUE,
|
||||||
|
'e' => FALSE,
|
||||||
|
'empty' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
TRUE,
|
FALSE,
|
||||||
|
],
|
||||||
|
|
||||||
|
// Add uuid in deeper level. Should not match, as this is removed
|
||||||
|
// only at the top level during normalization.
|
||||||
|
[
|
||||||
|
$base,
|
||||||
|
[
|
||||||
|
'uuid' => 'bar',
|
||||||
|
'a' => 'a',
|
||||||
|
'b' => 0,
|
||||||
|
'c' => [
|
||||||
|
'd' => TRUE,
|
||||||
|
'e' => FALSE,
|
||||||
|
'uuid' => 'important',
|
||||||
|
'empty' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
FALSE,
|
||||||
],
|
],
|
||||||
|
|
||||||
// Omit a component. Should not match.
|
// Omit a component. Should not match.
|
||||||
@@ -120,6 +130,7 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
'c' => [
|
'c' => [
|
||||||
'd' => TRUE,
|
'd' => TRUE,
|
||||||
'e' => FALSE,
|
'e' => FALSE,
|
||||||
|
'empty' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
FALSE,
|
FALSE,
|
||||||
@@ -135,6 +146,7 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
'c' => [
|
'c' => [
|
||||||
'd' => TRUE,
|
'd' => TRUE,
|
||||||
'e' => FALSE,
|
'e' => FALSE,
|
||||||
|
'empty' => [],
|
||||||
],
|
],
|
||||||
'f' => 'f',
|
'f' => 'f',
|
||||||
],
|
],
|
||||||
@@ -152,6 +164,24 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
'c' => [
|
'c' => [
|
||||||
'd' => TRUE,
|
'd' => TRUE,
|
||||||
'e' => FALSE,
|
'e' => FALSE,
|
||||||
|
'empty' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
FALSE,
|
||||||
|
],
|
||||||
|
|
||||||
|
// 0 should not match NULL.
|
||||||
|
[
|
||||||
|
$base,
|
||||||
|
[
|
||||||
|
'_core' => 'foo',
|
||||||
|
'uuid' => 'bar',
|
||||||
|
'a' => 'a',
|
||||||
|
'b' => NULL,
|
||||||
|
'c' => [
|
||||||
|
'd' => TRUE,
|
||||||
|
'e' => FALSE,
|
||||||
|
'empty' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
FALSE,
|
FALSE,
|
||||||
@@ -168,6 +198,7 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
'c' => [
|
'c' => [
|
||||||
'd' => TRUE,
|
'd' => TRUE,
|
||||||
'e' => 'e',
|
'e' => 'e',
|
||||||
|
'empty' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
FALSE,
|
FALSE,
|
||||||
@@ -184,10 +215,29 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
'c' => [
|
'c' => [
|
||||||
'd' => 'd',
|
'd' => 'd',
|
||||||
'e' => FALSE,
|
'e' => FALSE,
|
||||||
|
'empty' => [],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
FALSE,
|
FALSE,
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// Add an empty array at top, and remove at lower level. Should still
|
||||||
|
// match.
|
||||||
|
[
|
||||||
|
$base,
|
||||||
|
[
|
||||||
|
'_core' => 'foo',
|
||||||
|
'uuid' => 'bar',
|
||||||
|
'a' => 'a',
|
||||||
|
'b' => 0,
|
||||||
|
'c' => [
|
||||||
|
'd' => TRUE,
|
||||||
|
'e' => FALSE,
|
||||||
|
],
|
||||||
|
'empty_two' => [],
|
||||||
|
],
|
||||||
|
TRUE,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,6 +251,7 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
'id_to_remove' => 'test.remove.id',
|
'id_to_remove' => 'test.remove.id',
|
||||||
'type' => 'old_type',
|
'type' => 'old_type',
|
||||||
'true_value' => TRUE,
|
'true_value' => TRUE,
|
||||||
|
'null_value' => NULL,
|
||||||
'nested_array' => [
|
'nested_array' => [
|
||||||
'flat_array' => [
|
'flat_array' => [
|
||||||
'value2',
|
'value2',
|
||||||
@@ -216,6 +267,7 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
'id' => 'test.config.id',
|
'id' => 'test.config.id',
|
||||||
'type' => 'new_type',
|
'type' => 'new_type',
|
||||||
'true_value' => FALSE,
|
'true_value' => FALSE,
|
||||||
|
'null_value' => FALSE,
|
||||||
'nested_array' => [
|
'nested_array' => [
|
||||||
'flat_array' => [
|
'flat_array' => [
|
||||||
'value2',
|
'value2',
|
||||||
@@ -284,12 +336,14 @@ class ConfigDifferTest extends UnitTestCase {
|
|||||||
'orig' => [
|
'orig' => [
|
||||||
'nested_array::flat_array::1 : value1',
|
'nested_array::flat_array::1 : value1',
|
||||||
'nested_array::flat_array::2 : value3',
|
'nested_array::flat_array::2 : value3',
|
||||||
'true_value : 1',
|
'null_value : null',
|
||||||
|
'true_value : true',
|
||||||
'type : old_type',
|
'type : old_type',
|
||||||
],
|
],
|
||||||
'closing' => [
|
'closing' => [
|
||||||
'nested_array::flat_array::1 : value3',
|
'nested_array::flat_array::1 : value3',
|
||||||
'true_value : ',
|
'null_value : false',
|
||||||
|
'true_value : false',
|
||||||
'type : new_type',
|
'type : new_type',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|||||||
+177
-149
@@ -2,169 +2,73 @@
|
|||||||
|
|
||||||
namespace Drupal\Tests\config_update\Unit;
|
namespace Drupal\Tests\config_update\Unit;
|
||||||
|
|
||||||
use Drupal\config_update\ConfigLister;
|
|
||||||
use Drupal\Tests\UnitTestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the \Drupal\config_update\ConfigLister class.
|
* Tests the \Drupal\config_update\ConfigListerWithProviders class.
|
||||||
|
*
|
||||||
|
* The methods from \Drupal\config_update\ConfigLister are also tested.
|
||||||
*
|
*
|
||||||
* @group config_update
|
* @group config_update
|
||||||
*
|
*
|
||||||
* @coversDefaultClass \Drupal\config_update\ConfigLister
|
* @coversDefaultClass \Drupal\config_update\ConfigListerWithProviders
|
||||||
*/
|
*/
|
||||||
class ConfigListerTest extends UnitTestCase {
|
class ConfigListerTest extends ConfigUpdateUnitTestBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The config lister to test.
|
* The config lister to test.
|
||||||
*
|
*
|
||||||
* @var \Drupal\config_update\ConfigLister
|
* @var \Drupal\config_update\ConfigListerWithProviders
|
||||||
*/
|
*/
|
||||||
protected $configLister;
|
protected $configLister;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The mocked entity definition information.
|
* List of configuration by provider in the mocks.
|
||||||
*
|
*
|
||||||
* @var string[]
|
* This is an array whose keys are provider names, and whose values are
|
||||||
|
* each an array containing the provider type, the name of one config item
|
||||||
|
* mocked to be in config/install, and one in config/optional.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $entityDefinitionInformation;
|
protected $configProviderList = [
|
||||||
|
'foo_module' => ['module', 'foo.barbaz.one', 'foo.barbaz.two'],
|
||||||
|
'foo_theme' => ['theme', 'foo.bar.one', 'foo.bar.two'],
|
||||||
|
'standard' => ['profile', 'baz.bar.one', 'baz.bar.two'],
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
$this->configLister = new ConfigLister($this->getEntityManagerMock(), $this->getConfigStorageMock('active'), $this->getConfigStorageMock('extension'), $this->getConfigStorageMock('optional'));
|
$lister = $this->getMockBuilder('Drupal\config_update\ConfigListerWithProviders')
|
||||||
|
->setConstructorArgs([
|
||||||
|
$this->getEntityManagerMock(),
|
||||||
|
$this->getConfigStorageMock('active'),
|
||||||
|
$this->getConfigStorageMock('extension'),
|
||||||
|
$this->getConfigStorageMock('optional'),
|
||||||
|
$this->getModuleHandlerMock(),
|
||||||
|
$this->getThemeHandlerMock(),
|
||||||
|
])
|
||||||
|
->setMethods(['listProvidedItems', 'getProfileName'])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$lister->method('getProfileName')
|
||||||
|
->willReturn('standard');
|
||||||
|
|
||||||
|
$map = [];
|
||||||
|
foreach ($this->configProviderList as $provider => $info) {
|
||||||
|
// Info has: [type, install storage item, optional storage item].
|
||||||
|
// Map needs: [type, provider name, isOptional, [config items]].
|
||||||
|
$map[] = [$info[0], $provider, FALSE, [$info[1]]];
|
||||||
|
$map[] = [$info[0], $provider, TRUE, [$info[2]]];
|
||||||
|
}
|
||||||
|
$lister->method('listProvidedItems')
|
||||||
|
->will($this->returnValueMap($map));
|
||||||
|
|
||||||
|
$this->configLister = $lister;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a mock entity manager for the test.
|
* @covers \Drupal\config_update\ConfigListerWithProviders::listConfig
|
||||||
*/
|
|
||||||
protected function getEntityManagerMock() {
|
|
||||||
// Make a list of fake entity definitions. Make sure they are not sorted,
|
|
||||||
// to test that the methods sort them. Also make sure there are a couple
|
|
||||||
// with prefixes that are subsets of each other.
|
|
||||||
$this->entityDefinitionInformation = [
|
|
||||||
['prefix' => 'foo.bar', 'type' => 'foo'],
|
|
||||||
['prefix' => 'foo.barbaz', 'type' => 'bar'],
|
|
||||||
['prefix' => 'baz.foo', 'type' => 'baz'],
|
|
||||||
];
|
|
||||||
|
|
||||||
$definitions = [];
|
|
||||||
foreach ($this->entityDefinitionInformation as $info) {
|
|
||||||
$def = $this->getMockBuilder('Drupal\Core\Config\Entity\ConfigEntityTypeInterface')->getMock();
|
|
||||||
$def
|
|
||||||
->expects($this->any())
|
|
||||||
->method('getConfigPrefix')
|
|
||||||
->willReturn($info['prefix']);
|
|
||||||
$def
|
|
||||||
->expects($this->any())
|
|
||||||
->method('isSubclassOf')
|
|
||||||
->willReturn(TRUE);
|
|
||||||
|
|
||||||
$def->getConfigPrefix();
|
|
||||||
|
|
||||||
$definitions[$info['type']] = $def;
|
|
||||||
}
|
|
||||||
|
|
||||||
$manager = $this->getMockBuilder('Drupal\Core\Entity\EntityTypeManagerInterface')->getMock();
|
|
||||||
$manager
|
|
||||||
->method('getDefinitions')
|
|
||||||
->willReturn($definitions);
|
|
||||||
|
|
||||||
return($manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a mock config storage object for the test.
|
|
||||||
*
|
|
||||||
* @param string $type
|
|
||||||
* Type of storage object to return: 'active', 'extension', or 'optional'.
|
|
||||||
*/
|
|
||||||
protected function getConfigStorageMock($type) {
|
|
||||||
if ($type == 'active') {
|
|
||||||
$storage = $this->getMockBuilder('Drupal\Core\Config\StorageInterface')->getMock();
|
|
||||||
|
|
||||||
// The only use of the read() method on active storage is
|
|
||||||
// with the core.extension config, to get the profile name.
|
|
||||||
$storage
|
|
||||||
->method('read')
|
|
||||||
->willReturn(['profile' => 'standard']);
|
|
||||||
|
|
||||||
$map = [
|
|
||||||
['foo.bar', ['foo.bar.one', 'foo.bar.two', 'foo.bar.three']],
|
|
||||||
['foo.barbaz', ['foo.barbaz.four', 'foo.barbaz.five', 'foo.barbaz.six']],
|
|
||||||
['baz.foo'], [],
|
|
||||||
['',
|
|
||||||
[
|
|
||||||
'foo.bar.one',
|
|
||||||
'foo.bar.two',
|
|
||||||
'foo.bar.three',
|
|
||||||
'foo.barbaz.four',
|
|
||||||
'foo.barbaz.five',
|
|
||||||
'foo.barbaz.six',
|
|
||||||
'something.else',
|
|
||||||
'another.one',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
$storage
|
|
||||||
->method('listAll')
|
|
||||||
->will($this->returnValueMap($map));
|
|
||||||
}
|
|
||||||
elseif ($type == 'extension') {
|
|
||||||
$storage = $this->getMockBuilder('Drupal\Core\Config\ExtensionInstallStorage')->disableOriginalConstructor()->getMock();
|
|
||||||
$storage
|
|
||||||
->method('getComponentNames')
|
|
||||||
->willReturn([
|
|
||||||
'foo.bar.one' => 'ignored',
|
|
||||||
'foo.bar.two' => 'ignored',
|
|
||||||
'foo.bar.seven' => 'ignored',
|
|
||||||
'foo.barnot.three' => 'ignored',
|
|
||||||
'something.else' => 'ignored',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$map = [
|
|
||||||
['foo.bar', ['foo.bar.one', 'foo.bar.two', 'foo.bar.seven']],
|
|
||||||
['baz.foo'], [],
|
|
||||||
['',
|
|
||||||
[
|
|
||||||
'foo.bar.one',
|
|
||||||
'foo.bar.two',
|
|
||||||
'foo.bar.seven',
|
|
||||||
'foo.barbaz.four',
|
|
||||||
'foo.barnot.three',
|
|
||||||
'something.else',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
$storage
|
|
||||||
->method('listAll')
|
|
||||||
->will($this->returnValueMap($map));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$storage = $this->getMockBuilder('Drupal\Core\Config\ExtensionInstallStorage')->disableOriginalConstructor()->getMock();
|
|
||||||
$storage
|
|
||||||
->method('getComponentNames')
|
|
||||||
->willReturn([
|
|
||||||
'foo.barbaz.four' => 'ignored',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$map = [
|
|
||||||
['foo.bar'], [],
|
|
||||||
['foo.barbaz', ['foo.barbaz.four']],
|
|
||||||
['', ['foo.barbaz.four']],
|
|
||||||
];
|
|
||||||
$storage
|
|
||||||
->method('listAll')
|
|
||||||
->will($this->returnValueMap($map));
|
|
||||||
}
|
|
||||||
return $storage;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @covers \Drupal\config_update\ConfigLister::listConfig
|
|
||||||
* @dataProvider listConfigProvider
|
* @dataProvider listConfigProvider
|
||||||
*/
|
*/
|
||||||
public function testListConfig($a, $b, $expected) {
|
public function testListConfig($a, $b, $expected) {
|
||||||
@@ -176,12 +80,8 @@ class ConfigListerTest extends UnitTestCase {
|
|||||||
*/
|
*/
|
||||||
public function listConfigProvider() {
|
public function listConfigProvider() {
|
||||||
return [
|
return [
|
||||||
// Arguments are $list_type, $name.
|
// Arguments are $list_type, $name, and return value is that list of
|
||||||
// We cannot really test the extension types here, because they rely
|
// configuration in active, extension, and optional storage.
|
||||||
// on the going out to the file system to find out what config objects
|
|
||||||
// are there. This is too complex to mock. It is tested in the tests for
|
|
||||||
// the report output in the config_update_ui module tests. Anyway, we
|
|
||||||
// can test the other types.
|
|
||||||
['type', 'system.all',
|
['type', 'system.all',
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
@@ -220,11 +120,59 @@ class ConfigListerTest extends UnitTestCase {
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
['type', 'unknown.type', [[], [], []]],
|
['type', 'unknown.type', [[], [], []]],
|
||||||
|
['profile', 'dummy',
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'foo.bar.one',
|
||||||
|
'foo.bar.two',
|
||||||
|
'foo.bar.three',
|
||||||
|
'foo.barbaz.four',
|
||||||
|
'foo.barbaz.five',
|
||||||
|
'foo.barbaz.six',
|
||||||
|
'something.else',
|
||||||
|
'another.one',
|
||||||
|
],
|
||||||
|
['baz.bar.one'],
|
||||||
|
['baz.bar.two'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
['module', 'foo_module',
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'foo.bar.one',
|
||||||
|
'foo.bar.two',
|
||||||
|
'foo.bar.three',
|
||||||
|
'foo.barbaz.four',
|
||||||
|
'foo.barbaz.five',
|
||||||
|
'foo.barbaz.six',
|
||||||
|
'something.else',
|
||||||
|
'another.one',
|
||||||
|
],
|
||||||
|
['foo.barbaz.one'],
|
||||||
|
['foo.barbaz.two'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
['theme', 'foo_theme',
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'foo.bar.one',
|
||||||
|
'foo.bar.two',
|
||||||
|
'foo.bar.three',
|
||||||
|
'foo.barbaz.four',
|
||||||
|
'foo.barbaz.five',
|
||||||
|
'foo.barbaz.six',
|
||||||
|
'something.else',
|
||||||
|
'another.one',
|
||||||
|
],
|
||||||
|
['foo.bar.one'],
|
||||||
|
['foo.bar.two'],
|
||||||
|
],
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \Drupal\config_update\ConfigLister::getType
|
* @covers \Drupal\config_update\ConfigListerWithProviders::getType
|
||||||
*/
|
*/
|
||||||
public function testGetType() {
|
public function testGetType() {
|
||||||
$return = $this->configLister->getType('not_in_list');
|
$return = $this->configLister->getType('not_in_list');
|
||||||
@@ -237,7 +185,7 @@ class ConfigListerTest extends UnitTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \Drupal\config_update\ConfigLister::getTypeByPrefix
|
* @covers \Drupal\config_update\ConfigListerWithProviders::getTypeByPrefix
|
||||||
*/
|
*/
|
||||||
public function testGetTypeByPrefix() {
|
public function testGetTypeByPrefix() {
|
||||||
$return = $this->configLister->getTypeByPrefix('not_in_list');
|
$return = $this->configLister->getTypeByPrefix('not_in_list');
|
||||||
@@ -250,7 +198,7 @@ class ConfigListerTest extends UnitTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @covers \Drupal\config_update\ConfigLister::getTypeNameByConfigName
|
* @covers \Drupal\config_update\ConfigListerWithProviders::getTypeNameByConfigName
|
||||||
*/
|
*/
|
||||||
public function testGetTypeNameByConfigName() {
|
public function testGetTypeNameByConfigName() {
|
||||||
$return = $this->configLister->getTypeNameByConfigName('not_in_list');
|
$return = $this->configLister->getTypeNameByConfigName('not_in_list');
|
||||||
@@ -262,4 +210,84 @@ class ConfigListerTest extends UnitTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Drupal\config_update\ConfigListerWithProviders::listTypes
|
||||||
|
*/
|
||||||
|
public function testListTypes() {
|
||||||
|
$return = $this->configLister->listTypes();
|
||||||
|
// Should return an array in sorted order, of just the config entities
|
||||||
|
// that $this->getEntityManagerMock() set up.
|
||||||
|
$expected = ['bar' => 'foo.barbaz', 'baz' => 'baz.foo', 'foo' => 'foo.bar'];
|
||||||
|
$this->assertEquals(array_keys($return), array_keys($expected));
|
||||||
|
foreach ($return as $key => $definition) {
|
||||||
|
$this->assertTrue($definition->entityClassImplements('Drupal\Core\Config\Entity\ConfigEntityInterface'));
|
||||||
|
$this->assertEquals($definition->getConfigPrefix(), $expected[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Drupal\config_update\ConfigListerWithProviders::listProviders
|
||||||
|
*/
|
||||||
|
public function testListProviders() {
|
||||||
|
// This method's return value is not sorted in any particular way.
|
||||||
|
$return = $this->configLister->listProviders();
|
||||||
|
$expected = [];
|
||||||
|
foreach ($this->configProviderList as $provider => $info) {
|
||||||
|
// Info has: [type, install storage item, optional storage item].
|
||||||
|
// Expected needs: key is item name, value is [type, provider name].
|
||||||
|
$expected[$info[1]] = [$info[0], $provider];
|
||||||
|
$expected[$info[2]] = [$info[0], $provider];
|
||||||
|
}
|
||||||
|
ksort($return);
|
||||||
|
ksort($expected);
|
||||||
|
$this->assertEquals($return, $expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Drupal\config_update\ConfigListerWithProviders::getConfigProvider
|
||||||
|
* @dataProvider getConfigProviderProvider
|
||||||
|
*/
|
||||||
|
public function testGetConfigProvider($a, $expected) {
|
||||||
|
$this->assertEquals($expected, $this->configLister->getConfigProvider($a));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for self:testGetConfigProvider().
|
||||||
|
*/
|
||||||
|
public function getConfigProviderProvider() {
|
||||||
|
$values = [];
|
||||||
|
foreach ($this->configProviderList as $provider => $info) {
|
||||||
|
// Info has: [type, install storage item, optional storage item].
|
||||||
|
// Values needs: [item, [type, provider name]].
|
||||||
|
$values[] = [$info[1], [$info[0], $provider]];
|
||||||
|
$values[] = [$info[2], [$info[0], $provider]];
|
||||||
|
}
|
||||||
|
$values[] = ['not.a.config.item', NULL];
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Drupal\config_update\ConfigListerWithProviders::providerHasConfig
|
||||||
|
* @dataProvider providerHasConfigProvider
|
||||||
|
*/
|
||||||
|
public function testProviderHasConfig($a, $b, $expected) {
|
||||||
|
$this->assertEquals($expected, $this->configLister->providerHasConfig($a, $b));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for self:testProviderHasConfig().
|
||||||
|
*/
|
||||||
|
public function providerHasConfigProvider() {
|
||||||
|
$values = [];
|
||||||
|
foreach ($this->configProviderList as $provider => $info) {
|
||||||
|
// Info has: [type, install storage item, optional storage item].
|
||||||
|
// Values needs: [type, provider name, TRUE] for valid providers,
|
||||||
|
// change the last to FALSE for invalid providers.
|
||||||
|
$values[] = [$info[0], $provider, TRUE];
|
||||||
|
$values[] = [$info[0], $provider . '_suffix', FALSE];
|
||||||
|
}
|
||||||
|
$values[] = ['invalid_type', 'foo_module', FALSE];
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,356 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\config_update\Unit;
|
||||||
|
|
||||||
|
use Drupal\config_update\ConfigReverter;
|
||||||
|
use Drupal\config_update\ConfigRevertInterface;
|
||||||
|
use Drupal\config_update\ConfigDeleteInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the \Drupal\config_update\ConfigReverter class.
|
||||||
|
*
|
||||||
|
* @group config_update
|
||||||
|
*
|
||||||
|
* @coversDefaultClass \Drupal\config_update\ConfigReverter
|
||||||
|
*/
|
||||||
|
class ConfigReverterTest extends ConfigUpdateUnitTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The config reverter to test.
|
||||||
|
*
|
||||||
|
* @var \Drupal\config_update\ConfigReverter
|
||||||
|
*/
|
||||||
|
protected $configReverter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function setUp() {
|
||||||
|
$this->configReverter = new ConfigReverter(
|
||||||
|
$this->getEntityManagerMock(),
|
||||||
|
$this->getConfigStorageMock('active'),
|
||||||
|
$this->getConfigStorageMock('extension'),
|
||||||
|
$this->getConfigStorageMock('optional'),
|
||||||
|
$this->getConfigFactoryMock(),
|
||||||
|
$this->getEventDispatcherMock());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Drupal\config_update\ConfigReverter::getFromActive
|
||||||
|
* @dataProvider getFromActiveProvider
|
||||||
|
*/
|
||||||
|
public function testGetFromActive($a, $b, $expected) {
|
||||||
|
$this->assertEquals($expected, $this->configReverter->getFromActive($a, $b));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for self:testGetFromActive().
|
||||||
|
*/
|
||||||
|
public function getFromActiveProvider() {
|
||||||
|
return [
|
||||||
|
// Arguments are $type, $name, and return value is the config.
|
||||||
|
// Some config items that are already prefixed.
|
||||||
|
['', 'foo.bar.one', ['foo.bar.one' => 'active', 'id' => 'one']],
|
||||||
|
['system.simple', 'foo.bar.one',
|
||||||
|
['foo.bar.one' => 'active', 'id' => 'one'],
|
||||||
|
],
|
||||||
|
// Config item with a defined entity definition prefix. Entity type 'foo'
|
||||||
|
// has prefix 'foo.bar'.
|
||||||
|
['foo', 'one', ['foo.bar.one' => 'active', 'id' => 'one']],
|
||||||
|
// Unknown type. This should not generate a call into the config read,
|
||||||
|
// so should not return the known value.
|
||||||
|
['unknown', 'foo.bar.one', FALSE],
|
||||||
|
// Missing configuration. Config mock is configured to return FALSE for
|
||||||
|
// this particular config name.
|
||||||
|
['system.simple', 'missing', FALSE],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Drupal\config_update\ConfigReverter::getFromExtension
|
||||||
|
* @dataProvider getFromExtensionProvider
|
||||||
|
*/
|
||||||
|
public function testGetFromExtension($a, $b, $expected) {
|
||||||
|
$this->assertEquals($expected, $this->configReverter->getFromExtension($a, $b));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for self:testGetFromExtension().
|
||||||
|
*/
|
||||||
|
public function getFromExtensionProvider() {
|
||||||
|
return [
|
||||||
|
// Arguments are $type, $name, and return value is the config.
|
||||||
|
// Some config items that are already prefixed, and exist in the mock
|
||||||
|
// extension storage.
|
||||||
|
['', 'in.extension', ['in.extension' => 'extension']],
|
||||||
|
['system.simple', 'in.extension', ['in.extension' => 'extension']],
|
||||||
|
// Config item with a defined entity definition prefix. Entity type 'foo'
|
||||||
|
// has prefix 'foo.bar'.
|
||||||
|
['foo', 'one', ['foo.bar.one' => 'extension', 'id' => 'one']],
|
||||||
|
// One that exists in both extension and optional storage.
|
||||||
|
['system.simple', 'in.both', ['in.both' => 'extension']],
|
||||||
|
// One that exists only in optional storage.
|
||||||
|
['system.simple', 'in.optional', ['in.optional' => 'optional']],
|
||||||
|
// Unknown type. This should not generate a call into the config read,
|
||||||
|
// so should not return the known value.
|
||||||
|
['unknown', 'in.extension', FALSE],
|
||||||
|
// Missing configuration. Storage mock is configured to return FALSE for
|
||||||
|
// this particular config name.
|
||||||
|
['system.simple', 'missing2', FALSE],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Drupal\config_update\ConfigReverter::import
|
||||||
|
* @dataProvider importProvider
|
||||||
|
*/
|
||||||
|
public function testImport($type, $name, $config_name, $expected, $config_before, $config_after) {
|
||||||
|
// Clear dispatch log and set pre-config.
|
||||||
|
$this->dispatchedEvents = [];
|
||||||
|
if ($config_name) {
|
||||||
|
$this->configStorage[$config_name] = $config_before;
|
||||||
|
}
|
||||||
|
$save_config = $this->configStorage;
|
||||||
|
|
||||||
|
// Call the importer and test the Boolean result.
|
||||||
|
$result = $this->configReverter->import($type, $name);
|
||||||
|
$this->assertEquals($result, $expected);
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
// Verify that the config is correct after import, and logging worked.
|
||||||
|
$this->assertEquals($this->configStorage[$config_name], $config_after);
|
||||||
|
$this->assertEquals(count($this->dispatchedEvents), 1);
|
||||||
|
$this->assertEquals($this->dispatchedEvents[0][0], ConfigRevertInterface::IMPORT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Verify that the config didn't change and no events were logged.
|
||||||
|
$this->assertEquals($this->configStorage, $save_config);
|
||||||
|
$this->assertEquals(count($this->dispatchedEvents), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for self:testImport().
|
||||||
|
*/
|
||||||
|
public function importProvider() {
|
||||||
|
return [
|
||||||
|
// Elements: type, name, config name, return value,
|
||||||
|
// config to set up before, config expected after. See also
|
||||||
|
// getFromExtensionProvider().
|
||||||
|
[
|
||||||
|
'system.simple',
|
||||||
|
'in.extension',
|
||||||
|
'in.extension',
|
||||||
|
TRUE,
|
||||||
|
['in.extension' => 'before'],
|
||||||
|
['in.extension' => 'extension', '_core' => 'core_for_in.extension'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'foo',
|
||||||
|
'one',
|
||||||
|
'foo.bar.one',
|
||||||
|
TRUE,
|
||||||
|
['foo.bar.one' => 'before', 'id' => 'one'],
|
||||||
|
[
|
||||||
|
'foo.bar.one' => 'extension',
|
||||||
|
'id' => 'one',
|
||||||
|
'_core' => 'core_for_foo.bar.one',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'system.simple',
|
||||||
|
'in.both',
|
||||||
|
'in.both',
|
||||||
|
TRUE,
|
||||||
|
['in.both' => 'before'],
|
||||||
|
['in.both' => 'extension', '_core' => 'core_for_in.both'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'system.simple',
|
||||||
|
'in.optional',
|
||||||
|
'in.optional',
|
||||||
|
TRUE,
|
||||||
|
['in.optional' => 'before'],
|
||||||
|
['in.optional' => 'optional', '_core' => 'core_for_in.optional'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'unknown',
|
||||||
|
'in.extension',
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'system.simple',
|
||||||
|
'missing2',
|
||||||
|
'missing2',
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Drupal\config_update\ConfigReverter::revert
|
||||||
|
* @dataProvider revertProvider
|
||||||
|
*/
|
||||||
|
public function testRevert($type, $name, $config_name, $expected, $config_before, $config_after) {
|
||||||
|
// Clear dispatch log and set pre-config.
|
||||||
|
$this->dispatchedEvents = [];
|
||||||
|
if ($config_name) {
|
||||||
|
$this->configStorage[$config_name] = $config_before;
|
||||||
|
}
|
||||||
|
$save_config = $this->configStorage;
|
||||||
|
|
||||||
|
// Call the reverter and test the Boolean result.
|
||||||
|
$result = $this->configReverter->revert($type, $name);
|
||||||
|
$this->assertEquals($result, $expected);
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
// Verify that the config is correct after revert, and logging worked.
|
||||||
|
$this->assertEquals($this->configStorage[$config_name], $config_after);
|
||||||
|
$this->assertEquals(count($this->dispatchedEvents), 1);
|
||||||
|
$this->assertEquals($this->dispatchedEvents[0][0], ConfigRevertInterface::REVERT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Verify that the config didn't change and no events were logged.
|
||||||
|
$this->assertEquals($this->configStorage, $save_config);
|
||||||
|
$this->assertEquals(count($this->dispatchedEvents), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for self:testRevert().
|
||||||
|
*/
|
||||||
|
public function revertProvider() {
|
||||||
|
return [
|
||||||
|
// Elements: type, name, config name, return value,
|
||||||
|
// config to set up before, config expected after. See also
|
||||||
|
// getFromExtensionProvider().
|
||||||
|
[
|
||||||
|
'system.simple',
|
||||||
|
'in.extension',
|
||||||
|
'in.extension',
|
||||||
|
TRUE,
|
||||||
|
['in.extension' => 'active'],
|
||||||
|
['in.extension' => 'extension', '_core' => 'core_for_in.extension'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'foo',
|
||||||
|
'one',
|
||||||
|
'foo.bar.one',
|
||||||
|
TRUE,
|
||||||
|
['foo.bar.one' => 'active', 'id' => 'one'],
|
||||||
|
[
|
||||||
|
'foo.bar.one' => 'extension',
|
||||||
|
'id' => 'one',
|
||||||
|
'_core' => 'core_for_foo.bar.one',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'system.simple',
|
||||||
|
'in.both',
|
||||||
|
'in.both',
|
||||||
|
TRUE,
|
||||||
|
['in.both' => 'active'],
|
||||||
|
['in.both' => 'extension', '_core' => 'core_for_in.both'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'system.simple',
|
||||||
|
'in.optional',
|
||||||
|
'in.optional',
|
||||||
|
TRUE,
|
||||||
|
['in.optional' => 'active'],
|
||||||
|
['in.optional' => 'optional', '_core' => 'core_for_in.optional'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'unknown',
|
||||||
|
'in.extension',
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
],
|
||||||
|
// Missing from extension storage.
|
||||||
|
[
|
||||||
|
'system.simple',
|
||||||
|
'missing2',
|
||||||
|
'missing2',
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
],
|
||||||
|
// Present in extension storage but missing from active storage.
|
||||||
|
[
|
||||||
|
'system.simple',
|
||||||
|
'another',
|
||||||
|
'another',
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Drupal\config_update\ConfigReverter::delete
|
||||||
|
* @dataProvider deleteProvider
|
||||||
|
*/
|
||||||
|
public function testDelete($type, $name, $config_name, $expected) {
|
||||||
|
// Clear dispatch log.
|
||||||
|
$this->dispatchedEvents = [];
|
||||||
|
$save_config = $this->configStorage;
|
||||||
|
|
||||||
|
// Call the deleteer and test the Boolean result.
|
||||||
|
$result = $this->configReverter->delete($type, $name);
|
||||||
|
$this->assertEquals($result, $expected);
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
// Verify that the config is missing after delete, and logging worked.
|
||||||
|
$this->assertTrue(!isset($this->configStorage[$config_name]));
|
||||||
|
$this->assertEquals(count($this->dispatchedEvents), 1);
|
||||||
|
$this->assertEquals($this->dispatchedEvents[0][0], ConfigDeleteInterface::DELETE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Verify that the config didn't change and no events were logged.
|
||||||
|
$this->assertEquals($this->configStorage, $save_config);
|
||||||
|
$this->assertEquals(count($this->dispatchedEvents), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for self:testDelete().
|
||||||
|
*/
|
||||||
|
public function deleteProvider() {
|
||||||
|
return [
|
||||||
|
// Elements: type, name, config name, return value.
|
||||||
|
[
|
||||||
|
'system.simple',
|
||||||
|
'in.extension',
|
||||||
|
'in.extension',
|
||||||
|
TRUE,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'foo',
|
||||||
|
'one',
|
||||||
|
'foo.bar.one',
|
||||||
|
TRUE,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'unknown',
|
||||||
|
'in.extension',
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'system.simple',
|
||||||
|
'missing2',
|
||||||
|
'missing2',
|
||||||
|
FALSE,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+547
@@ -0,0 +1,547 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\config_update\Unit;
|
||||||
|
|
||||||
|
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||||
|
use Drupal\Tests\UnitTestCase;
|
||||||
|
use Symfony\Component\EventDispatcher\Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for unit testing in Config Update Manager.
|
||||||
|
*
|
||||||
|
* This class provides some mock classes for unit testing.
|
||||||
|
*/
|
||||||
|
abstract class ConfigUpdateUnitTestBase extends UnitTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mocked entity definition information.
|
||||||
|
*
|
||||||
|
* They are not sorted, to test that the methods sort them. Also there are a
|
||||||
|
* couple with prefixes that are subsets of each other.
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*
|
||||||
|
* @see ConfigUpdateUnitTestBase::getEntityManagerMock().
|
||||||
|
*/
|
||||||
|
protected $entityDefinitionInformation = [
|
||||||
|
['prefix' => 'foo.bar', 'type' => 'foo'],
|
||||||
|
['prefix' => 'foo.barbaz', 'type' => 'bar'],
|
||||||
|
['prefix' => 'baz.foo', 'type' => 'baz'],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a mock entity manager for the test.
|
||||||
|
*
|
||||||
|
* @see ConfigUpdateUnitTestBase::entityDefinitionInformation
|
||||||
|
*/
|
||||||
|
protected function getEntityManagerMock() {
|
||||||
|
$definitions = [];
|
||||||
|
$map = [];
|
||||||
|
foreach ($this->entityDefinitionInformation as $info) {
|
||||||
|
$def = $this->getMockBuilder('Drupal\Core\Config\Entity\ConfigEntityTypeInterface')->getMock();
|
||||||
|
$def
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getConfigPrefix')
|
||||||
|
->willReturn($info['prefix']);
|
||||||
|
$def
|
||||||
|
->expects($this->any())
|
||||||
|
->method('entityClassImplements')
|
||||||
|
->willReturn(TRUE);
|
||||||
|
|
||||||
|
$def
|
||||||
|
->method('getKey')
|
||||||
|
->willReturn('id');
|
||||||
|
|
||||||
|
$def->getConfigPrefix();
|
||||||
|
|
||||||
|
$definitions[$info['type']] = $def;
|
||||||
|
$map[] = [$info['type'], FALSE, $def];
|
||||||
|
$map[] = [$info['type'], TRUE, $def];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add in a content entity definition, which shouldn't be recognized by the
|
||||||
|
// config lister class.
|
||||||
|
$def = $this->getMockBuilder('Drupal\Core\Entity\ContentEntityTypeInterface')->getMock();
|
||||||
|
$def
|
||||||
|
->expects($this->any())
|
||||||
|
->method('entityClassImplements')
|
||||||
|
->willReturn(FALSE);
|
||||||
|
$definitions['content_entity'] = $def;
|
||||||
|
|
||||||
|
$manager = $this->getMockBuilder('Drupal\Core\Entity\EntityTypeManagerInterface')->getMock();
|
||||||
|
$manager
|
||||||
|
->method('getDefinitions')
|
||||||
|
->willReturn($definitions);
|
||||||
|
|
||||||
|
$manager
|
||||||
|
->method('getDefinition')
|
||||||
|
->will($this->returnValueMap($map));
|
||||||
|
|
||||||
|
$manager
|
||||||
|
->method('getStorage')
|
||||||
|
->will($this->returnCallback([$this, 'mockGetStorage']));
|
||||||
|
|
||||||
|
return $manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mocks the getStorage() method for the entity manager.
|
||||||
|
*/
|
||||||
|
public function mockGetStorage($entity_type) {
|
||||||
|
// Figure out the config prefix for this entity type.
|
||||||
|
$prefix = '';
|
||||||
|
foreach ($this->entityDefinitionInformation as $info) {
|
||||||
|
if ($info['type'] == $entity_type) {
|
||||||
|
$prefix = $info['prefix'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is used in ConfigReverter::import(). Although it is supposed to
|
||||||
|
// be entity storage, we'll use our mock config object instead.
|
||||||
|
return new MockConfig('', $prefix, $this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of active configuration information for mocking.
|
||||||
|
*
|
||||||
|
* Array structure: Each element is an array whose first element is a
|
||||||
|
* provider name, and second is an array of config items it provides.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @see ConfigUpdateUnitTestBase::getConfigStorageMock()
|
||||||
|
*/
|
||||||
|
protected $configStorageActiveInfo = [
|
||||||
|
['foo.bar', ['foo.bar.one', 'foo.bar.two', 'foo.bar.three']],
|
||||||
|
['foo.barbaz', ['foo.barbaz.four', 'foo.barbaz.five', 'foo.barbaz.six']],
|
||||||
|
['baz.foo', []],
|
||||||
|
['',
|
||||||
|
[
|
||||||
|
'foo.bar.one',
|
||||||
|
'foo.bar.two',
|
||||||
|
'foo.bar.three',
|
||||||
|
'foo.barbaz.four',
|
||||||
|
'foo.barbaz.five',
|
||||||
|
'foo.barbaz.six',
|
||||||
|
'something.else',
|
||||||
|
'another.one',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of extension configuration information for mocking.
|
||||||
|
*
|
||||||
|
* Array structure: Each element is an array whose first element is a
|
||||||
|
* provider name, and second is an array of config items it provides.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @see ConfigUpdateUnitTestBase::getConfigStorageMock()
|
||||||
|
*/
|
||||||
|
protected $configStorageExtensionInfo = [
|
||||||
|
['foo.bar', ['foo.bar.one', 'foo.bar.two', 'foo.bar.seven']],
|
||||||
|
['baz.foo', []],
|
||||||
|
// This next item is assumed to be element 2 of the array. If not, you
|
||||||
|
// will need to change ConfigUpdateUnitTestBase::getConfigStorageMock().
|
||||||
|
['',
|
||||||
|
[
|
||||||
|
'foo.bar.one',
|
||||||
|
'foo.bar.two',
|
||||||
|
'foo.bar.seven',
|
||||||
|
'foo.barbaz.four',
|
||||||
|
'foo.barnot.three',
|
||||||
|
'something.else',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of optional configuration information for mocking.
|
||||||
|
*
|
||||||
|
* Array structure: Each element is an array whose first element is a
|
||||||
|
* provider name, and second is an array of config items it provides.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @see ConfigUpdateUnitTestBase::getConfigStorageMock()
|
||||||
|
*/
|
||||||
|
protected $configStorageOptionalInfo = [
|
||||||
|
['foo.bar', []],
|
||||||
|
['foo.barbaz', ['foo.barbaz.four']],
|
||||||
|
// This next item is assumed to be element 2 of the array. If not, you
|
||||||
|
// will need to change ConfigUpdateUnitTestBase::getConfigStorageMock().
|
||||||
|
['', ['foo.barbaz.four']],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a mock config storage object for the test.
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* Type of storage object to return: 'active', 'extension', or 'optional'.
|
||||||
|
* In active storage, the read() method is mocked to assume you are reading
|
||||||
|
* core.extension to get the profile name, so it returns that information.
|
||||||
|
* For extension and optional storage, the getComponentNames() method is
|
||||||
|
* mocked, and for all storages, the listAll() method is mocked.
|
||||||
|
*
|
||||||
|
* @see ConfigUpdateUnitTestBase::configStorageActiveInfo
|
||||||
|
* @see ConfigUpdateUnitTestBase::configStorageExtensionInfo
|
||||||
|
* @see ConfigUpdateUnitTestBase::configStorageOptionalInfo
|
||||||
|
*/
|
||||||
|
protected function getConfigStorageMock($type) {
|
||||||
|
if ($type == 'active') {
|
||||||
|
$storage = $this->getMockBuilder('Drupal\Core\Config\StorageInterface')->getMock();
|
||||||
|
|
||||||
|
// Various tests assume various values of configuration that need to be
|
||||||
|
// read from active storage.
|
||||||
|
$map = [
|
||||||
|
['core.extension', ['profile' => 'standard']],
|
||||||
|
['foo.bar.one', ['foo.bar.one' => 'active', 'id' => 'one']],
|
||||||
|
['missing', FALSE],
|
||||||
|
['in.extension',
|
||||||
|
['in.extension' => 'active', '_core' => 'core_for_in.extension'],
|
||||||
|
],
|
||||||
|
['in.both', ['in.both' => 'active']],
|
||||||
|
['in.optional', ['in.optional' => 'active']],
|
||||||
|
];
|
||||||
|
$storage
|
||||||
|
->method('read')
|
||||||
|
->will($this->returnValueMap($map));
|
||||||
|
|
||||||
|
$storage
|
||||||
|
->method('listAll')
|
||||||
|
->will($this->returnValueMap($this->configStorageActiveInfo));
|
||||||
|
}
|
||||||
|
elseif ($type == 'extension') {
|
||||||
|
$storage = $this->getMockBuilder('Drupal\Core\Config\ExtensionInstallStorage')->disableOriginalConstructor()->getMock();
|
||||||
|
|
||||||
|
$value = [];
|
||||||
|
foreach ($this->configStorageExtensionInfo[2][1] as $item) {
|
||||||
|
$value[$item] = 'ignored';
|
||||||
|
}
|
||||||
|
$storage
|
||||||
|
->method('getComponentNames')
|
||||||
|
->willReturn($value);
|
||||||
|
|
||||||
|
$storage
|
||||||
|
->method('listAll')
|
||||||
|
->will($this->returnValueMap($this->configStorageExtensionInfo));
|
||||||
|
$map = [
|
||||||
|
['in.extension', ['in.extension' => 'extension']],
|
||||||
|
['in.both', ['in.both' => 'extension']],
|
||||||
|
['in.optional', FALSE],
|
||||||
|
['foo.bar.one', ['foo.bar.one' => 'extension', 'id' => 'one']],
|
||||||
|
['another', ['another' => 'extension', 'id' => 'one']],
|
||||||
|
['missing2', FALSE],
|
||||||
|
];
|
||||||
|
$storage
|
||||||
|
->method('read')
|
||||||
|
->will($this->returnValueMap($map));
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$storage = $this->getMockBuilder('Drupal\Core\Config\ExtensionInstallStorage')->disableOriginalConstructor()->getMock();
|
||||||
|
|
||||||
|
$value = [];
|
||||||
|
foreach ($this->configStorageOptionalInfo[2][1] as $item) {
|
||||||
|
$value[$item] = 'ignored';
|
||||||
|
}
|
||||||
|
$storage
|
||||||
|
->method('getComponentNames')
|
||||||
|
->willReturn($value);
|
||||||
|
|
||||||
|
$storage
|
||||||
|
->method('listAll')
|
||||||
|
->will($this->returnValueMap($this->configStorageOptionalInfo));
|
||||||
|
|
||||||
|
$map = [
|
||||||
|
['in.optional', ['in.optional' => 'optional']],
|
||||||
|
['in.both', ['in.both' => 'optional']],
|
||||||
|
['missing2', FALSE],
|
||||||
|
];
|
||||||
|
$storage
|
||||||
|
->method('read')
|
||||||
|
->will($this->returnValueMap($map));
|
||||||
|
}
|
||||||
|
return $storage;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a mock module handler for the test.
|
||||||
|
*/
|
||||||
|
protected function getModuleHandlerMock() {
|
||||||
|
$manager = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandlerInterface')->getMock();
|
||||||
|
$manager->method('getModuleList')
|
||||||
|
->willReturn(['foo_module' => '', 'standard' => '']);
|
||||||
|
|
||||||
|
return $manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a mock theme handler for the test.
|
||||||
|
*/
|
||||||
|
protected function getThemeHandlerMock() {
|
||||||
|
$manager = $this->getMockBuilder('Drupal\Core\Extension\ThemeHandlerInterface')->getMock();
|
||||||
|
$manager->method('listInfo')
|
||||||
|
->willReturn(['foo_theme' => '']);
|
||||||
|
return $manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a mock string translation class for the test.
|
||||||
|
*/
|
||||||
|
protected function getTranslationMock() {
|
||||||
|
$translation = $this->getMockBuilder('Drupal\Core\StringTranslation\TranslationInterface')->getMock();
|
||||||
|
$translation
|
||||||
|
->method('translateString')
|
||||||
|
->will($this->returnCallback([$this, 'mockTranslate']));
|
||||||
|
return $translation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mocks the translateString() method for the string translation mock object.
|
||||||
|
*
|
||||||
|
* @param \Drupal\Core\StringTranslation\TranslatableMarkup $input
|
||||||
|
* Object to translate.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* The untranslated string from $input.
|
||||||
|
*/
|
||||||
|
public function mockTranslate(TranslatableMarkup $input) {
|
||||||
|
return $input->getUntranslatedString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of mock-dispatched events.
|
||||||
|
*
|
||||||
|
* Each element of the array is the call parameters to dispatchEvent() in
|
||||||
|
* the mocked dispatch class: name and event instance.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @see ConfigUpdateUnitTestBase::getEventDispatcherMock()
|
||||||
|
*/
|
||||||
|
protected $dispatchedEvents = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mocks the event dispatcher service.
|
||||||
|
*
|
||||||
|
* Stores dispatched events in ConfigUpdateUnitTestBase::dispatchedEvents.
|
||||||
|
*/
|
||||||
|
protected function getEventDispatcherMock() {
|
||||||
|
$event = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
|
||||||
|
$event
|
||||||
|
->method('dispatch')
|
||||||
|
->will($this->returnCallback([$this, 'mockDispatch']));
|
||||||
|
|
||||||
|
return $event;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mocks event dispatch.
|
||||||
|
*
|
||||||
|
* For \Symfony\Component\EventDispatcher\EventDispatchInterface::dispatch().
|
||||||
|
*/
|
||||||
|
public function mockDispatch($name, Event $event = NULL) {
|
||||||
|
$this->dispatchedEvents[] = [$name, $event];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock config storage for the mock config factory.
|
||||||
|
*
|
||||||
|
* This is actually managed by the MockConfig class in this file.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $configStorage = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value of the mocked config storage.
|
||||||
|
*/
|
||||||
|
public function getConfigStorage() {
|
||||||
|
return $this->configStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of the mocked config storage.
|
||||||
|
*/
|
||||||
|
public function setConfigStorage($values) {
|
||||||
|
$this->configStorage = $values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a mock config factory class for the test.
|
||||||
|
*/
|
||||||
|
protected function getConfigFactoryMock() {
|
||||||
|
$config = $this->getMockBuilder('Drupal\Core\Config\ConfigFactoryInterface')->getMock();
|
||||||
|
$config
|
||||||
|
->method('getEditable')
|
||||||
|
->will($this->returnCallback([$this, 'mockGetEditable']));
|
||||||
|
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mocks the getEditable() method for the mock config factory.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* Name of the config object to get an editable object for.
|
||||||
|
*
|
||||||
|
* @return MockConfig
|
||||||
|
* Editable mock config object.
|
||||||
|
*/
|
||||||
|
public function mockGetEditable($name) {
|
||||||
|
return new MockConfig($name, '', $this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock class for mutable configuration, config entity, and entity storage.
|
||||||
|
*/
|
||||||
|
class MockConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the config.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $name = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix for the entity type being mocked, for entity storage mocking.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $entityPrefix = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class this comes from.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Tests\config_update\Unit\ConfigUpdateUnitTestBase
|
||||||
|
*/
|
||||||
|
protected $test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current value of the configuration.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $value = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a mock config object.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* Name of the config that is being mocked. Can be blank.
|
||||||
|
* @param string $entity_prefix
|
||||||
|
* Prefix for the entity type that is being mocked. Often blank.
|
||||||
|
* @param \Drupal\Tests\config_update\Unit\ConfigUpdateUnitTestBase $test
|
||||||
|
* Test class this comes from.
|
||||||
|
*/
|
||||||
|
public function __construct($name, $entity_prefix, ConfigUpdateUnitTestBase $test) {
|
||||||
|
$this->name = $name;
|
||||||
|
$this->entityPrefix = $entity_prefix;
|
||||||
|
$this->test = $test;
|
||||||
|
|
||||||
|
$storage = $test->getConfigStorage();
|
||||||
|
if ($name && isset($storage[$name])) {
|
||||||
|
$value = $storage[$name];
|
||||||
|
$value['is_new'] = FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$value['is_new'] = TRUE;
|
||||||
|
}
|
||||||
|
$value['_core'] = 'core_for_' . $name;
|
||||||
|
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a component of the configuration value.
|
||||||
|
*/
|
||||||
|
public function get($key) {
|
||||||
|
return isset($this->value[$key]) ? $this->value[$key] : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a component of the configuration value.
|
||||||
|
*/
|
||||||
|
public function set($key, $value) {
|
||||||
|
$this->value[$key] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the entire configuration value.
|
||||||
|
*/
|
||||||
|
public function setData($value) {
|
||||||
|
// Retain the _core key.
|
||||||
|
$core = isset($this->value['_core']) ? $this->value['_core'] : '';
|
||||||
|
$this->value = $value;
|
||||||
|
if ($core) {
|
||||||
|
$this->value['_core'] = $core;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the configuration.
|
||||||
|
*/
|
||||||
|
public function save() {
|
||||||
|
$config = $this->test->getConfigStorage();
|
||||||
|
$config[$this->name] = $this->value;
|
||||||
|
$this->test->setConfigStorage($config);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the configuration.
|
||||||
|
*/
|
||||||
|
public function delete() {
|
||||||
|
$config = $this->test->getConfigStorage();
|
||||||
|
unset($config[$this->name]);
|
||||||
|
$this->test->setConfigStorage($config);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mocks the createFromStorageRecord() method from entity storage.
|
||||||
|
*/
|
||||||
|
public function createFromStorageRecord($values) {
|
||||||
|
if (!$this->entityPrefix) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is supposed to return an entity, but the only method we need is
|
||||||
|
// save(), so instead set up and return this object.
|
||||||
|
$this->name = $this->entityPrefix . '.' . $values['id'];
|
||||||
|
$this->value = $values;
|
||||||
|
$this->value['_core'] = 'core_for_' . $this->name;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mocks the updateFromStorageRecord() method from entity storage.
|
||||||
|
*/
|
||||||
|
public function updateFromStorageRecord($object, $values) {
|
||||||
|
return $object->createFromStorageRecord($values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mocks the load() method for entity storage.
|
||||||
|
*/
|
||||||
|
public function load($id) {
|
||||||
|
$full_name = $this->entityPrefix . '.' . $id;
|
||||||
|
$configs = $this->test->getConfigStorage();
|
||||||
|
if (isset($configs[$full_name])) {
|
||||||
|
$this->value = $configs[$full_name];
|
||||||
|
$this->name = $full_name;
|
||||||
|
$this->value['_core'] = 'core_for_' . $full_name;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,21 +4,13 @@ sudo: false
|
|||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
include:
|
include:
|
||||||
- env: DRUPAL=8.5.x
|
- env: DRUPAL=8.6.x
|
||||||
php: 5.5
|
|
||||||
- env: DRUPAL=8.5.x
|
|
||||||
php: 5.6
|
|
||||||
- env: DRUPAL=8.5.x
|
|
||||||
php: 7.1
|
php: 7.1
|
||||||
- env: DRUPAL=8.5.x
|
- env: DRUPAL=8.6.x
|
||||||
php: 7.2
|
php: 7.2
|
||||||
- env: DRUPAL=8.6.x
|
- env: DRUPAL=8.7.x
|
||||||
php: 5.5
|
|
||||||
- env: DRUPAL=8.6.x
|
|
||||||
php: 5.6
|
|
||||||
- env: DRUPAL=8.6.x
|
|
||||||
php: 7.1
|
php: 7.1
|
||||||
- env: DRUPAL=8.6.x
|
- env: DRUPAL=8.7.x
|
||||||
php: 7.2
|
php: 7.2
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
@@ -94,11 +86,11 @@ before_script:
|
|||||||
- until curl -s example.com:8080; do true; done > /dev/null
|
- until curl -s example.com:8080; do true; done > /dev/null
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 4 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain
|
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 20 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain
|
||||||
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 4 --types "PHPUnit-Kernel" --php `which php` --url http://example.com:8080 domain
|
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 20 --types "PHPUnit-Kernel" --php `which php` --url http://example.com:8080 domain
|
||||||
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 4 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain_access
|
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 20 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain_access
|
||||||
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 4 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain_alias
|
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 20 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain_alias
|
||||||
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 4 --types "PHPUnit-Kernel" --php `which php` --url http://example.com:8080 domain_alias
|
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 20 --types "PHPUnit-Kernel" --php `which php` --url http://example.com:8080 domain_alias
|
||||||
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 4 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain_config
|
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 20 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain_config
|
||||||
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 4 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain_content
|
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 20 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain_content
|
||||||
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 4 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain_source
|
- php core/scripts/run-tests.sh --suppress-deprecations --verbose --color --concurrency 20 --types "PHPUnit-Functional" --php `which php` --url http://example.com:8080 domain_source
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ Changelog
|
|||||||
12-FEB-2018 8.x-1.0-alpha12
|
12-FEB-2018 8.x-1.0-alpha12
|
||||||
07-MAR-2018 8.x-1.0-alpha13
|
07-MAR-2018 8.x-1.0-alpha13
|
||||||
19-OCT-2018 8.x-1.0-alpha14
|
19-OCT-2018 8.x-1.0-alpha14
|
||||||
|
21-FEB-2019 8.x-1.0-alpha15
|
||||||
|
|
||||||
Status
|
Status
|
||||||
====
|
====
|
||||||
@@ -113,7 +114,7 @@ marked with [x] are considered complete.
|
|||||||
- [x] Check domain responses on configuration forms
|
- [x] Check domain responses on configuration forms
|
||||||
- [x] Remove deprecated `entity_get_form_display`
|
- [x] Remove deprecated `entity_get_form_display`
|
||||||
- [x] Implement theme functions or twig templates where proper
|
- [x] Implement theme functions or twig templates where proper
|
||||||
- [ ] Advanced drush integration / complete labelled tasks
|
- [x] Advanced drush integration / complete labelled tasks
|
||||||
- [ ] Add filter options to domain_access and domain_source views
|
- [ ] Add filter options to domain_access and domain_source views
|
||||||
- [ ] Test cron handling
|
- [ ] Test cron handling
|
||||||
- [ ] Caching strategies in DomainNegotiator
|
- [ ] Caching strategies in DomainNegotiator
|
||||||
|
|||||||
@@ -199,23 +199,16 @@ a beta release on Drupal.org.
|
|||||||
|
|
||||||
We would like to tackle issues in that order, but feel free to work on what motivates you.
|
We would like to tackle issues in that order, but feel free to work on what motivates you.
|
||||||
|
|
||||||
Testing
|
Testing [](https://travis-ci.com/agentrickard/domain)
|
||||||
====
|
====
|
||||||
|
|
||||||
@zerolab built a Travis definition file for automated testing! That means all pull requests will automatically run tests!
|
@zerolab built a Travis definition file for automated testing! That means all pull requests will automatically run tests!
|
||||||
|
|
||||||
[](https://travis-ci.org/agentrickard/domain)
|
|
||||||
|
|
||||||
The module does have solid test coverage, and complete coverage is required for release.
|
|
||||||
Right now, we mostly use SimpleTest, because it is most familiar, and much of our
|
|
||||||
testing is about browser and http behavior.
|
|
||||||
|
|
||||||
If you file a pull request or patch, please (at a minimum) run the existing tests to check
|
If you file a pull request or patch, please (at a minimum) run the existing tests to check
|
||||||
for failures. Writing additional tests will greatly speed completion, as I won't commit
|
for failures. Writing additional tests will greatly speed completion, as I won't commit
|
||||||
code without test coverage.
|
code without test coverage.
|
||||||
|
|
||||||
New tests should be written as Functional, Kernel, or Unit tests. Conversion patches that
|
New tests should be written in PHPUnit as Functional, Kernel, or Unit tests.
|
||||||
move Simpletests to Functional tests are welcome.
|
|
||||||
|
|
||||||
Because Domain requires varying http host requests to test, we can't normally use the Drupal.org
|
Because Domain requires varying http host requests to test, we can't normally use the Drupal.org
|
||||||
testing infrastructure. (This may change, but we are not counting on it.)
|
testing infrastructure. (This may change, but we are not counting on it.)
|
||||||
@@ -227,5 +220,3 @@ point to your drupal instance. I use variants of `example.com` for local tests.
|
|||||||
in most test cases. See `DomainTestBase::domainCreateTestDomains()` for the logic.
|
in most test cases. See `DomainTestBase::domainCreateTestDomains()` for the logic.
|
||||||
|
|
||||||
When running tests, you normally need to be on the default domain.
|
When running tests, you normally need to be on the default domain.
|
||||||
|
|
||||||
If anyone is capable of building a vagrant box to simplify testing, that would be ideal.
|
|
||||||
|
|||||||
@@ -13,5 +13,14 @@
|
|||||||
"issues": "http://drupal.org/project/issues/domain",
|
"issues": "http://drupal.org/project/issues/domain",
|
||||||
"irc": "http://irc.freenode.org/drupal-contribute",
|
"irc": "http://irc.freenode.org/drupal-contribute",
|
||||||
"source": "http://cgit.drupalcode.org/domain"
|
"source": "http://cgit.drupalcode.org/domain"
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"drush": {
|
||||||
|
"services": {
|
||||||
|
"domain/drush.services.yml": "^9",
|
||||||
|
"domain_access/drush.services.yml": "^9",
|
||||||
|
"domain_source/drush.services.yml": "^9"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ dependencies:
|
|||||||
- drupal:options
|
- drupal:options
|
||||||
configure: domain.admin
|
configure: domain.admin
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
@@ -159,3 +159,19 @@ function domain_theme() {
|
|||||||
function template_preprocess_domain_nav_block(array &$variables) {
|
function template_preprocess_domain_nav_block(array &$variables) {
|
||||||
$variables['items'] = $variables['items']['#items'];
|
$variables['items'] = $variables['items']['#items'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_hook_info().
|
||||||
|
*/
|
||||||
|
function domain_hook_info() {
|
||||||
|
$hooks['domain_request_alter'] = [
|
||||||
|
'group' => 'domain',
|
||||||
|
];
|
||||||
|
$hooks['domain_validate_alter'] = [
|
||||||
|
'group' => 'domain',
|
||||||
|
];
|
||||||
|
$hooks['domain_references_alter'] = [
|
||||||
|
'group' => 'domain',
|
||||||
|
];
|
||||||
|
return $hooks;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
services:
|
||||||
|
domain.commands:
|
||||||
|
class: \Drupal\domain\Commands\DomainCommands
|
||||||
|
tags:
|
||||||
|
- { name: drush.command }
|
||||||
@@ -75,17 +75,17 @@ class DomainAccessCheck implements AccessCheckInterface {
|
|||||||
// Is the domain allowed?
|
// Is the domain allowed?
|
||||||
// No domain, let it pass.
|
// No domain, let it pass.
|
||||||
if (empty($domain)) {
|
if (empty($domain)) {
|
||||||
return AccessResult::allowed()->setCacheMaxAge(0);
|
return AccessResult::allowed()->addCacheTags(['url.site']);
|
||||||
}
|
}
|
||||||
// Active domain, let it pass.
|
// Active domain, let it pass.
|
||||||
if ($domain->status()) {
|
if ($domain->status()) {
|
||||||
return AccessResult::allowed()->setCacheMaxAge(0);
|
return AccessResult::allowed()->addCacheTags(['url.site']);
|
||||||
}
|
}
|
||||||
// Inactive domain, require permissions.
|
// Inactive domain, require permissions.
|
||||||
else {
|
else {
|
||||||
$permissions = ['administer domains', 'access inactive domains'];
|
$permissions = ['administer domains', 'access inactive domains'];
|
||||||
$operator = 'OR';
|
$operator = 'OR';
|
||||||
return AccessResult::allowedIfHasPermissions($account, $permissions, $operator)->setCacheMaxAge(0);
|
return AccessResult::allowedIfHasPermissions($account, $permissions, $operator)->addCacheTags(['url.site']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\domain\Commands;
|
||||||
|
|
||||||
|
class DomainCommandException extends \Exception {
|
||||||
|
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -59,8 +59,15 @@ class DomainElementManager implements DomainElementManagerInterface {
|
|||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
$fields = $this->fieldList($field_name);
|
$fields = $this->fieldList($field_name);
|
||||||
|
$empty = FALSE;
|
||||||
$disallowed = $this->disallowedOptions($form_state, $form[$field_name]);
|
$disallowed = $this->disallowedOptions($form_state, $form[$field_name]);
|
||||||
$empty = empty($form[$field_name]['widget']['#options']);
|
if (empty($form[$field_name]['widget']['#options']) ||
|
||||||
|
(count($form[$field_name]['widget']['#options']) == 1 &&
|
||||||
|
isset($form[$field_name]['widget']['#options']['_none'])
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
$empty = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
// If the domain form element is set as a group, and the field is not
|
// If the domain form element is set as a group, and the field is not
|
||||||
// assigned to another group, then move it. See
|
// assigned to another group, then move it. See
|
||||||
@@ -68,7 +75,10 @@ class DomainElementManager implements DomainElementManagerInterface {
|
|||||||
if (isset($form['domain']) && !isset($form[$field_name]['#group'])) {
|
if (isset($form['domain']) && !isset($form[$field_name]['#group'])) {
|
||||||
$form[$field_name]['#group'] = 'domain';
|
$form[$field_name]['#group'] = 'domain';
|
||||||
}
|
}
|
||||||
|
// If no values and we should hide the element, do so.
|
||||||
|
if ($hide_on_disallow && $empty) {
|
||||||
|
$form[$field_name]['#access'] = FALSE;
|
||||||
|
}
|
||||||
// Check for domains the user cannot access or the absence of any options.
|
// Check for domains the user cannot access or the absence of any options.
|
||||||
if (!empty($disallowed) || $empty) {
|
if (!empty($disallowed) || $empty) {
|
||||||
// @TODO: Potentially show this information to users with permission.
|
// @TODO: Potentially show this information to users with permission.
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class DomainNegotiator implements DomainNegotiatorInterface {
|
|||||||
/**
|
/**
|
||||||
* The domain storage class.
|
* The domain storage class.
|
||||||
*
|
*
|
||||||
* @var \Drupal\domain\DomainStorageInterface
|
* @var \Drupal\domain\DomainStorageInterface|null
|
||||||
*/
|
*/
|
||||||
protected $domainStorage;
|
protected $domainStorage;
|
||||||
|
|
||||||
@@ -87,7 +87,6 @@ class DomainNegotiator implements DomainNegotiatorInterface {
|
|||||||
$this->requestStack = $requestStack;
|
$this->requestStack = $requestStack;
|
||||||
$this->moduleHandler = $module_handler;
|
$this->moduleHandler = $module_handler;
|
||||||
$this->entityTypeManager = $entity_type_manager;
|
$this->entityTypeManager = $entity_type_manager;
|
||||||
$this->domainStorage = $this->entityTypeManager->getStorage('domain');
|
|
||||||
$this->configFactory = $config_factory;
|
$this->configFactory = $config_factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +97,7 @@ class DomainNegotiator implements DomainNegotiatorInterface {
|
|||||||
// @TODO: Investigate caching methods.
|
// @TODO: Investigate caching methods.
|
||||||
$this->setHttpHost($httpHost);
|
$this->setHttpHost($httpHost);
|
||||||
// Try to load a direct match.
|
// Try to load a direct match.
|
||||||
if ($domain = $this->domainStorage->loadByHostname($httpHost)) {
|
if ($domain = $this->domainStorage()->loadByHostname($httpHost)) {
|
||||||
// If the load worked, set an exact match flag for the hook.
|
// If the load worked, set an exact match flag for the hook.
|
||||||
$domain->setMatchType(self::DOMAIN_MATCH_EXACT);
|
$domain->setMatchType(self::DOMAIN_MATCH_EXACT);
|
||||||
}
|
}
|
||||||
@@ -107,16 +106,10 @@ class DomainNegotiator implements DomainNegotiatorInterface {
|
|||||||
else {
|
else {
|
||||||
$values = ['hostname' => $httpHost];
|
$values = ['hostname' => $httpHost];
|
||||||
/** @var \Drupal\domain\DomainInterface $domain */
|
/** @var \Drupal\domain\DomainInterface $domain */
|
||||||
$domain = $this->domainStorage->create($values);
|
$domain = $this->domainStorage()->create($values);
|
||||||
$domain->setMatchType(self::DOMAIN_MATCH_NONE);
|
$domain->setMatchType(self::DOMAIN_MATCH_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure all modules are loaded and can alter the found domains.
|
|
||||||
// See https://www.drupal.org/node/2896434#comment-12267208.
|
|
||||||
$this->moduleHandler->reload();
|
|
||||||
foreach ($this->moduleHandler->getImplementations('domain_request_alter') as $module) {
|
|
||||||
$this->moduleHandler->load($module);
|
|
||||||
}
|
|
||||||
// Now check with modules (like Domain Alias) that register alternate
|
// Now check with modules (like Domain Alias) that register alternate
|
||||||
// lookup systems with the main module.
|
// lookup systems with the main module.
|
||||||
$this->moduleHandler->alter('domain_request', $domain);
|
$this->moduleHandler->alter('domain_request', $domain);
|
||||||
@@ -126,7 +119,7 @@ class DomainNegotiator implements DomainNegotiatorInterface {
|
|||||||
$this->setActiveDomain($domain);
|
$this->setActiveDomain($domain);
|
||||||
}
|
}
|
||||||
// Fallback to default domain if no match.
|
// Fallback to default domain if no match.
|
||||||
elseif ($domain = $this->domainStorage->loadDefaultDomain()) {
|
elseif ($domain = $this->domainStorage()->loadDefaultDomain()) {
|
||||||
$this->moduleHandler->alter('domain_request', $domain);
|
$this->moduleHandler->alter('domain_request', $domain);
|
||||||
$domain->setMatchType(self::DOMAIN_MATCH_NONE);
|
$domain->setMatchType(self::DOMAIN_MATCH_NONE);
|
||||||
if (!empty($domain->id())) {
|
if (!empty($domain->id())) {
|
||||||
@@ -180,7 +173,7 @@ class DomainNegotiator implements DomainNegotiatorInterface {
|
|||||||
$httpHost = $_SERVER['HTTP_HOST'];
|
$httpHost = $_SERVER['HTTP_HOST'];
|
||||||
}
|
}
|
||||||
$hostname = !empty($httpHost) ? $httpHost : 'localhost';
|
$hostname = !empty($httpHost) ? $httpHost : 'localhost';
|
||||||
return $this->domainStorage->prepareHostname($hostname);
|
return $this->domainStorage()->prepareHostname($hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -202,13 +195,13 @@ class DomainNegotiator implements DomainNegotiatorInterface {
|
|||||||
*/
|
*/
|
||||||
public function isRegisteredDomain($hostname) {
|
public function isRegisteredDomain($hostname) {
|
||||||
// Direct hostname match always passes.
|
// Direct hostname match always passes.
|
||||||
if ($domain = $this->domainStorage->loadByHostname($hostname)) {
|
if ($domain = $this->domainStorage()->loadByHostname($hostname)) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
// Check for registered alias matches.
|
// Check for registered alias matches.
|
||||||
$values = ['hostname' => $hostname];
|
$values = ['hostname' => $hostname];
|
||||||
/** @var \Drupal\domain\DomainInterface $domain */
|
/** @var \Drupal\domain\DomainInterface $domain */
|
||||||
$domain = $this->domainStorage->create($values);
|
$domain = $this->domainStorage()->create($values);
|
||||||
$domain->setMatchType(self::DOMAIN_MATCH_NONE);
|
$domain->setMatchType(self::DOMAIN_MATCH_NONE);
|
||||||
|
|
||||||
// Now check with modules (like Domain Alias) that register alternate
|
// Now check with modules (like Domain Alias) that register alternate
|
||||||
@@ -222,4 +215,17 @@ class DomainNegotiator implements DomainNegotiatorInterface {
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the domain storage handler.
|
||||||
|
*
|
||||||
|
* @return \Drupal\domain\DomainStorageInterface
|
||||||
|
* The domain storage handler.
|
||||||
|
*/
|
||||||
|
protected function domainStorage() {
|
||||||
|
if (!$this->domainStorage) {
|
||||||
|
$this->domainStorage = $this->entityTypeManager->getStorage('domain');
|
||||||
|
}
|
||||||
|
return $this->domainStorage;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,10 +132,9 @@ class DomainValidator implements DomainValidatorInterface {
|
|||||||
}
|
}
|
||||||
// We cannot know which Guzzle Exception class will be returned; be generic.
|
// We cannot know which Guzzle Exception class will be returned; be generic.
|
||||||
catch (RequestException $e) {
|
catch (RequestException $e) {
|
||||||
watchdog_exception('domain', $e);
|
|
||||||
// File a general server failure.
|
// File a general server failure.
|
||||||
$domain->setResponse(500);
|
$domain->setResponse(500);
|
||||||
return;
|
return $domain->getResponse();
|
||||||
}
|
}
|
||||||
// Expected result (i.e. no exception thrown.)
|
// Expected result (i.e. no exception thrown.)
|
||||||
$domain->setResponse($request->getStatusCode());
|
$domain->setResponse($request->getStatusCode());
|
||||||
|
|||||||
@@ -343,8 +343,8 @@ class Domain extends ConfigEntityBase implements DomainInterface {
|
|||||||
$default->is_default = FALSE;
|
$default->is_default = FALSE;
|
||||||
$default->save();
|
$default->save();
|
||||||
}
|
}
|
||||||
// Ensures we have a proper domain_id.
|
// Ensures we have a proper domain_id but does not erase existing ones.
|
||||||
if ($this->isNew()) {
|
if ($this->isNew() && empty($this->getDomainId())) {
|
||||||
$this->createDomainId();
|
$this->createDomainId();
|
||||||
}
|
}
|
||||||
// Prevent duplicate hostname.
|
// Prevent duplicate hostname.
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||||||
* id = "domain",
|
* id = "domain",
|
||||||
* label = @Translation("Domain"),
|
* label = @Translation("Domain"),
|
||||||
* context = {
|
* context = {
|
||||||
* "entity:domain" = @ContextDefinition("entity:domain", label = @Translation("Domain"), required = TRUE)
|
* "entity:domain" = @ContextDefinition("entity:domain", label = @Translation("Domain"), required = FALSE)
|
||||||
* }
|
* }
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
@@ -73,7 +73,12 @@ class Domain extends ConditionPluginBase implements ContainerFactoryPluginInterf
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
return parent::buildConfigurationForm($form, $form_state);
|
$form = parent::buildConfigurationForm($form, $form_state);
|
||||||
|
if (isset($form['context_mapping']['entity:domain']['#title'])) {
|
||||||
|
$form['context_mapping']['entity:domain']['#title'] = $this->t('Select the Domain condition');
|
||||||
|
$form['context_mapping']['entity:domain']['#description'] = $this->t('This value must be set to "Active domain" for the context to work.');
|
||||||
|
}
|
||||||
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-3
@@ -9,8 +9,8 @@ hidden: TRUE
|
|||||||
dependencies:
|
dependencies:
|
||||||
- domain
|
- domain
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
+3
-3
@@ -9,8 +9,8 @@ hidden: TRUE
|
|||||||
dependencies:
|
dependencies:
|
||||||
- domain
|
- domain
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ dependencies:
|
|||||||
- drupal:node
|
- drupal:node
|
||||||
- domain:domain
|
- domain:domain
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
services:
|
||||||
|
domain_access.commands:
|
||||||
|
class: \Drupal\domain_access\Commands\DomainAccessCommands
|
||||||
|
tags:
|
||||||
|
- { name: drush.command }
|
||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\domain_access\Commands;
|
||||||
|
|
||||||
|
use Consolidation\AnnotatedCommand\AnnotationData;
|
||||||
|
use Consolidation\AnnotatedCommand\CommandData;
|
||||||
|
use Drupal\domain\Commands\DomainCommands;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drush commands for the domain access module.
|
||||||
|
*
|
||||||
|
* These commands mainly extend base Domain commands. See the documentation at
|
||||||
|
* https://github.com/consolidation/annotated-command for details.
|
||||||
|
*/
|
||||||
|
class DomainAccessCommands extends DomainCommands {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers additional information to domain:info.
|
||||||
|
*
|
||||||
|
* @hook init domain:info
|
||||||
|
*/
|
||||||
|
public function initDomainInfo(InputInterface $input, AnnotationData $annotationData) {
|
||||||
|
// To add a field label, append to the 'field-labels' item.
|
||||||
|
// @TODO: watch https://github.com/consolidation/annotated-command/pull/174
|
||||||
|
$annotationData['field-labels'] .= "\n" . 'domain_access_entities: Domain access entities';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides additional information to domain:info.
|
||||||
|
*
|
||||||
|
* @hook alter domain:info
|
||||||
|
*/
|
||||||
|
public function alterDomainInfo($result, CommandData $commandData) {
|
||||||
|
// Display which entities are enabled for domain by checking for the fields.
|
||||||
|
$result['domain_access_entities'] = $this->getFieldEntities(DOMAIN_ACCESS_FIELD);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hook option domain:delete
|
||||||
|
*/
|
||||||
|
public function deleteOptions(Command $command, AnnotationData $annotationData) {
|
||||||
|
$command->addOption(
|
||||||
|
'content-assign',
|
||||||
|
'',
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'Reassign content for Domain Access',
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hook on-event domain-delete
|
||||||
|
*/
|
||||||
|
public function domainAccessDomainDelete($target_domain, $options) {
|
||||||
|
// Run our own deletion routine here.
|
||||||
|
if (is_null($options['content-assign'])) {
|
||||||
|
$policy_content = 'prompt';
|
||||||
|
}
|
||||||
|
if (!empty($options['content-assign'])) {
|
||||||
|
if (in_array($options['content-assign'], $this->reassignment_policies, TRUE)) {
|
||||||
|
$policy_content = $options['content-assign'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$delete_options = [
|
||||||
|
'entity_filter' => 'node',
|
||||||
|
'policy' => $policy_content,
|
||||||
|
'field' => DOMAIN_ACCESS_FIELD,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->doReassign($target_domain, $delete_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+3
-3
@@ -11,8 +11,8 @@ dependencies:
|
|||||||
- domain_access
|
- domain_access
|
||||||
- taxonomy
|
- taxonomy
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ package: Domain
|
|||||||
dependencies:
|
dependencies:
|
||||||
- domain:domain
|
- domain:domain
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ package: Domain
|
|||||||
dependencies:
|
dependencies:
|
||||||
- domain:domain
|
- domain:domain
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ services:
|
|||||||
class: Drupal\domain_config\DomainConfigOverrider
|
class: Drupal\domain_config\DomainConfigOverrider
|
||||||
tags:
|
tags:
|
||||||
- { name: config.factory.override, priority: -150}
|
- { name: config.factory.override, priority: -150}
|
||||||
arguments: ['@config.storage']
|
arguments: ['@config.storage', '@module_handler']
|
||||||
|
|
||||||
domain_config.library.discovery.collector:
|
domain_config.library.discovery.collector:
|
||||||
decorates: library.discovery.collector
|
decorates: library.discovery.collector
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use Drupal\domain\DomainInterface;
|
|||||||
use Drupal\Core\Cache\CacheableMetadata;
|
use Drupal\Core\Cache\CacheableMetadata;
|
||||||
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
|
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
|
||||||
use Drupal\Core\Config\StorageInterface;
|
use Drupal\Core\Config\StorageInterface;
|
||||||
|
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Domain-specific config overrides.
|
* Domain-specific config overrides.
|
||||||
@@ -29,6 +30,13 @@ class DomainConfigOverrider implements ConfigFactoryOverrideInterface {
|
|||||||
*/
|
*/
|
||||||
protected $storage;
|
protected $storage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The module handler.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Extension\ModuleHandlerInterface
|
||||||
|
*/
|
||||||
|
protected $moduleHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The domain context of the request.
|
* The domain context of the request.
|
||||||
*
|
*
|
||||||
@@ -64,9 +72,12 @@ class DomainConfigOverrider implements ConfigFactoryOverrideInterface {
|
|||||||
*
|
*
|
||||||
* @param \Drupal\Core\Config\StorageInterface $storage
|
* @param \Drupal\Core\Config\StorageInterface $storage
|
||||||
* The configuration storage engine.
|
* The configuration storage engine.
|
||||||
|
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
|
||||||
|
* The module handler.
|
||||||
*/
|
*/
|
||||||
public function __construct(StorageInterface $storage) {
|
public function __construct(StorageInterface $storage, ModuleHandlerInterface $module_handler) {
|
||||||
$this->storage = $storage;
|
$this->storage = $storage;
|
||||||
|
$this->moduleHandler = $module_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,11 +88,16 @@ class DomainConfigOverrider implements ConfigFactoryOverrideInterface {
|
|||||||
static $lookups;
|
static $lookups;
|
||||||
// Key should be a known length, so hash.
|
// Key should be a known length, so hash.
|
||||||
$key = md5(implode(':', $names));
|
$key = md5(implode(':', $names));
|
||||||
|
|
||||||
if (isset($lookups[$key])) {
|
if (isset($lookups[$key])) {
|
||||||
return $lookups[$key];
|
return $lookups[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the context of the override request.
|
||||||
|
if (empty($this->contextSet)) {
|
||||||
|
$this->initiateContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare our overrides.
|
||||||
$overrides = [];
|
$overrides = [];
|
||||||
// loadOverrides() runs on config entities, which means that if we try
|
// loadOverrides() runs on config entities, which means that if we try
|
||||||
// to run this routine on our own data, then we end up in an infinite loop.
|
// to run this routine on our own data, then we end up in an infinite loop.
|
||||||
@@ -92,9 +108,6 @@ class DomainConfigOverrider implements ConfigFactoryOverrideInterface {
|
|||||||
$lookups[$key] = $overrides;
|
$lookups[$key] = $overrides;
|
||||||
return $overrides;
|
return $overrides;
|
||||||
}
|
}
|
||||||
if (empty($this->contextSet)) {
|
|
||||||
$this->initiateContext();
|
|
||||||
}
|
|
||||||
if (!empty($this->domain)) {
|
if (!empty($this->domain)) {
|
||||||
foreach ($names as $name) {
|
foreach ($names as $name) {
|
||||||
$config_name = $this->getDomainConfigName($name, $this->domain);
|
$config_name = $this->getDomainConfigName($name, $this->domain);
|
||||||
@@ -198,7 +211,11 @@ class DomainConfigOverrider implements ConfigFactoryOverrideInterface {
|
|||||||
// run.
|
// run.
|
||||||
if (empty($this->domain)) {
|
if (empty($this->domain)) {
|
||||||
$this->domain = $this->domainNegotiator->getActiveDomain(TRUE);
|
$this->domain = $this->domainNegotiator->getActiveDomain(TRUE);
|
||||||
|
// Ensure the module hook cache is set properly.
|
||||||
|
// See https://www.drupal.org/project/domain/issues/3025541
|
||||||
|
$this->moduleHandler->resetImplementations();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
name: "Domain config hook test"
|
||||||
|
description: "Support module for domain config testing."
|
||||||
|
type: module
|
||||||
|
package: Testing
|
||||||
|
# version: VERSION
|
||||||
|
# core: 8.x
|
||||||
|
hidden: TRUE
|
||||||
|
|
||||||
|
dependencies: []
|
||||||
|
|
||||||
|
# This module represents several services that could be provided by multiple modules in the Drupal community.
|
||||||
|
# The following are not playing nice together:
|
||||||
|
# - A page cache policy service that uses the config factory.
|
||||||
|
# - A module that implements hook_module_implements.
|
||||||
|
# - A random hook that hook_module_implements wishes to control.
|
||||||
|
# - The domain_config module (and domain negotiator service, I believe).
|
||||||
|
|
||||||
|
# When this module is functioning correctly, when a user logs in, there will not be a state key set.
|
||||||
|
|
||||||
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
|
version: '8.x-1.0-alpha15'
|
||||||
|
core: '8.x'
|
||||||
|
project: 'domain'
|
||||||
|
datestamp: 1550763190
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Hook implementations for this module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_user_login().
|
||||||
|
*/
|
||||||
|
function domain_config_hook_test_user_login($account) {
|
||||||
|
\Drupal::state()->set('domain_config_test__user_login', TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_module_implements_alter().
|
||||||
|
*/
|
||||||
|
function domain_config_hook_test_module_implements_alter(&$implementations, $hook) {
|
||||||
|
if ($hook == 'user_login') {
|
||||||
|
// Turn off the domain_config_hook_test's hook_user_login (above).
|
||||||
|
unset($implementations['domain_config_hook_test']);
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
services:
|
||||||
|
domain_config_service.page_cache_request_policy:
|
||||||
|
class: Drupal\domain_config_hook_test\PageCache\RequestPolicy\PageCacheRequestPolicy
|
||||||
|
arguments: ['@config.factory']
|
||||||
|
tags:
|
||||||
|
- { name: page_cache_request_policy }
|
||||||
|
|
||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\domain_config_hook_test\PageCache\RequestPolicy;
|
||||||
|
|
||||||
|
use Drupal\Core\Config\ConfigFactory;
|
||||||
|
use Drupal\Core\PageCache\RequestPolicyInterface;
|
||||||
|
use Drupal\Core\Session\SessionConfigurationInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A page cache request policy.
|
||||||
|
*
|
||||||
|
* This service is not meant to DO anything, it's just meant to represent
|
||||||
|
* a service that might be present in the Drupal community. For example,
|
||||||
|
* persistent_login module has this same structure.
|
||||||
|
*/
|
||||||
|
class PageCacheRequestPolicy implements RequestPolicyInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drupal config factory.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Config\ConfigFactory
|
||||||
|
*/
|
||||||
|
protected $configFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param \Drupal\Core\Config\ConfigFactory $config_factory
|
||||||
|
* Drupal config factory.
|
||||||
|
*/
|
||||||
|
public function __construct(ConfigFactory $config_factory) {
|
||||||
|
$this->configFactory = $config_factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function check(Request $request) {
|
||||||
|
// This line is important. You have to use this service for it to fail.
|
||||||
|
$this->configFactory
|
||||||
|
->get('system.site');
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+3
-3
@@ -10,8 +10,8 @@ dependencies:
|
|||||||
- domain
|
- domain
|
||||||
- domain_config
|
- domain_config
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
+3
-3
@@ -10,8 +10,8 @@ dependencies:
|
|||||||
- domain
|
- domain
|
||||||
- domain_config
|
- domain_config
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\domain_config\Functional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the domain config system.
|
||||||
|
*
|
||||||
|
* @group domain_config
|
||||||
|
*/
|
||||||
|
class DomainConfigHookProblemTest extends DomainConfigHookTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static $modules = [
|
||||||
|
// Adds the domain_config module.
|
||||||
|
'domain_config',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disabled config schema checking.
|
||||||
|
*
|
||||||
|
* Domain Config actually duplicates schemas provided by other modules,
|
||||||
|
* so it cannot define its own.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $strictConfigSchema = FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\domain_config\Functional;
|
||||||
|
|
||||||
|
use Drupal\Tests\BrowserTestBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the domain config system.
|
||||||
|
*
|
||||||
|
* @group domain_config
|
||||||
|
*/
|
||||||
|
class DomainConfigHookTest extends BrowserTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static $modules = [
|
||||||
|
'domain',
|
||||||
|
// See module info file for description of what this module does.
|
||||||
|
'domain_config_hook_test',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test to ensure a domain_config_hook_test_user_login() does not run.
|
||||||
|
*
|
||||||
|
* This test serves as a control to show the domain_config_hook_test module
|
||||||
|
* functions correctly on it's own. Only when you add the domain_config
|
||||||
|
* module, does it fail.
|
||||||
|
*/
|
||||||
|
public function testHookRuns() {
|
||||||
|
$this->drupalGet('user/login');
|
||||||
|
$user = $this->drupalCreateUser([]);
|
||||||
|
$edit = ['name' => $user->getUserName(), 'pass' => $user->passRaw];
|
||||||
|
$this->drupalPostForm(NULL, $edit, t('Log in'));
|
||||||
|
|
||||||
|
$test = \Drupal::state()->get('domain_config_test__user_login', NULL);
|
||||||
|
// When this test passes, it means domain_config_hook_test_user_login was
|
||||||
|
// not run.
|
||||||
|
$this->assertNull($test, 'The hook_user_login state message is set.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,8 +11,8 @@ dependencies:
|
|||||||
- domain:domain
|
- domain:domain
|
||||||
- domain:domain_access
|
- domain:domain_access
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ use Drupal\Core\Url;
|
|||||||
class DomainContentController extends ControllerBase {
|
class DomainContentController extends ControllerBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the lost of domains and relevant entities.
|
* Builds the list of domains and relevant entities.
|
||||||
*
|
*
|
||||||
* @param array $options
|
* @param array $options
|
||||||
* A list of variables required to build editor or content pages.
|
* A list of variables required to build editor or content pages.
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ dependencies:
|
|||||||
- drupal:node
|
- drupal:node
|
||||||
- domain:domain
|
- domain:domain
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
@@ -286,3 +286,17 @@ function domain_source_presave_generate(EntityInterface $entity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements hook_hook_info().
|
||||||
|
*/
|
||||||
|
function domain_source_hook_info() {
|
||||||
|
$hooks['domain_source_alter'] = [
|
||||||
|
'group' => 'domain_source',
|
||||||
|
];
|
||||||
|
$hooks['domain_source_path_alter'] = [
|
||||||
|
'group' => 'domain_source',
|
||||||
|
];
|
||||||
|
return $hooks;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
services:
|
||||||
|
domain_source.commands:
|
||||||
|
class: \Drupal\domain_source\Commands\DomainSourceCommands
|
||||||
|
tags:
|
||||||
|
- { name: drush.command }
|
||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\domain_source\Commands;
|
||||||
|
|
||||||
|
use Consolidation\AnnotatedCommand\AnnotationData;
|
||||||
|
use Consolidation\AnnotatedCommand\CommandData;
|
||||||
|
use Drupal\domain\Commands\DomainCommands;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drush commands for the domain source module.
|
||||||
|
*
|
||||||
|
* These commands mainly extend base Domain commands. See the documentation at
|
||||||
|
* https://github.com/consolidation/annotated-command for details.
|
||||||
|
*/
|
||||||
|
class DomainSourceCommands extends DomainCommands {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers additional information to domain:info.
|
||||||
|
*
|
||||||
|
* @hook init domain:info
|
||||||
|
*/
|
||||||
|
public function initDomainInfo(InputInterface $input, AnnotationData $annotationData) {
|
||||||
|
// To add a field label, append to the 'field-labels' item.
|
||||||
|
// @TODO: watch https://github.com/consolidation/annotated-command/pull/174
|
||||||
|
$annotationData['field-labels'] .= "\n" . 'domain_source_entities: Domain source entities';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides additional information to domain:info.
|
||||||
|
*
|
||||||
|
* @hook alter domain:info
|
||||||
|
*/
|
||||||
|
public function alterDomainInfo($result, CommandData $commandData) {
|
||||||
|
// Display which entities are enabled for domain by checking for the fields.
|
||||||
|
$result['domain_source_entities'] = $this->getFieldEntities(DOMAIN_SOURCE_FIELD);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hook option domain:delete
|
||||||
|
*/
|
||||||
|
public function deleteOptions(Command $command, AnnotationData $annotationData) {
|
||||||
|
$command->addOption(
|
||||||
|
'source-assign',
|
||||||
|
'',
|
||||||
|
InputOption::VALUE_OPTIONAL,
|
||||||
|
'Reassign content for Domain Source',
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hook on-event domain-delete
|
||||||
|
*/
|
||||||
|
public function domainSourceDomainDelete($target_domain, $options) {
|
||||||
|
// Run our own deletion routine here.
|
||||||
|
if (is_null($options['content-assign'])) {
|
||||||
|
$policy_content = 'prompt';
|
||||||
|
}
|
||||||
|
if (!empty($options['content-assign'])) {
|
||||||
|
if (in_array($options['content-assign'], $this->reassignment_policies, TRUE)) {
|
||||||
|
$policy_content = $options['content-assign'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$delete_options = [
|
||||||
|
'entity_filter' => 'node',
|
||||||
|
'policy' => $policy_content,
|
||||||
|
'field' => DOMAIN_SOURCE_FIELD,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->doReassign($target_domain, $delete_options);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+16
-4
@@ -76,7 +76,7 @@ class DomainSourcePathProcessor implements OutboundPathProcessorInterface {
|
|||||||
/**
|
/**
|
||||||
* The domain storage.
|
* The domain storage.
|
||||||
*
|
*
|
||||||
* @var \Drupal\domain\DomainStorageInterface
|
* @var \Drupal\domain\DomainStorageInterface|null
|
||||||
*/
|
*/
|
||||||
protected $domainStorage;
|
protected $domainStorage;
|
||||||
|
|
||||||
@@ -100,7 +100,6 @@ class DomainSourcePathProcessor implements OutboundPathProcessorInterface {
|
|||||||
$this->entityTypeManager = $entity_type_manager;
|
$this->entityTypeManager = $entity_type_manager;
|
||||||
$this->aliasManager = $alias_manager;
|
$this->aliasManager = $alias_manager;
|
||||||
$this->configFactory = $config_factory;
|
$this->configFactory = $config_factory;
|
||||||
$this->domainStorage = $entity_type_manager->getStorage('domain');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,7 +158,7 @@ class DomainSourcePathProcessor implements OutboundPathProcessorInterface {
|
|||||||
$target_id = domain_source_get($entity);
|
$target_id = domain_source_get($entity);
|
||||||
}
|
}
|
||||||
if (!empty($target_id)) {
|
if (!empty($target_id)) {
|
||||||
$source = $this->domainStorage->load($target_id);
|
$source = $this->domainStorage()->load($target_id);
|
||||||
}
|
}
|
||||||
$options['entity'] = $entity;
|
$options['entity'] = $entity;
|
||||||
$options['entity_type'] = $entity->getEntityTypeId();
|
$options['entity_type'] = $entity->getEntityTypeId();
|
||||||
@@ -169,7 +168,7 @@ class DomainSourcePathProcessor implements OutboundPathProcessorInterface {
|
|||||||
else {
|
else {
|
||||||
if (isset($options['domain_target_id'])) {
|
if (isset($options['domain_target_id'])) {
|
||||||
$target_id = $options['domain_target_id'];
|
$target_id = $options['domain_target_id'];
|
||||||
$source = $this->domainStorage->load($target_id);
|
$source = $this->domainStorage()->load($target_id);
|
||||||
}
|
}
|
||||||
$this->moduleHandler->alter('domain_source_path', $source, $path, $options);
|
$this->moduleHandler->alter('domain_source_path', $source, $path, $options);
|
||||||
}
|
}
|
||||||
@@ -279,4 +278,17 @@ class DomainSourcePathProcessor implements OutboundPathProcessorInterface {
|
|||||||
return $this->activeDomain;
|
return $this->activeDomain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the domain storage handler.
|
||||||
|
*
|
||||||
|
* @return \Drupal\domain\DomainStorageInterface
|
||||||
|
* The domain storage handler.
|
||||||
|
*/
|
||||||
|
protected function domainStorage() {
|
||||||
|
if (!$this->domainStorage) {
|
||||||
|
$this->domainStorage = $this->entityTypeManager->getStorage('domain');
|
||||||
|
}
|
||||||
|
return $this->domainStorage;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -14,8 +14,8 @@ dependencies:
|
|||||||
- serialization
|
- serialization
|
||||||
- user
|
- user
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-11-14
|
# Information added by Drupal.org packaging script on 2019-02-21
|
||||||
version: '8.x-1.0-alpha14+9-dev'
|
version: '8.x-1.0-alpha15'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain'
|
project: 'domain'
|
||||||
datestamp: 1542230887
|
datestamp: 1550763190
|
||||||
|
|||||||
+40
@@ -141,4 +141,44 @@ class DomainSourceElementTest extends DomainTestBase {
|
|||||||
$this->assert(strpos($url, 'node/' . $nid . '/edit') === FALSE, 'Form submitted.');
|
$this->assert(strpos($url, 'node/' . $nid . '/edit') === FALSE, 'Form submitted.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for https://www.drupal.org/project/domain/issues/3010256.
|
||||||
|
*/
|
||||||
|
public function testAnonForm() {
|
||||||
|
// Editor with no domain permissions should not see the element.
|
||||||
|
$editor = $this->drupalCreateUser([
|
||||||
|
'create article content',
|
||||||
|
]);
|
||||||
|
$this->drupalLogin($editor);
|
||||||
|
|
||||||
|
$this->drupalGet('node/add/article');
|
||||||
|
$this->assertSession()->statusCodeEquals(200);
|
||||||
|
|
||||||
|
$locator = DOMAIN_SOURCE_FIELD;
|
||||||
|
$this->assertSession()->fieldNotExists($locator);
|
||||||
|
|
||||||
|
// Editor with domain permissions should see the element once they
|
||||||
|
// are assigned to domains.
|
||||||
|
$editor2 = $this->drupalCreateUser([
|
||||||
|
'create article content',
|
||||||
|
'publish to any assigned domain',
|
||||||
|
]);
|
||||||
|
$this->drupalLogin($editor2);
|
||||||
|
|
||||||
|
$this->drupalGet('node/add/article');
|
||||||
|
$this->assertSession()->statusCodeEquals(200);
|
||||||
|
|
||||||
|
$locator = DOMAIN_SOURCE_FIELD;
|
||||||
|
$this->assertSession()->fieldNotExists($locator);
|
||||||
|
|
||||||
|
// Domain assignment.
|
||||||
|
$ids = ['example_com', 'one_example_com'];
|
||||||
|
$this->addDomainsToEntity('user', $editor2->id(), $ids, DOMAIN_ACCESS_FIELD);
|
||||||
|
|
||||||
|
$this->drupalGet('node/add/article');
|
||||||
|
$this->assertSession()->statusCodeEquals(200);
|
||||||
|
|
||||||
|
$this->assertSession()->fieldExists($locator);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-58
@@ -1,58 +0,0 @@
|
|||||||
diff --git a/domain_site_settings.services.yml b/domain_site_settings.services.yml
|
|
||||||
index 65e9113..6ebd87d 100644
|
|
||||||
--- a/domain_site_settings.services.yml
|
|
||||||
+++ b/domain_site_settings.services.yml
|
|
||||||
@@ -1,6 +1,6 @@
|
|
||||||
services:
|
|
||||||
domain_site_settings.overrider:
|
|
||||||
class: \Drupal\domain_site_settings\Configuration\DomainConfigOverride
|
|
||||||
- arguments: ['@domain.negotiator', '@config.factory']
|
|
||||||
+ arguments: ['@config.factory']
|
|
||||||
tags:
|
|
||||||
- {name: config.factory.override, priority: 5}
|
|
||||||
diff --git a/src/Configuration/DomainConfigOverride.php b/src/Configuration/DomainConfigOverride.php
|
|
||||||
index b2571b4..506feef 100644
|
|
||||||
--- a/src/Configuration/DomainConfigOverride.php
|
|
||||||
+++ b/src/Configuration/DomainConfigOverride.php
|
|
||||||
@@ -16,13 +16,6 @@ use Drupal\Core\Config\ConfigFactoryInterface;
|
|
||||||
*/
|
|
||||||
class DomainConfigOverride implements ConfigFactoryOverrideInterface {
|
|
||||||
|
|
||||||
- /**
|
|
||||||
- * The Domain negotiator.
|
|
||||||
- *
|
|
||||||
- * @var \Drupal\domain\DomainNegotiatorInterface
|
|
||||||
- */
|
|
||||||
- protected $negotiator;
|
|
||||||
-
|
|
||||||
/**
|
|
||||||
* The config factory.
|
|
||||||
*
|
|
||||||
@@ -33,16 +26,11 @@ class DomainConfigOverride implements ConfigFactoryOverrideInterface {
|
|
||||||
/**
|
|
||||||
* Constructs a DomainSourcePathProcessor object.
|
|
||||||
*
|
|
||||||
- * The domain loader.
|
|
||||||
- * @param \Drupal\domain\DomainNegotiatorInterface $negotiator
|
|
||||||
- * The domain negotiator.
|
|
||||||
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
|
|
||||||
* The module handler service.
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
- DomainNegotiatorInterface $negotiator,
|
|
||||||
ConfigFactoryInterface $config_factory) {
|
|
||||||
- $this->negotiator = $negotiator;
|
|
||||||
$this->configFactory = $config_factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -59,7 +47,9 @@ class DomainConfigOverride implements ConfigFactoryOverrideInterface {
|
|
||||||
public function loadOverrides($names) {
|
|
||||||
$overrides = array();
|
|
||||||
if (in_array('system.site', $names)) {
|
|
||||||
- $domain = $this->negotiator->getActiveDomain();
|
|
||||||
+ /* @var \Drupal\domain\DomainNegotiator $negotiator */
|
|
||||||
+ $negotiator = \Drupal::service('domain.negotiator');
|
|
||||||
+ $domain = $negotiator->getActiveDomain();
|
|
||||||
if (!empty($domain)) {
|
|
||||||
$domain_key = $domain->id();
|
|
||||||
$configFactory = $this->configFactory->get('domain_site_settings.domainconfigsettings');
|
|
||||||
@@ -2,15 +2,15 @@ name: Domain Site Settings
|
|||||||
type: module
|
type: module
|
||||||
description: 'Basic Site Setting for Domains.'
|
description: 'Basic Site Setting for Domains.'
|
||||||
dependencies:
|
dependencies:
|
||||||
- domain
|
- domain:domain
|
||||||
- domain_config
|
- domain:domain_config
|
||||||
|
|
||||||
package: Domain
|
package: Domain
|
||||||
# core: 8.x
|
# core: 8.x
|
||||||
configure: domain_site_settings.list
|
configure: domain_site_settings.list
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2017-04-04
|
# Information added by Drupal.org packaging script on 2018-09-23
|
||||||
version: '8.x-1.2'
|
version: '8.x-1.3'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'domain_site_settings'
|
project: 'domain_site_settings'
|
||||||
datestamp: 1491339784
|
datestamp: 1537684984
|
||||||
|
|||||||
-1
@@ -4,4 +4,3 @@ domain_site_settings.menu_domain_list:
|
|||||||
description: 'Change domains site name, email address, slogan, default front page, and error pages.'
|
description: 'Change domains site name, email address, slogan, default front page, and error pages.'
|
||||||
parent: domain.admin
|
parent: domain.admin
|
||||||
weight: 10
|
weight: 10
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
domain_site_settings.overrider:
|
domain_site_settings.overrider:
|
||||||
class: \Drupal\domain_site_settings\Configuration\DomainConfigOverride
|
class: \Drupal\domain_site_settings\Configuration\DomainConfigOverride
|
||||||
arguments: ['@config.factory']
|
arguments: ['@domain.negotiator', '@config.factory']
|
||||||
tags:
|
tags:
|
||||||
- {name: config.factory.override, priority: 5}
|
- {name: config.factory.override, priority: 5}
|
||||||
|
|||||||
+18
-7
@@ -5,7 +5,6 @@ namespace Drupal\domain_site_settings\Configuration;
|
|||||||
use Drupal\Core\Cache\CacheableMetadata;
|
use Drupal\Core\Cache\CacheableMetadata;
|
||||||
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
|
use Drupal\Core\Config\ConfigFactoryOverrideInterface;
|
||||||
use Drupal\Core\Config\StorageInterface;
|
use Drupal\Core\Config\StorageInterface;
|
||||||
use Drupal\domain\DomainLoaderInterface;
|
|
||||||
use Drupal\domain\DomainNegotiatorInterface;
|
use Drupal\domain\DomainNegotiatorInterface;
|
||||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||||
|
|
||||||
@@ -16,6 +15,13 @@ use Drupal\Core\Config\ConfigFactoryInterface;
|
|||||||
*/
|
*/
|
||||||
class DomainConfigOverride implements ConfigFactoryOverrideInterface {
|
class DomainConfigOverride implements ConfigFactoryOverrideInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Domain negotiator.
|
||||||
|
*
|
||||||
|
* @var \Drupal\domain\DomainNegotiatorInterface
|
||||||
|
*/
|
||||||
|
protected $negotiator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The config factory.
|
* The config factory.
|
||||||
*
|
*
|
||||||
@@ -26,11 +32,15 @@ class DomainConfigOverride implements ConfigFactoryOverrideInterface {
|
|||||||
/**
|
/**
|
||||||
* Constructs a DomainSourcePathProcessor object.
|
* Constructs a DomainSourcePathProcessor object.
|
||||||
*
|
*
|
||||||
|
* @param \Drupal\domain\DomainNegotiatorInterface $negotiator
|
||||||
|
* The domain negotiator.
|
||||||
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
|
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
|
||||||
* The module handler service.
|
* The module handler service.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
DomainNegotiatorInterface $negotiator,
|
||||||
ConfigFactoryInterface $config_factory) {
|
ConfigFactoryInterface $config_factory) {
|
||||||
|
$this->negotiator = $negotiator;
|
||||||
$this->configFactory = $config_factory;
|
$this->configFactory = $config_factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,12 +54,10 @@ class DomainConfigOverride implements ConfigFactoryOverrideInterface {
|
|||||||
* An array keyed by configuration name of override data. Override data
|
* An array keyed by configuration name of override data. Override data
|
||||||
* contains a nested array structure of overrides.
|
* contains a nested array structure of overrides.
|
||||||
*/
|
*/
|
||||||
public function loadOverrides($names) {
|
public function loadOverrides($names = []) {
|
||||||
$overrides = array();
|
$overrides = [];
|
||||||
if (in_array('system.site', $names)) {
|
if (in_array('system.site', $names)) {
|
||||||
/* @var \Drupal\domain\DomainNegotiator $negotiator */
|
$domain = $this->negotiator->getActiveDomain();
|
||||||
$negotiator = \Drupal::service('domain.negotiator');
|
|
||||||
$domain = $negotiator->getActiveDomain();
|
|
||||||
if (!empty($domain)) {
|
if (!empty($domain)) {
|
||||||
$domain_key = $domain->id();
|
$domain_key = $domain->id();
|
||||||
$configFactory = $this->configFactory->get('domain_site_settings.domainconfigsettings');
|
$configFactory = $this->configFactory->get('domain_site_settings.domainconfigsettings');
|
||||||
@@ -60,6 +68,8 @@ class DomainConfigOverride implements ConfigFactoryOverrideInterface {
|
|||||||
$site_403 = $configFactory->get($domain_key . '.site_403');
|
$site_403 = $configFactory->get($domain_key . '.site_403');
|
||||||
$site_404 = $configFactory->get($domain_key . '.site_404');
|
$site_404 = $configFactory->get($domain_key . '.site_404');
|
||||||
$site_front = $configFactory->get($domain_key . '.site_frontpage');
|
$site_front = $configFactory->get($domain_key . '.site_frontpage');
|
||||||
|
$front = ($site_front !== \NULL) ? $site_front : '/node';
|
||||||
|
|
||||||
// Create the new settings array to override the configuration.
|
// Create the new settings array to override the configuration.
|
||||||
$overrides['system.site'] = [
|
$overrides['system.site'] = [
|
||||||
'name' => $site_name,
|
'name' => $site_name,
|
||||||
@@ -68,7 +78,8 @@ class DomainConfigOverride implements ConfigFactoryOverrideInterface {
|
|||||||
'page' => [
|
'page' => [
|
||||||
'403' => $site_403,
|
'403' => $site_403,
|
||||||
'404' => $site_404,
|
'404' => $site_404,
|
||||||
'front' => ($site_front !== NULL) ? $site_front : '/node']
|
'front' => $front,
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -25,7 +25,7 @@ class DomainSiteSettingsController extends ControllerBase {
|
|||||||
/**
|
/**
|
||||||
* Construct function.
|
* Construct function.
|
||||||
*
|
*
|
||||||
* @param DomainLoader $domain_loader
|
* @param \Drupal\domain\DomainLoader $domain_loader
|
||||||
* Load the domain records.
|
* Load the domain records.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@@ -37,7 +37,7 @@ class DomainSiteSettingsController extends ControllerBase {
|
|||||||
/**
|
/**
|
||||||
* Create function return static domain loader configuration.
|
* Create function return static domain loader configuration.
|
||||||
*
|
*
|
||||||
* @param ContainerInterface $container
|
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
|
||||||
* Load the ContainerInterface.
|
* Load the ContainerInterface.
|
||||||
*
|
*
|
||||||
* @return \static
|
* @return \static
|
||||||
@@ -62,22 +62,22 @@ class DomainSiteSettingsController extends ControllerBase {
|
|||||||
foreach ($domains as $domain) {
|
foreach ($domains as $domain) {
|
||||||
$row = [
|
$row = [
|
||||||
$domain->label(),
|
$domain->label(),
|
||||||
$domain->id(),
|
$domain->getCanonical(),
|
||||||
Link::fromTextAndUrl($this->t('Edit'), Url::fromRoute('domain_site_settings.config_form', array('domain_id' => $domain->id()))),
|
Link::fromTextAndUrl($this->t('Edit'), Url::fromRoute('domain_site_settings.config_form', ['domain_id' => $domain->id()])),
|
||||||
];
|
];
|
||||||
$rows[] = $row;
|
$rows[] = $row;
|
||||||
}
|
}
|
||||||
// Build a render array which will be themed as a table.
|
// Build a render array which will be themed as a table.
|
||||||
$build['pager_example'] = array(
|
$build['pager_example'] = [
|
||||||
'#rows' => $rows,
|
'#rows' => $rows,
|
||||||
'#header' => array(
|
'#header' => [
|
||||||
$this->t('Name'),
|
$this->t('Name'),
|
||||||
$this->t('Hostname'),
|
$this->t('Hostname'),
|
||||||
$this->t('Edit Settings')
|
$this->t('Edit Settings'),
|
||||||
),
|
],
|
||||||
'#type' => 'table',
|
'#type' => 'table',
|
||||||
'#empty' => $this->t('No domain record found.'),
|
'#empty' => $this->t('No domain record found.'),
|
||||||
);
|
];
|
||||||
return $build;
|
return $build;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-24
@@ -98,67 +98,64 @@ class DomainConfigSettingsForm extends ConfigFormBase {
|
|||||||
$site_mail = $config->get($domain_id . '.site_mail');
|
$site_mail = $config->get($domain_id . '.site_mail');
|
||||||
}
|
}
|
||||||
|
|
||||||
$form['site_information'] = array(
|
$form['site_information'] = [
|
||||||
'#type' => 'details',
|
'#type' => 'details',
|
||||||
'#title' => $this->t('Site details'),
|
'#title' => $this->t('Site details'),
|
||||||
'#open' => TRUE,
|
'#open' => TRUE,
|
||||||
);
|
];
|
||||||
$form['site_information']['site_name'] = array(
|
$form['site_information']['site_name'] = [
|
||||||
'#type' => 'textfield',
|
'#type' => 'textfield',
|
||||||
'#title' => $this->t('Site name'),
|
'#title' => $this->t('Site name'),
|
||||||
'#default_value' => ($config->get($domain_id) != NULL) ? $config->get($domain_id . '.site_name') : $site_config->get('name'),
|
'#default_value' => ($config->get($domain_id) != NULL) ? $config->get($domain_id . '.site_name') : $site_config->get('name'),
|
||||||
'#required' => TRUE,
|
'#required' => TRUE,
|
||||||
);
|
];
|
||||||
$form['site_information']['site_slogan'] = array(
|
$form['site_information']['site_slogan'] = [
|
||||||
'#type' => 'textfield',
|
'#type' => 'textfield',
|
||||||
'#title' => $this->t('Slogan'),
|
'#title' => $this->t('Slogan'),
|
||||||
'#default_value' => ($config->get($domain_id) != NULL) ? $config->get($domain_id . '.site_slogan') : $site_config->get('slogan'),
|
'#default_value' => ($config->get($domain_id) != NULL) ? $config->get($domain_id . '.site_slogan') : $site_config->get('slogan'),
|
||||||
'#description' => $this->t("How this is used depends on your site's theme."),
|
'#description' => $this->t("How this is used depends on your site's theme."),
|
||||||
);
|
];
|
||||||
$form['site_information']['site_mail'] = array(
|
$form['site_information']['site_mail'] = [
|
||||||
'#type' => 'email',
|
'#type' => 'email',
|
||||||
'#title' => $this->t('Email address'),
|
'#title' => $this->t('Email address'),
|
||||||
'#default_value' => $site_mail,
|
'#default_value' => $site_mail,
|
||||||
'#description' => $this->t("The <em>From</em> address in automated emails sent during registration and new password requests, and other notifications. (Use an address ending in your site's domain to help prevent this email being flagged as spam.)"),
|
'#description' => $this->t("The <em>From</em> address in automated emails sent during registration and new password requests, and other notifications. (Use an address ending in your site's domain to help prevent this email being flagged as spam.)"),
|
||||||
'#required' => TRUE,
|
'#required' => TRUE,
|
||||||
);
|
];
|
||||||
|
$form['front_page'] = [
|
||||||
$form['front_page'] = array(
|
|
||||||
'#type' => 'details',
|
'#type' => 'details',
|
||||||
'#title' => $this->t('Front page'),
|
'#title' => $this->t('Front page'),
|
||||||
'#open' => TRUE,
|
'#open' => TRUE,
|
||||||
);
|
];
|
||||||
$front_page = $site_config->get('page.front') != '/user/login' ? $this->aliasManager->getAliasByPath($site_config->get('page.front')) : '';
|
$front_page = $site_config->get('page.front') != '/user/login' ? $this->aliasManager->getAliasByPath($site_config->get('page.front')) : '';
|
||||||
|
|
||||||
$front_page = ($config->get($domain_id) != NULL) ? $config->get($domain_id . '.site_frontpage') : $front_page;
|
$front_page = ($config->get($domain_id) != NULL) ? $config->get($domain_id . '.site_frontpage') : $front_page;
|
||||||
|
$form['front_page']['site_frontpage'] = [
|
||||||
$form['front_page']['site_frontpage'] = array(
|
|
||||||
'#type' => 'textfield',
|
'#type' => 'textfield',
|
||||||
'#title' => $this->t('Default front page'),
|
'#title' => $this->t('Default front page'),
|
||||||
'#default_value' => $front_page,
|
'#default_value' => $front_page,
|
||||||
'#size' => 40,
|
'#size' => 40,
|
||||||
'#description' => $this->t('Optionally, specify a relative URL to display as the front page. Leave blank to display the default front page.'),
|
'#description' => $this->t('Optionally, specify a relative URL to display as the front page. Leave blank to display the default front page.'),
|
||||||
'#field_prefix' => $this->requestContext->getCompleteBaseUrl(),
|
'#field_prefix' => $this->requestContext->getCompleteBaseUrl(),
|
||||||
);
|
];
|
||||||
$form['error_page'] = array(
|
$form['error_page'] = [
|
||||||
'#type' => 'details',
|
'#type' => 'details',
|
||||||
'#title' => $this->t('Error pages'),
|
'#title' => $this->t('Error pages'),
|
||||||
'#open' => TRUE,
|
'#open' => TRUE,
|
||||||
);
|
];
|
||||||
$form['error_page']['site_403'] = array(
|
$form['error_page']['site_403'] = [
|
||||||
'#type' => 'textfield',
|
'#type' => 'textfield',
|
||||||
'#title' => $this->t('Default 403 (access denied) page'),
|
'#title' => $this->t('Default 403 (access denied) page'),
|
||||||
'#default_value' => ($config->get($domain_id) !== NULL) ? $config->get($domain_id . '.site_403') : $site_config->get('page.403'),
|
'#default_value' => ($config->get($domain_id) !== NULL) ? $config->get($domain_id . '.site_403') : $site_config->get('page.403'),
|
||||||
'#size' => 40,
|
'#size' => 40,
|
||||||
'#description' => $this->t('This page is displayed when the requested document is denied to the current user. Leave blank to display a generic "access denied" page.'),
|
'#description' => $this->t('This page is displayed when the requested document is denied to the current user. Leave blank to display a generic "access denied" page.'),
|
||||||
);
|
];
|
||||||
$form['error_page']['site_404'] = array(
|
$form['error_page']['site_404'] = [
|
||||||
'#type' => 'textfield',
|
'#type' => 'textfield',
|
||||||
'#title' => $this->t('Default 404 (not found) page'),
|
'#title' => $this->t('Default 404 (not found) page'),
|
||||||
'#default_value' => ($config->get($domain_id) !== NULL) ? $config->get($domain_id . '.site_404') : $site_config->get('page.404'),
|
'#default_value' => ($config->get($domain_id) !== NULL) ? $config->get($domain_id . '.site_404') : $site_config->get('page.404'),
|
||||||
'#size' => 40,
|
'#size' => 40,
|
||||||
'#description' => $this->t('This page is displayed when no other content matches the requested document. Leave blank to display a generic "page not found" page.'),
|
'#description' => $this->t('This page is displayed when no other content matches the requested document. Leave blank to display a generic "page not found" page.'),
|
||||||
);
|
];
|
||||||
$form['domain_id'] = [
|
$form['domain_id'] = [
|
||||||
'#type' => 'hidden',
|
'#type' => 'hidden',
|
||||||
'#title' => $this->t('Domain ID'),
|
'#title' => $this->t('Domain ID'),
|
||||||
@@ -185,7 +182,7 @@ class DomainConfigSettingsForm extends ConfigFormBase {
|
|||||||
$form_state->setErrorByName('site_frontpage', $this->t("The path '%path' has to start with a slash.", ['%path' => $form_state->getValue('site_frontpage')]));
|
$form_state->setErrorByName('site_frontpage', $this->t("The path '%path' has to start with a slash.", ['%path' => $form_state->getValue('site_frontpage')]));
|
||||||
}
|
}
|
||||||
if (!$this->pathValidator->isValid($form_state->getValue('site_frontpage'))) {
|
if (!$this->pathValidator->isValid($form_state->getValue('site_frontpage'))) {
|
||||||
$form_state->setErrorByName('site_frontpage', $this->t("The path '%path' is either invalid or you do not have access to it.", array('%path' => $form_state->getValue('site_frontpage'))));
|
$form_state->setErrorByName('site_frontpage', $this->t("The path '%path' is either invalid or you do not have access to it.", ['%path' => $form_state->getValue('site_frontpage')]));
|
||||||
}
|
}
|
||||||
// Get the normal paths of both error pages.
|
// Get the normal paths of both error pages.
|
||||||
if (!$form_state->isValueEmpty('site_403')) {
|
if (!$form_state->isValueEmpty('site_403')) {
|
||||||
@@ -202,11 +199,11 @@ class DomainConfigSettingsForm extends ConfigFormBase {
|
|||||||
}
|
}
|
||||||
// Validate 403 error path.
|
// Validate 403 error path.
|
||||||
if (!$form_state->isValueEmpty('site_403') && !$this->pathValidator->isValid($form_state->getValue('site_403'))) {
|
if (!$form_state->isValueEmpty('site_403') && !$this->pathValidator->isValid($form_state->getValue('site_403'))) {
|
||||||
$form_state->setErrorByName('site_403', $this->t("The path '%path' is either invalid or you do not have access to it.", array('%path' => $form_state->getValue('site_403'))));
|
$form_state->setErrorByName('site_403', $this->t("The path '%path' is either invalid or you do not have access to it.", ['%path' => $form_state->getValue('site_403')]));
|
||||||
}
|
}
|
||||||
// Validate 404 error path.
|
// Validate 404 error path.
|
||||||
if (!$form_state->isValueEmpty('site_404') && !$this->pathValidator->isValid($form_state->getValue('site_404'))) {
|
if (!$form_state->isValueEmpty('site_404') && !$this->pathValidator->isValid($form_state->getValue('site_404'))) {
|
||||||
$form_state->setErrorByName('site_404', $this->t("The path '%path' is either invalid or you do not have access to it.", array('%path' => $form_state->getValue('site_404'))));
|
$form_state->setErrorByName('site_404', $this->t("The path '%path' is either invalid or you do not have access to it.", ['%path' => $form_state->getValue('site_404')]));
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::validateForm($form, $form_state);
|
parent::validateForm($form, $form_state);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
Module: Matomo Analytics
|
Module: Matomo Analytics
|
||||||
Author: Alexander Hass <http://drupal.org/user/85918>
|
Author: Alexander Hass <https://drupal.org/user/85918>
|
||||||
|
|
||||||
|
|
||||||
Description
|
Description
|
||||||
@@ -46,7 +46,7 @@ user with 'Administer Matomo' permission.
|
|||||||
Like the blocks visibility settings in Drupal core, there is a choice for
|
Like the blocks visibility settings in Drupal core, there is a choice for
|
||||||
"Add if the following PHP code returns TRUE." Sample PHP snippets that can be
|
"Add if the following PHP code returns TRUE." Sample PHP snippets that can be
|
||||||
used in this textarea can be found on the handbook page "Overview-approach to
|
used in this textarea can be found on the handbook page "Overview-approach to
|
||||||
block visibility" at http://drupal.org/node/64135.
|
block visibility" at https://drupal.org/node/64135.
|
||||||
|
|
||||||
Custom variables
|
Custom variables
|
||||||
=================
|
=================
|
||||||
@@ -65,7 +65,7 @@ Value: [current-user:matomo-role-ids]
|
|||||||
Scope: Visitor
|
Scope: Visitor
|
||||||
|
|
||||||
More details about custom variables can be found in the Matomo API documentation
|
More details about custom variables can be found in the Matomo API documentation
|
||||||
at http://matomo.org/docs/javascript-tracking/#toc-custom-variables.
|
at https://matomo.org/docs/javascript-tracking/#toc-custom-variables.
|
||||||
|
|
||||||
|
|
||||||
Advanced Settings
|
Advanced Settings
|
||||||
@@ -80,7 +80,7 @@ file locally.
|
|||||||
|
|
||||||
Known issues
|
Known issues
|
||||||
============
|
============
|
||||||
Drupal requirements (http://drupal.org/requirements) tell you to configure
|
Drupal requirements (https://drupal.org/requirements) tell you to configure
|
||||||
PHP with "session.save_handler = user", but your Matomo installation may
|
PHP with "session.save_handler = user", but your Matomo installation may
|
||||||
not work with this configuration and gives you a server error 500.
|
not work with this configuration and gives you a server error 500.
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,10 @@
|
|||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://www.drupal.org/project/issues/matomo",
|
"issues": "https://www.drupal.org/project/issues/matomo",
|
||||||
"source": "http://git.drupal.org/project/matomo.git"
|
"source": "https://git.drupal.org/project/matomo.git"
|
||||||
},
|
},
|
||||||
"license": "GPL-2.0+",
|
"license": "GPL-2.0+",
|
||||||
"require": {}
|
"require": {
|
||||||
|
"drupal/core": "~8.5"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ description: "Adds Matomo javascript tracking code to all your site's pages."
|
|||||||
package: Statistics
|
package: Statistics
|
||||||
# core: 8.x
|
# core: 8.x
|
||||||
configure: matomo.admin_settings_form
|
configure: matomo.admin_settings_form
|
||||||
|
dependencies:
|
||||||
|
- drupal:system (>= 8.5)
|
||||||
test_dependencies:
|
test_dependencies:
|
||||||
- php:php
|
- php:php
|
||||||
- token:token
|
- token:token
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-07-13
|
# Information added by Drupal.org packaging script on 2019-02-08
|
||||||
version: '8.x-1.7'
|
version: '8.x-1.9'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'matomo'
|
project: 'matomo'
|
||||||
datestamp: 1531470224
|
datestamp: 1549615102
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ function matomo_install() {
|
|||||||
$role->grantPermission('opt-in or out of matomo tracking');
|
$role->grantPermission('opt-in or out of matomo tracking');
|
||||||
$success = $role->save();
|
$success = $role->save();
|
||||||
if ($success) {
|
if ($success) {
|
||||||
drupal_set_message(t('Module %module granted %permission permission to authenticated users.', ['%module' => 'Matomo Analytics', '%permission' => t('Opt-in or out of tracking')]), 'status');
|
$messenger = \Drupal::messenger();
|
||||||
|
$messenger->addMessage(t('Module %module granted %permission permission to authenticated users.', ['%module' => 'Matomo Analytics', '%permission' => t('Opt-in or out of tracking')]), 'status');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* Adds the required Javascript to all your Drupal pages to allow tracking by
|
* Adds the required Javascript to all your Drupal pages to allow tracking by
|
||||||
* the Matomo statistics package.
|
* the Matomo statistics package.
|
||||||
*
|
*
|
||||||
* @author: Alexander Hass <http://drupal.org/user/85918>
|
* @author: Alexander Hass <https://drupal.org/user/85918>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use Drupal\Component\Serialization\Json;
|
use Drupal\Component\Serialization\Json;
|
||||||
@@ -19,22 +19,18 @@ use Drupal\Core\Form\FormStateInterface;
|
|||||||
use Drupal\Core\Routing\RouteMatchInterface;
|
use Drupal\Core\Routing\RouteMatchInterface;
|
||||||
use Drupal\Core\Site\Settings;
|
use Drupal\Core\Site\Settings;
|
||||||
use Drupal\Core\Url;
|
use Drupal\Core\Url;
|
||||||
|
use Drupal\matomo\MatomoInterface;
|
||||||
use Drupal\node\NodeInterface;
|
use Drupal\node\NodeInterface;
|
||||||
use GuzzleHttp\Exception\RequestException;
|
use GuzzleHttp\Exception\RequestException;
|
||||||
use Drupal\matomo\Component\Render\MatomoJavaScriptSnippet;
|
use Drupal\matomo\Component\Render\MatomoJavaScriptSnippet;
|
||||||
|
|
||||||
/**
|
|
||||||
* Define the default file extension list that should be tracked as download.
|
|
||||||
*/
|
|
||||||
define('MATOMO_TRACKFILES_EXTENSIONS', '7z|aac|arc|arj|asf|asx|avi|bin|csv|doc(x|m)?|dot(x|m)?|exe|flv|gif|gz|gzip|hqx|jar|jpe?g|js|mp(2|3|4|e?g)|mov(ie)?|msi|msp|pdf|phps|png|ppt(x|m)?|pot(x|m)?|pps(x|m)?|ppam|sld(x|m)?|thmx|qtm?|ra(m|r)?|sea|sit|tar|tgz|torrent|txt|wav|wma|wmv|wpd|xls(x|m|b)?|xlt(x|m)|xlam|xml|z|zip');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements hook_help().
|
* Implements hook_help().
|
||||||
*/
|
*/
|
||||||
function matomo_help($route_name, RouteMatchInterface $route_match) {
|
function matomo_help($route_name, RouteMatchInterface $route_match) {
|
||||||
switch ($route_name) {
|
switch ($route_name) {
|
||||||
case 'matomo.admin_settings_form':
|
case 'matomo.admin_settings_form':
|
||||||
return t('<a href=":pk_url">Matomo Analytics</a> is an open source (GPL license) web analytics software. It gives interesting reports on your website visitors, your popular pages, the search engines keywords they used, the language they speak... and so much more. Matomo aims to be an open source alternative to Google Analytics.', [':pk_url' => 'http://www.matomo.org/']);
|
return t('<a href=":pk_url">Matomo Analytics</a> is an open source (GPL license) web analytics software. It gives interesting reports on your website visitors, your popular pages, the search engines keywords they used, the language they speak... and so much more. Matomo aims to be an open source alternative to Google Analytics.', [':pk_url' => 'https://www.matomo.org/']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +110,7 @@ function matomo_page_attachments(array &$page) {
|
|||||||
'error' => t('Error message'),
|
'error' => t('Error message'),
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach (drupal_get_messages(NULL, FALSE) as $type => $messages) {
|
foreach (\Drupal::messenger()->all(NULL, FALSE) as $type => $messages) {
|
||||||
// Track only the selected message types.
|
// Track only the selected message types.
|
||||||
if (in_array($type, $message_types)) {
|
if (in_array($type, $message_types)) {
|
||||||
foreach ($messages as $message) {
|
foreach ($messages as $message) {
|
||||||
@@ -198,7 +194,7 @@ function matomo_page_attachments(array &$page) {
|
|||||||
$codesnippet_after = $config->get('codesnippet.after');
|
$codesnippet_after = $config->get('codesnippet.after');
|
||||||
|
|
||||||
// Build tracker code.
|
// Build tracker code.
|
||||||
// @see http://matomo.org/docs/javascript-tracking/#toc-asynchronous-tracking
|
// @see https://matomo.org/docs/javascript-tracking/#toc-asynchronous-tracking
|
||||||
$script = 'var _paq = _paq || [];';
|
$script = 'var _paq = _paq || [];';
|
||||||
$script .= '(function(){';
|
$script .= '(function(){';
|
||||||
$script .= 'var u=(("https:" == document.location.protocol) ? "' . UrlHelper::filterBadProtocol($url_https) . '" : "' . UrlHelper::filterBadProtocol($url_http) . '");';
|
$script .= 'var u=(("https:" == document.location.protocol) ? "' . UrlHelper::filterBadProtocol($url_https) . '" : "' . UrlHelper::filterBadProtocol($url_http) . '");';
|
||||||
@@ -220,7 +216,7 @@ function matomo_page_attachments(array &$page) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Custom file download extensions.
|
// Custom file download extensions.
|
||||||
if ($config->get('track.files') && !($config->get('track.files_extensions') == MATOMO_TRACKFILES_EXTENSIONS)) {
|
if ($config->get('track.files') && !($config->get('track.files_extensions') == MatomoInterface::MATOMO_TRACKFILES_EXTENSIONS)) {
|
||||||
$script .= '_paq.push(["setDownloadExtensions", ' . Json::encode($config->get('track.files_extensions')) . ']);';
|
$script .= '_paq.push(["setDownloadExtensions", ' . Json::encode($config->get('track.files_extensions')) . ']);';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +275,7 @@ function matomo_page_attachments(array &$page) {
|
|||||||
];
|
];
|
||||||
// Disable the download & outlink tracking for specific CSS classes.
|
// Disable the download & outlink tracking for specific CSS classes.
|
||||||
// Custom code snippets with 'setIgnoreClasses' will override the value.
|
// Custom code snippets with 'setIgnoreClasses' will override the value.
|
||||||
// @see http://developer.matomo.org/api-reference/tracking-javascript#disable-the-download-amp-outlink-tracking-for-specific-css-classes
|
// @see https://developer.matomo.org/api-reference/tracking-javascript#disable-the-download-amp-outlink-tracking-for-specific-css-classes
|
||||||
$script .= '_paq.push(["setIgnoreClasses", ' . Json::encode($ignore_classes) . ']);';
|
$script .= '_paq.push(["setIgnoreClasses", ' . Json::encode($ignore_classes) . ']);';
|
||||||
|
|
||||||
// Enable download & outlink link tracking.
|
// Enable download & outlink link tracking.
|
||||||
@@ -441,11 +437,12 @@ function matomo_user_profile_form_submit($form, FormStateInterface $form_state)
|
|||||||
*/
|
*/
|
||||||
function matomo_cron() {
|
function matomo_cron() {
|
||||||
$config = \Drupal::config('matomo.settings');
|
$config = \Drupal::config('matomo.settings');
|
||||||
|
$request_time = \Drupal::time()->getRequestTime();
|
||||||
|
|
||||||
// Regenerate the piwik.js every day.
|
// Regenerate the piwik.js every day.
|
||||||
if (REQUEST_TIME - \Drupal::state()->get('matomo.last_cache') >= 86400 && $config->get('cache')) {
|
if ($request_time - \Drupal::state()->get('matomo.last_cache') >= 86400 && $config->get('cache')) {
|
||||||
_matomo_cache($config->get('url_http') . 'piwik.js', TRUE);
|
_matomo_cache($config->get('url_http') . 'piwik.js', TRUE);
|
||||||
\Drupal::state()->set('matomo.last_cache', REQUEST_TIME);
|
\Drupal::state()->set('matomo.last_cache', $request_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,37 @@ namespace Drupal\matomo\Form;
|
|||||||
|
|
||||||
use Drupal\Component\Utility\Unicode;
|
use Drupal\Component\Utility\Unicode;
|
||||||
use Drupal\Component\Utility\UrlHelper;
|
use Drupal\Component\Utility\UrlHelper;
|
||||||
|
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||||
|
use Drupal\Core\Extension\ModuleHandler;
|
||||||
use Drupal\Core\Form\ConfigFormBase;
|
use Drupal\Core\Form\ConfigFormBase;
|
||||||
use Drupal\Core\Form\FormStateInterface;
|
use Drupal\Core\Form\FormStateInterface;
|
||||||
|
use Drupal\Core\Session\AccountInterface;
|
||||||
|
use Drupal\matomo\MatomoInterface;
|
||||||
use GuzzleHttp\Exception\RequestException;
|
use GuzzleHttp\Exception\RequestException;
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure Matomo settings for this site.
|
* Configure Matomo settings for this site.
|
||||||
*/
|
*/
|
||||||
class MatomoAdminSettingsForm extends ConfigFormBase {
|
class MatomoAdminSettingsForm extends ConfigFormBase {
|
||||||
|
|
||||||
|
protected $moduleHandler;
|
||||||
|
|
||||||
|
protected $currentUser;
|
||||||
|
|
||||||
|
protected $httpClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function __construct(ConfigFactoryInterface $config_factory, AccountInterface $currentUser, ModuleHandler $moduleHandler, Client $httpClient) {
|
||||||
|
parent::__construct($config_factory);
|
||||||
|
$this->currentUser = $currentUser;
|
||||||
|
$this->moduleHandler = $moduleHandler;
|
||||||
|
$this->httpClient = $httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@@ -117,7 +139,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Page specific visibility configurations.
|
// Page specific visibility configurations.
|
||||||
$account = \Drupal::currentUser();
|
$account = $this->currentUser;
|
||||||
$php_access = $account->hasPermission('use php for matomo tracking visibility');
|
$php_access = $account->hasPermission('use php for matomo tracking visibility');
|
||||||
$visibility_request_path_pages = $config->get('visibility.request_path_pages');
|
$visibility_request_path_pages = $config->get('visibility.request_path_pages');
|
||||||
|
|
||||||
@@ -140,7 +162,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
];
|
];
|
||||||
$description = $this->t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", ['%blog' => '/blog', '%blog-wildcard' => '/blog/*', '%front' => '<front>']);
|
$description = $this->t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", ['%blog' => '/blog', '%blog-wildcard' => '/blog/*', '%front' => '<front>']);
|
||||||
|
|
||||||
if (\Drupal::moduleHandler()->moduleExists('php') && $php_access) {
|
if ($this->moduleHandler->moduleExists('php') && $php_access) {
|
||||||
$options[] = $this->t('Pages on which this PHP code returns <code>TRUE</code> (experts only)');
|
$options[] = $this->t('Pages on which this PHP code returns <code>TRUE</code> (experts only)');
|
||||||
$title = $this->t('Pages or PHP code');
|
$title = $this->t('Pages or PHP code');
|
||||||
$description .= ' ' . $this->t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', ['%php' => '<?php ?>']);
|
$description .= ' ' . $this->t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', ['%php' => '<?php ?>']);
|
||||||
@@ -207,13 +229,13 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
1 => $this->t('Tracking on by default, users with %permission permission can opt out', $t_permission),
|
1 => $this->t('Tracking on by default, users with %permission permission can opt out', $t_permission),
|
||||||
2 => $this->t('Tracking off by default, users with %permission permission can opt in', $t_permission),
|
2 => $this->t('Tracking off by default, users with %permission permission can opt in', $t_permission),
|
||||||
],
|
],
|
||||||
'#default_value' => !empty($visibility_user_account_mode) ? $visibility_user_account_mode : 1,
|
'#default_value' => !empty($visibility_user_account_mode) ? $visibility_user_account_mode : 0,
|
||||||
];
|
];
|
||||||
$form['tracking']['user_visibility_settings']['matomo_trackuserid'] = [
|
$form['tracking']['user_visibility_settings']['matomo_trackuserid'] = [
|
||||||
'#type' => 'checkbox',
|
'#type' => 'checkbox',
|
||||||
'#title' => $this->t('Track User ID'),
|
'#title' => $this->t('Track User ID'),
|
||||||
'#default_value' => $config->get('track.userid'),
|
'#default_value' => $config->get('track.userid'),
|
||||||
'#description' => $this->t('User ID enables the analysis of groups of sessions, across devices, using a unique, persistent, and non-personally identifiable ID string representing a user. <a href=":url">Learn more about the benefits of using User ID</a>.', [':url' => 'http://matomo.org/docs/user-id/']),
|
'#description' => $this->t('User ID enables the analysis of groups of sessions, across devices, using a unique, persistent, and non-personally identifiable ID string representing a user. <a href=":url">Learn more about the benefits of using User ID</a>.', [':url' => 'https://matomo.org/docs/user-id/']),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Link specific configurations.
|
// Link specific configurations.
|
||||||
@@ -237,7 +259,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
'#title_display' => 'invisible',
|
'#title_display' => 'invisible',
|
||||||
'#type' => 'textfield',
|
'#type' => 'textfield',
|
||||||
'#default_value' => $config->get('track.files_extensions'),
|
'#default_value' => $config->get('track.files_extensions'),
|
||||||
'#description' => $this->t('A file extension list separated by the | character that will be tracked as download when clicked. Regular expressions are supported. For example: @extensions', ['@extensions' => MATOMO_TRACKFILES_EXTENSIONS]),
|
'#description' => $this->t('A file extension list separated by the | character that will be tracked as download when clicked. Regular expressions are supported. For example: @extensions', ['@extensions' => MatomoInterface::MATOMO_TRACKFILES_EXTENSIONS]),
|
||||||
'#maxlength' => 500,
|
'#maxlength' => 500,
|
||||||
'#states' => [
|
'#states' => [
|
||||||
'enabled' => [
|
'enabled' => [
|
||||||
@@ -251,7 +273,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
];
|
];
|
||||||
|
|
||||||
$colorbox_dependencies = '<div class="admin-requirements">';
|
$colorbox_dependencies = '<div class="admin-requirements">';
|
||||||
$colorbox_dependencies .= $this->t('Requires: @module-list', ['@module-list' => (\Drupal::moduleHandler()->moduleExists('colorbox') ? $this->t('@module (<span class="admin-enabled">enabled</span>)', ['@module' => 'Colorbox']) : $this->t('@module (<span class="admin-missing">disabled</span>)', ['@module' => 'Colorbox']))]);
|
$colorbox_dependencies .= $this->t('Requires: @module-list', ['@module-list' => ($this->moduleHandler->moduleExists('colorbox') ? $this->t('@module (<span class="admin-enabled">enabled</span>)', ['@module' => 'Colorbox']) : $this->t('@module (<span class="admin-missing">disabled</span>)', ['@module' => 'Colorbox']))]);
|
||||||
$colorbox_dependencies .= '</div>';
|
$colorbox_dependencies .= '</div>';
|
||||||
|
|
||||||
$form['tracking']['linktracking']['matomo_trackcolorbox'] = [
|
$form['tracking']['linktracking']['matomo_trackcolorbox'] = [
|
||||||
@@ -259,7 +281,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
'#title' => $this->t('Track content in colorbox modal dialogs'),
|
'#title' => $this->t('Track content in colorbox modal dialogs'),
|
||||||
'#description' => $this->t('Enable to track the content shown in colorbox modal windows.') . $colorbox_dependencies,
|
'#description' => $this->t('Enable to track the content shown in colorbox modal windows.') . $colorbox_dependencies,
|
||||||
'#default_value' => $config->get('track.colorbox'),
|
'#default_value' => $config->get('track.colorbox'),
|
||||||
'#disabled' => (\Drupal::moduleHandler()->moduleExists('colorbox') ? FALSE : TRUE),
|
'#disabled' => ($this->moduleHandler->moduleExists('colorbox') ? FALSE : TRUE),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Message specific configurations.
|
// Message specific configurations.
|
||||||
@@ -288,7 +310,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
];
|
];
|
||||||
|
|
||||||
$site_search_dependencies = '<div class="admin-requirements">';
|
$site_search_dependencies = '<div class="admin-requirements">';
|
||||||
$site_search_dependencies .= $this->t('Requires: @module-list', ['@module-list' => (\Drupal::moduleHandler()->moduleExists('search') ? $this->t('@module (<span class="admin-enabled">enabled</span>)', ['@module' => 'Search']) : $this->t('@module (<span class="admin-missing">disabled</span>)', ['@module' => 'Search']))]);
|
$site_search_dependencies .= $this->t('Requires: @module-list', ['@module-list' => ($this->moduleHandler->moduleExists('search') ? $this->t('@module (<span class="admin-enabled">enabled</span>)', ['@module' => 'Search']) : $this->t('@module (<span class="admin-missing">disabled</span>)', ['@module' => 'Search']))]);
|
||||||
$site_search_dependencies .= '</div>';
|
$site_search_dependencies .= '</div>';
|
||||||
|
|
||||||
$form['tracking']['search']['matomo_site_search'] = [
|
$form['tracking']['search']['matomo_site_search'] = [
|
||||||
@@ -296,7 +318,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
'#title' => $this->t('Track internal search'),
|
'#title' => $this->t('Track internal search'),
|
||||||
'#description' => $this->t('If checked, internal search keywords are tracked.') . $site_search_dependencies,
|
'#description' => $this->t('If checked, internal search keywords are tracked.') . $site_search_dependencies,
|
||||||
'#default_value' => $config->get('track.site_search'),
|
'#default_value' => $config->get('track.site_search'),
|
||||||
'#disabled' => (\Drupal::moduleHandler()->moduleExists('search') ? FALSE : TRUE),
|
'#disabled' => ($this->moduleHandler->moduleExists('search') ? FALSE : TRUE),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Privacy specific configurations.
|
// Privacy specific configurations.
|
||||||
@@ -308,7 +330,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
$form['tracking']['privacy']['matomo_privacy_donottrack'] = [
|
$form['tracking']['privacy']['matomo_privacy_donottrack'] = [
|
||||||
'#type' => 'checkbox',
|
'#type' => 'checkbox',
|
||||||
'#title' => $this->t('Universal web tracking opt-out'),
|
'#title' => $this->t('Universal web tracking opt-out'),
|
||||||
'#description' => $this->t('If enabled and your Matomo server receives the <a href="http://donottrack.us/">Do-Not-Track</a> header from the client browser, the Matomo server will not track the user. Compliance with Do Not Track could be purely voluntary, enforced by industry self-regulation, or mandated by state or federal law. Please accept your visitors privacy. If they have opt-out from tracking and advertising, you should accept their personal decision.'),
|
'#description' => $this->t('If enabled and your Matomo server receives the <a href=":donottrack">Do-Not-Track</a> header from the client browser, the Matomo server will not track the user. Compliance with Do Not Track could be purely voluntary, enforced by industry self-regulation, or mandated by state or federal law. Please accept your visitors privacy. If they have opt-out from tracking and advertising, you should accept their personal decision.', [':donottrack' => 'https://www.eff.org/issues/do-not-track']),
|
||||||
'#default_value' => $config->get('privacy.donottrack'),
|
'#default_value' => $config->get('privacy.donottrack'),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -334,7 +356,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
|
|
||||||
// Custom variables.
|
// Custom variables.
|
||||||
$form['matomo_custom_var'] = [
|
$form['matomo_custom_var'] = [
|
||||||
'#description' => $this->t('You can add Matomos <a href=":custom_var_documentation">Custom Variables</a> here. These will be added to every page that Matomo tracking code appears on. Custom variable names and values are limited to 200 characters in length. Keep the names and values as short as possible and expect long values to get trimmed. You may use tokens in custom variable names and values. Global and user tokens are always available; on node pages, node tokens are also available.', [':custom_var_documentation' => 'http://matomo.org/docs/custom-variables/']),
|
'#description' => $this->t('You can add Matomos <a href=":custom_var_documentation">Custom Variables</a> here. These will be added to every page that Matomo tracking code appears on. Custom variable names and values are limited to 200 characters in length. Keep the names and values as short as possible and expect long values to get trimmed. You may use tokens in custom variable names and values. Global and user tokens are always available; on node pages, node tokens are also available.', [':custom_var_documentation' => 'https://matomo.org/docs/custom-variables/']),
|
||||||
'#title' => $this->t('Custom variables'),
|
'#title' => $this->t('Custom variables'),
|
||||||
'#tree' => TRUE,
|
'#tree' => TRUE,
|
||||||
'#type' => 'details',
|
'#type' => 'details',
|
||||||
@@ -382,7 +404,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
'#element_validate' => [[get_class($this), 'tokenElementValidate']],
|
'#element_validate' => [[get_class($this), 'tokenElementValidate']],
|
||||||
'#token_types' => ['node'],
|
'#token_types' => ['node'],
|
||||||
];
|
];
|
||||||
if (\Drupal::moduleHandler()->moduleExists('token')) {
|
if ($this->moduleHandler->moduleExists('token')) {
|
||||||
$form['matomo_custom_var']['slots'][$i]['value']['#element_validate'][] = 'token_element_validate';
|
$form['matomo_custom_var']['slots'][$i]['value']['#element_validate'][] = 'token_element_validate';
|
||||||
}
|
}
|
||||||
$form['matomo_custom_var']['slots'][$i]['scope'] = [
|
$form['matomo_custom_var']['slots'][$i]['scope'] = [
|
||||||
@@ -402,7 +424,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
'#type' => 'item',
|
'#type' => 'item',
|
||||||
'#description' => $this->t("You can supplement Matomos' basic IP address tracking of visitors by segmenting users based on custom variables. Make sure you will not associate (or permit any third party to associate) any data gathered from your websites (or such third parties' websites) with any personally identifying information from any source as part of your use (or such third parties' use) of the Matomo' service."),
|
'#description' => $this->t("You can supplement Matomos' basic IP address tracking of visitors by segmenting users based on custom variables. Make sure you will not associate (or permit any third party to associate) any data gathered from your websites (or such third parties' websites) with any personally identifying information from any source as part of your use (or such third parties' use) of the Matomo' service."),
|
||||||
];
|
];
|
||||||
if (\Drupal::moduleHandler()->moduleExists('token')) {
|
if ($this->moduleHandler->moduleExists('token')) {
|
||||||
$form['matomo_custom_var']['matomo_custom_var_token_tree'] = [
|
$form['matomo_custom_var']['matomo_custom_var_token_tree'] = [
|
||||||
'#theme' => 'token_tree_link',
|
'#theme' => 'token_tree_link',
|
||||||
'#token_types' => ['node'],
|
'#token_types' => ['node'],
|
||||||
@@ -424,7 +446,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Allow for tracking of the originating node when viewing translation sets.
|
// Allow for tracking of the originating node when viewing translation sets.
|
||||||
if (\Drupal::moduleHandler()->moduleExists('content_translation')) {
|
if ($this->moduleHandler->moduleExists('content_translation')) {
|
||||||
$form['advanced']['matomo_translation_set'] = [
|
$form['advanced']['matomo_translation_set'] = [
|
||||||
'#type' => 'checkbox',
|
'#type' => 'checkbox',
|
||||||
'#title' => $this->t('Track translation sets as one unit'),
|
'#title' => $this->t('Track translation sets as one unit'),
|
||||||
@@ -439,7 +461,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
'#type' => 'details',
|
'#type' => 'details',
|
||||||
'#title' => $this->t('Custom JavaScript code'),
|
'#title' => $this->t('Custom JavaScript code'),
|
||||||
'#open' => TRUE,
|
'#open' => TRUE,
|
||||||
'#description' => $this->t('You can add custom Matomo <a href=":snippets">code snippets</a> here. These will be added to every page that Matomo appears on. <strong>Do not include the <script> tags</strong>, and always end your code with a semicolon (;).', [':snippets' => 'http://matomo.org/docs/javascript-tracking/']),
|
'#description' => $this->t('You can add custom Matomo <a href=":snippets">code snippets</a> here. These will be added to every page that Matomo appears on. <strong>Do not include the <script> tags</strong>, and always end your code with a semicolon (;).', [':snippets' => 'https://matomo.org/docs/javascript-tracking/']),
|
||||||
];
|
];
|
||||||
$form['advanced']['codesnippet']['matomo_codesnippet_before'] = [
|
$form['advanced']['codesnippet']['matomo_codesnippet_before'] = [
|
||||||
'#type' => 'textarea',
|
'#type' => 'textarea',
|
||||||
@@ -496,7 +518,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
|
|
||||||
$url = $form_state->getValue('matomo_url_http') . 'piwik.php';
|
$url = $form_state->getValue('matomo_url_http') . 'piwik.php';
|
||||||
try {
|
try {
|
||||||
$result = \Drupal::httpClient()->get($url);
|
$result = $this->httpClient->get($url);
|
||||||
if ($result->getStatusCode() != 200 && $form_state->getValue('matomo_url_skiperror') == FALSE) {
|
if ($result->getStatusCode() != 200 && $form_state->getValue('matomo_url_skiperror') == FALSE) {
|
||||||
$form_state->setErrorByName('matomo_url_http', $this->t('The validation of "@url" failed with error "@error" (HTTP code @code).', [
|
$form_state->setErrorByName('matomo_url_http', $this->t('The validation of "@url" failed with error "@error" (HTTP code @code).', [
|
||||||
'@url' => UrlHelper::filterBadProtocol($url),
|
'@url' => UrlHelper::filterBadProtocol($url),
|
||||||
@@ -517,7 +539,7 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
if (!empty($matomo_url_https)) {
|
if (!empty($matomo_url_https)) {
|
||||||
$url = $matomo_url_https . 'piwik.php';
|
$url = $matomo_url_https . 'piwik.php';
|
||||||
try {
|
try {
|
||||||
$result = \Drupal::httpClient()->get($url);
|
$result = $this->httpClient->get($url);
|
||||||
if ($result->getStatusCode() != 200 && $form_state->getValue('matomo_url_skiperror') == FALSE) {
|
if ($result->getStatusCode() != 200 && $form_state->getValue('matomo_url_skiperror') == FALSE) {
|
||||||
$form_state->setErrorByName('matomo_url_https', $this->t('The validation of "@url" failed with error "@error" (HTTP code @code).', [
|
$form_state->setErrorByName('matomo_url_https', $this->t('The validation of "@url" failed with error "@error" (HTTP code @code).', [
|
||||||
'@url' => UrlHelper::filterBadProtocol($url),
|
'@url' => UrlHelper::filterBadProtocol($url),
|
||||||
@@ -714,4 +736,17 @@ class MatomoAdminSettingsForm extends ConfigFormBase {
|
|||||||
return preg_match('/' . implode('|', array_map('preg_quote', $token_blacklist)) . '/i', $token_string);
|
return preg_match('/' . implode('|', array_map('preg_quote', $token_blacklist)) . '/i', $token_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function create(ContainerInterface $container) {
|
||||||
|
return new static(
|
||||||
|
// Load the service required to construct this class.
|
||||||
|
$container->get('config.factory'),
|
||||||
|
$container->get('current_user'),
|
||||||
|
$container->get('module_handler'),
|
||||||
|
$container->get('http_client')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\matomo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an interface.
|
||||||
|
*/
|
||||||
|
interface MatomoInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the default file extension list that should be tracked as download.
|
||||||
|
*/
|
||||||
|
const MATOMO_TRACKFILES_EXTENSIONS = '7z|aac|arc|arj|asf|asx|avi|bin|csv|doc(x|m)?|dot(x|m)?|exe|flv|gif|gz|gzip|hqx|jar|jpe?g|js|mp(2|3|4|e?g)|mov(ie)?|msi|msp|pdf|phps|png|ppt(x|m)?|pot(x|m)?|pps(x|m)?|ppam|sld(x|m)?|thmx|qtm?|ra(m|r)?|sea|sit|tar|tgz|torrent|txt|wav|wma|wmv|wpd|xls(x|m|b)?|xlt(x|m)|xlam|xml|z|zip';
|
||||||
|
|
||||||
|
}
|
||||||
@@ -63,7 +63,6 @@ class MatomoSearchTest extends WebTestBase {
|
|||||||
$search['keys'] = $this->randomMachineName(8);
|
$search['keys'] = $this->randomMachineName(8);
|
||||||
|
|
||||||
// Create a node to search for.
|
// Create a node to search for.
|
||||||
// Create a node.
|
|
||||||
$edit = [];
|
$edit = [];
|
||||||
$edit['title[0][value]'] = 'This is a test title';
|
$edit['title[0][value]'] = 'This is a test title';
|
||||||
$edit['body[0][value]'] = 'This test content contains ' . $search['keys'] . ' string.';
|
$edit['body[0][value]'] = 'This test content contains ' . $search['keys'] . ' string.';
|
||||||
|
|||||||
@@ -57,7 +57,11 @@ class MatomoStatusMessagesTest extends WebTestBase {
|
|||||||
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Error message", "Example error message with html tags and link."]);', '[testMatomoStatusMessages]: HTML has been stripped successful from Example error message with html tags and link.');
|
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Error message", "Example error message with html tags and link."]);', '[testMatomoStatusMessages]: HTML has been stripped successful from Example error message with html tags and link.');
|
||||||
|
|
||||||
// Enable logging of status, warnings and errors.
|
// Enable logging of status, warnings and errors.
|
||||||
$this->config('matomo.settings')->set('track.messages', ['status' => 'status', 'warning' => 'warning', 'error' => 'error'])->save();
|
$this->config('matomo.settings')->set('track.messages', [
|
||||||
|
'status' => 'status',
|
||||||
|
'warning' => 'warning',
|
||||||
|
'error' => 'error',
|
||||||
|
])->save();
|
||||||
|
|
||||||
$this->drupalGet('matomo-test/drupal-messenger-add-message');
|
$this->drupalGet('matomo-test/drupal-messenger-add-message');
|
||||||
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Status message", "Example status message."]);', '[testMatomoStatusMessages]: Example status message is enabled for tracking.');
|
$this->assertRaw('_paq.push(["trackEvent", "Messages", "Status message", "Example status message."]);', '[testMatomoStatusMessages]: Example status message is enabled for tracking.');
|
||||||
|
|||||||
+3
-3
@@ -4,8 +4,8 @@ description: 'Support module for Matomo testing.'
|
|||||||
package: Testing
|
package: Testing
|
||||||
# core: 8.x
|
# core: 8.x
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-07-13
|
# Information added by Drupal.org packaging script on 2019-02-08
|
||||||
version: '8.x-1.7'
|
version: '8.x-1.9'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'matomo'
|
project: 'matomo'
|
||||||
datestamp: 1531470224
|
datestamp: 1549615102
|
||||||
|
|||||||
+4
-4
@@ -17,10 +17,10 @@ class MatomoTestController extends ControllerBase {
|
|||||||
*/
|
*/
|
||||||
public function drupalAddMessageTest() {
|
public function drupalAddMessageTest() {
|
||||||
// Set some messages.
|
// Set some messages.
|
||||||
drupal_set_message($this->t('Example status message.'), 'status');
|
$this->messenger()->addMessage($this->t('Example status message.'), 'status');
|
||||||
drupal_set_message($this->t('Example warning message.'), 'warning');
|
$this->messenger()->addMessage($this->t('Example warning message.'), 'warning');
|
||||||
drupal_set_message($this->t('Example error message.'), 'error');
|
$this->messenger()->addMessage($this->t('Example error message.'), 'error');
|
||||||
drupal_set_message($this->t('Example error <em>message</em> with html tags and <a href="http://example.com/">link</a>.'), 'error');
|
$this->messenger()->addMessage($this->t('Example error <em>message</em> with html tags and <a href="https://example.com/">link</a>.'), 'error');
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
name: Extended Path Aliases
|
name: Extended Path Aliases
|
||||||
type: module
|
|
||||||
description: 'Automatically extend path aliases to include tabs, like <em>about-us/edit</em> for <em>node/123/edit</em>.<br> Allow these aliases to be entered in page specification wild-cards, <em>about-us*</em>, e.g for block visibility.'
|
description: 'Automatically extend path aliases to include tabs, like <em>about-us/edit</em> for <em>node/123/edit</em>.<br> Allow these aliases to be entered in page specification wild-cards, <em>about-us*</em>, e.g for block visibility.'
|
||||||
# core: 8.x
|
|
||||||
configure: path_alias_xt.settings_form
|
|
||||||
dependencies:
|
|
||||||
- path
|
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2017-07-14
|
type: module
|
||||||
|
# core: 8.x
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
- drupal:path
|
||||||
|
|
||||||
|
configure: path_alias_xt.settings_form
|
||||||
|
|
||||||
|
# Information added by Drupal.org packaging script on 2019-01-30
|
||||||
version: '8.x-1.x-dev'
|
version: '8.x-1.x-dev'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'path_alias_xt'
|
project: 'path_alias_xt'
|
||||||
datestamp: 1500044946
|
datestamp: 1548876484
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class PathAliasXtProcessorAlias extends PathProcessorAlias {
|
|||||||
|
|
||||||
// Validate the path.
|
// Validate the path.
|
||||||
// Injecting the service threw ServiceCircularReferenceException.
|
// Injecting the service threw ServiceCircularReferenceException.
|
||||||
if (\Drupal::service('path.validator')->isValid($return_path)) {
|
if (\Drupal::service('path.validator')->getUrlIfValidWithoutAccessCheck($return_path)) {
|
||||||
return $return_path;
|
return $return_path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,61 @@
|
|||||||
|
CONTENTS OF THIS FILE
|
||||||
|
---------------------
|
||||||
|
|
||||||
This is the new module home for a unified redirection API (also replaces
|
* Introduction
|
||||||
|
* Requirements
|
||||||
|
* Installation
|
||||||
|
* Configuration
|
||||||
|
* Maintainers
|
||||||
|
|
||||||
|
|
||||||
|
INTRODUCTION
|
||||||
|
------------
|
||||||
|
|
||||||
|
The Redirect module provides a unified redirection API (also replaces
|
||||||
path_redirect and globalredirect).
|
path_redirect and globalredirect).
|
||||||
|
|
||||||
|
|
||||||
|
* For a full description of the module visit:
|
||||||
|
https://www.drupal.org/project/redirect
|
||||||
|
|
||||||
|
* To submit bug reports and feature suggestions, or to track changes visit:
|
||||||
|
https://www.drupal.org/project/issues/redirect
|
||||||
|
|
||||||
|
|
||||||
|
REQUIREMENTS
|
||||||
|
------------
|
||||||
|
|
||||||
|
This module requires no modules outside of Drupal core.
|
||||||
|
|
||||||
|
|
||||||
|
INSTALLATION
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Install the Redirect module as you would normally install a contributed
|
||||||
|
Drupal module. Visit https://www.drupal.org/node/1897420 for further
|
||||||
|
information.
|
||||||
|
|
||||||
|
|
||||||
|
CONFIGURATION
|
||||||
|
-------------
|
||||||
|
|
||||||
|
1. Navigate to Administration > Extend and enable the module.
|
||||||
|
2. Navigate to Administration > Configuration > Search and Metadata > URL
|
||||||
|
redirects for configuration.
|
||||||
|
3. Select "Add redirect" and in the "Path" field add the old path.
|
||||||
|
4. In the "To" field, start typing the title of a piece of content to select
|
||||||
|
it. You can also enter an internal path such as /node/add or an external
|
||||||
|
URL such as http://example.com. Enter <front> to link to the front page.
|
||||||
|
5. Select the Redirect status: 300 Multiple Choices, 301 Moved Permanently,
|
||||||
|
302 Found, 303 See Other, 304 Not Modified, 305 Use Proxy, or 307
|
||||||
|
Temporary Redirect. Save.
|
||||||
|
6. Once a redirect has been added, it will be listed in the URL Redirects
|
||||||
|
vertical tab group on the content's edit page.
|
||||||
|
|
||||||
|
|
||||||
|
MAINTAINERS
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Supporting organization for 8.x-1.x port:
|
||||||
|
|
||||||
|
* MD Systems - https://www.drupal.org/md-systems
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ display:
|
|||||||
exposed_form:
|
exposed_form:
|
||||||
type: basic
|
type: basic
|
||||||
options:
|
options:
|
||||||
submit_button: Apply
|
submit_button: Filter
|
||||||
reset_button: false
|
reset_button: false
|
||||||
reset_button_label: Reset
|
reset_button_label: Reset
|
||||||
exposed_sorts_label: 'Sort by'
|
exposed_sorts_label: 'Sort by'
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ dependencies:
|
|||||||
- redirect
|
- redirect
|
||||||
- views
|
- views
|
||||||
|
|
||||||
# Information added by Drupal.org packaging script on 2018-05-04
|
# Information added by Drupal.org packaging script on 2018-10-16
|
||||||
version: '8.x-1.2'
|
version: '8.x-1.3'
|
||||||
core: '8.x'
|
core: '8.x'
|
||||||
project: 'redirect'
|
project: 'redirect'
|
||||||
datestamp: 1525419807
|
datestamp: 1539682690
|
||||||
|
|||||||
+2
-3
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace Drupal\redirect_404\EventSubscriber;
|
namespace Drupal\redirect_404\EventSubscriber;
|
||||||
|
|
||||||
use Drupal\Component\Utility\Unicode;
|
|
||||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||||
use Drupal\Core\Language\LanguageManagerInterface;
|
use Drupal\Core\Language\LanguageManagerInterface;
|
||||||
use Drupal\Core\Path\PathMatcherInterface;
|
use Drupal\Core\Path\PathMatcherInterface;
|
||||||
@@ -106,11 +105,11 @@ class Redirect404Subscriber implements EventSubscriberInterface {
|
|||||||
$path = $this->currentPath->getPath();
|
$path = $this->currentPath->getPath();
|
||||||
|
|
||||||
// Ignore paths specified in the redirect settings.
|
// Ignore paths specified in the redirect settings.
|
||||||
if ($pages = Unicode::strtolower($this->config->get('pages'))) {
|
if ($pages = mb_strtolower($this->config->get('pages'))) {
|
||||||
// Do not trim a trailing slash if that is the complete path.
|
// Do not trim a trailing slash if that is the complete path.
|
||||||
$path_to_match = $path === '/' ? $path : rtrim($path, '/');
|
$path_to_match = $path === '/' ? $path : rtrim($path, '/');
|
||||||
|
|
||||||
if ($this->pathMatcher->matchPath(Unicode::strtolower($path_to_match), $pages)) {
|
if ($this->pathMatcher->matchPath(mb_strtolower($path_to_match), $pages)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -51,7 +51,7 @@ class SqlRedirectNotFoundStorage implements RedirectNotFoundStorageInterface {
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function logRequest($path, $langcode) {
|
public function logRequest($path, $langcode) {
|
||||||
if (Unicode::strlen($path) > static::MAX_PATH_LENGTH) {
|
if (mb_strlen($path) > static::MAX_PATH_LENGTH) {
|
||||||
// Don't attempt to log paths that would result in an exception. There is
|
// Don't attempt to log paths that would result in an exception. There is
|
||||||
// no point in logging truncated paths, as they cannot be used to build a
|
// no point in logging truncated paths, as they cannot be used to build a
|
||||||
// new redirect.
|
// new redirect.
|
||||||
|
|||||||
+15
-14
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Drupal\redirect_404\Tests;
|
namespace Drupal\redirect_404\Tests;
|
||||||
|
|
||||||
|
use Drupal\Component\Utility\UrlHelper;
|
||||||
use Drupal\Core\Language\LanguageInterface;
|
use Drupal\Core\Language\LanguageInterface;
|
||||||
use Drupal\Core\Url;
|
use Drupal\Core\Url;
|
||||||
use Drupal\language\Entity\ConfigurableLanguage;
|
use Drupal\language\Entity\ConfigurableLanguage;
|
||||||
@@ -88,14 +89,14 @@ class Fix404RedirectUILanguageTest extends Redirect404TestBase {
|
|||||||
// Check if we generate correct Add redirect url and if the form is
|
// Check if we generate correct Add redirect url and if the form is
|
||||||
// pre-filled.
|
// pre-filled.
|
||||||
$destination = Url::fromRoute('redirect_404.fix_404')->getInternalPath();
|
$destination = Url::fromRoute('redirect_404.fix_404')->getInternalPath();
|
||||||
$options = [
|
$expected_query = [
|
||||||
'query' => [
|
'destination' => $destination,
|
||||||
'source' => 'testing',
|
'language' => 'fr',
|
||||||
'language' => 'fr',
|
'source' => 'testing',
|
||||||
'destination' => $destination,
|
|
||||||
]
|
|
||||||
];
|
];
|
||||||
$this->assertUrl('admin/config/search/redirect/add', $options);
|
$parsed_url = UrlHelper::parse($this->getUrl());
|
||||||
|
$this->assertEqual(Url::fromRoute('redirect.add')->setAbsolute()->toString(), $parsed_url['path']);
|
||||||
|
$this->assertEqual($expected_query, $parsed_url['query']);
|
||||||
$this->assertFieldByName('redirect_source[0][path]', 'testing');
|
$this->assertFieldByName('redirect_source[0][path]', 'testing');
|
||||||
$this->assertOptionSelected('edit-language-0-value', 'fr');
|
$this->assertOptionSelected('edit-language-0-value', 'fr');
|
||||||
// Save the redirect.
|
// Save the redirect.
|
||||||
@@ -177,14 +178,14 @@ class Fix404RedirectUILanguageTest extends Redirect404TestBase {
|
|||||||
|
|
||||||
// Assign a redirect to 'testing1'.
|
// Assign a redirect to 'testing1'.
|
||||||
$this->clickLink('Add redirect');
|
$this->clickLink('Add redirect');
|
||||||
$options = [
|
$expected_query = [
|
||||||
'query' => [
|
'destination' => $destination,
|
||||||
'source' => 'testing1',
|
'language' => 'en',
|
||||||
'language' => 'en',
|
'source' => 'testing1',
|
||||||
'destination' => $destination,
|
|
||||||
]
|
|
||||||
];
|
];
|
||||||
$this->assertUrl('admin/config/search/redirect/add', $options);
|
$parsed_url = UrlHelper::parse($this->getUrl());
|
||||||
|
$this->assertEqual(Url::fromRoute('redirect.add')->setAbsolute()->toString(), $parsed_url['path']);
|
||||||
|
$this->assertEqual($expected_query, $parsed_url['query']);
|
||||||
$this->assertFieldByName('redirect_source[0][path]', 'testing1');
|
$this->assertFieldByName('redirect_source[0][path]', 'testing1');
|
||||||
$this->assertOptionSelected('edit-language-0-value', 'en');
|
$this->assertOptionSelected('edit-language-0-value', 'en');
|
||||||
$edit = ['redirect_redirect[0][uri]' => '/node'];
|
$edit = ['redirect_redirect[0][uri]' => '/node'];
|
||||||
|
|||||||
+15
-14
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Drupal\redirect_404\Tests;
|
namespace Drupal\redirect_404\Tests;
|
||||||
|
|
||||||
|
use Drupal\Component\Utility\UrlHelper;
|
||||||
use Drupal\Core\Url;
|
use Drupal\Core\Url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,14 +27,14 @@ class Fix404RedirectUITest extends Redirect404TestBase {
|
|||||||
// Check if we generate correct Add redirect url and if the form is
|
// Check if we generate correct Add redirect url and if the form is
|
||||||
// pre-filled.
|
// pre-filled.
|
||||||
$destination = Url::fromRoute('redirect_404.fix_404')->getInternalPath();
|
$destination = Url::fromRoute('redirect_404.fix_404')->getInternalPath();
|
||||||
$options = [
|
$expected_query = [
|
||||||
'query' => [
|
'destination' => $destination,
|
||||||
'source' => 'non-existing0',
|
'language' => 'en',
|
||||||
'language' => 'en',
|
'source' => 'non-existing0',
|
||||||
'destination' => $destination,
|
|
||||||
]
|
|
||||||
];
|
];
|
||||||
$this->assertUrl('admin/config/search/redirect/add', $options);
|
$parsed_url = UrlHelper::parse($this->getUrl());
|
||||||
|
$this->assertEqual(Url::fromRoute('redirect.add')->setAbsolute()->toString(), $parsed_url['path']);
|
||||||
|
$this->assertEqual($expected_query, $parsed_url['query']);
|
||||||
$this->assertFieldByName('redirect_source[0][path]', 'non-existing0');
|
$this->assertFieldByName('redirect_source[0][path]', 'non-existing0');
|
||||||
// Save the redirect.
|
// Save the redirect.
|
||||||
$edit = ['redirect_redirect[0][uri]' => '/node'];
|
$edit = ['redirect_redirect[0][uri]' => '/node'];
|
||||||
@@ -97,14 +98,14 @@ class Fix404RedirectUITest extends Redirect404TestBase {
|
|||||||
|
|
||||||
// Assign a redirect to 'non-existing2'.
|
// Assign a redirect to 'non-existing2'.
|
||||||
$this->clickLink('Add redirect');
|
$this->clickLink('Add redirect');
|
||||||
$options = [
|
$expected_query = [
|
||||||
'query' => [
|
'source' => 'non-existing2',
|
||||||
'source' => 'non-existing2',
|
'language' => 'en',
|
||||||
'language' => 'en',
|
'destination' => $destination,
|
||||||
'destination' => $destination,
|
|
||||||
]
|
|
||||||
];
|
];
|
||||||
$this->assertUrl('admin/config/search/redirect/add', $options);
|
$parsed_url = UrlHelper::parse($this->getUrl());
|
||||||
|
$this->assertEqual(Url::fromRoute('redirect.add')->setAbsolute()->toString(), $parsed_url['path']);
|
||||||
|
$this->assertEqual($expected_query, $parsed_url['query']);
|
||||||
$this->assertFieldByName('redirect_source[0][path]', 'non-existing2');
|
$this->assertFieldByName('redirect_source[0][path]', 'non-existing2');
|
||||||
$this->drupalPostForm(NULL, $edit, t('Save'));
|
$this->drupalPostForm(NULL, $edit, t('Save'));
|
||||||
$this->assertUrl('admin/config/search/redirect/404');
|
$this->assertUrl('admin/config/search/redirect/404');
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user