diff --git a/sites/all/modules/contrib/admin/features/composer.json b/sites/all/modules/contrib/admin/features/composer.json
index 1b7a61d37..de7ea040a 100644
--- a/sites/all/modules/contrib/admin/features/composer.json
+++ b/sites/all/modules/contrib/admin/features/composer.json
@@ -6,5 +6,12 @@
"require": {
"drupal/config_update": "^1.4"
},
- "type": "drupal-module"
+ "type": "drupal-module",
+ "extra": {
+ "drush": {
+ "services": {
+ "drush.services.yml": "^9"
+ }
+ }
+ }
}
diff --git a/sites/all/modules/contrib/admin/features/drush/features.drush8.inc b/sites/all/modules/contrib/admin/features/drush/features.drush8.inc
index b4abe91f0..35a76abe8 100644
--- a/sites/all/modules/contrib/admin/features/drush/features.drush8.inc
+++ b/sites/all/modules/contrib/admin/features/drush/features.drush8.inc
@@ -6,6 +6,7 @@
*/
use Drupal\features\ConfigurationItem;
+use Drupal\features\FeaturesBundleInterface;
use Drupal\features\FeaturesManagerInterface;
use Drupal\features\Plugin\FeaturesGeneration\FeaturesGenerationWrite;
use Drupal\Component\Diff\DiffFormatter;
@@ -14,118 +15,118 @@ use Drupal\Component\Diff\DiffFormatter;
* Implements hook_drush_command().
*/
function features_drush_command() {
- $items = array();
+ $items = [];
- $items['features-status'] = array(
+ $items['features-status'] = [
'description' => 'Display current Features settings.',
- 'aliases' => array('fs'),
- );
+ 'aliases' => ['fs'],
+ ];
- $items['features-list-packages'] = array(
+ $items['features-list-packages'] = [
'description' => 'Display a list of all existing features and packages available to be generated. If a package name is provided as an argument, then all of the configuration objects assigned to that package will be listed.',
- 'examples' => array(
+ 'examples' => [
"drush features-list-packages" => 'Display a list of all existing featurea and packages available to be generated.',
"drush features-list-packages 'example_article'" => "Display a list of all configuration objects assigned to the 'example_article' package.",
- ),
- 'arguments' => array(
+ ],
+ 'arguments' => [
'package' => 'The package to list. Optional; if specified, lists all configuration objects assigned to that package. If no package is specified, lists all of the features.',
- ),
- 'outputformat' => array(
+ ],
+ 'outputformat' => [
'default' => 'table',
'pipe-format' => 'list',
- 'field-labels' => array(
+ 'field-labels' => [
'name' => 'Name',
'machine_name' => 'Machine name',
'status' => 'Status',
'version' => 'Version',
'state' => 'State',
'object' => 'Configuration object',
- ),
+ ],
'output-data-type' => 'format-table',
- ),
- 'aliases' => array('fl'),
- );
+ ],
+ 'aliases' => ['fl'],
+ ];
- $items['features-import-all'] = array(
+ $items['features-import-all'] = [
'description' => 'Import module config from all installed features.',
- 'examples' => array(
+ 'examples' => [
"drush features-import-all" => 'Import module config from all installed features.',
- ),
- 'aliases' => array('fra', 'fia', 'fim-all'),
- );
+ ],
+ 'aliases' => ['fra', 'fia', 'fim-all'],
+ ];
- $items['features-export'] = array(
+ $items['features-export'] = [
'description' => "Export the configuration on your site into a custom module.",
- 'arguments' => array(
+ 'arguments' => [
'package' => 'A space delimited list of features to export.',
- ),
- 'options' => array(
+ ],
+ 'options' => [
'add-profile' => 'Package features into an install profile.',
- ),
- 'examples' => array(
+ ],
+ 'examples' => [
"drush features-export" => 'Export all available packages.',
"drush features-export example_article example_page" => "Export the example_article and example_page packages.",
"drush features-export --add-profile" => "Export all available packages and add them to an install profile.",
- ),
+ ],
// Add previous "fu" alias for compatibility.
- 'aliases' => array('fex', 'fu', 'fua', 'fu-all'),
- );
+ 'aliases' => ['fex', 'fu', 'fua', 'fu-all'],
+ ];
- $items['features-add'] = array(
+ $items['features-add'] = [
'description' => "Add a config item to a feature package.",
- 'arguments' => array(
+ 'arguments' => [
'feature' => 'Feature package to export and add config to.',
'components' => 'Patterns of config to add, see features-components for the format of patterns.',
- ),
- 'aliases' => array('fa', 'fe'),
- );
+ ],
+ 'aliases' => ['fa', 'fe'],
+ ];
- $items['features-components'] = array(
+ $items['features-components'] = [
'description' => 'List features components.',
- 'arguments' => array(
+ 'arguments' => [
'patterns' => 'The features components type to list. Omit this argument to list all components.',
- ),
- 'options' => array(
- 'exported' => array(
+ ],
+ 'options' => [
+ 'exported' => [
'description' => 'Show only components that have been exported.',
- ),
- 'not-exported' => array(
+ ],
+ 'not-exported' => [
'description' => 'Show only components that have not been exported.',
- ),
- ),
- 'aliases' => array('fc'),
- );
+ ],
+ ],
+ 'aliases' => ['fc'],
+ ];
- $items['features-diff'] = array(
+ $items['features-diff'] = [
'description' => "Show the difference between the active config and the default config stored in a feature package.",
- 'arguments' => array(
+ 'arguments' => [
'feature' => 'The feature in question.',
- ),
- 'options' => array(
+ ],
+ 'options' => [
'ctypes' => 'Comma separated list of component types to limit the output to. Defaults to all types.',
'lines' => 'Generate diffs with lines of context instead of the usual two.',
- ),
- 'aliases' => array('fd'),
- );
+ ],
+ 'aliases' => ['fd'],
+ ];
- $items['features-import'] = array(
+ $items['features-import'] = [
'description' => "Import a module config into your site.",
- 'arguments' => array(
+ 'arguments' => [
'feature' => 'A space delimited list of features or feature:component pairs to import.',
- ),
- 'options' => array(
+ ],
+ 'options' => [
'force' => "Force import even if config is not overridden.",
- ),
- 'examples' => array(
+ ],
+ 'examples' => [
'drush features-import foo:node.type.page foo:taxonomy.vocabulary.tags bar' => 'Import node and taxonomy config of feature "foo". Import all config of feature "bar".',
- ),
- 'aliases' => array('fim', 'fr'),
- );
+ ],
+ 'aliases' => ['fim', 'fr'],
+ ];
foreach ($items as $name => &$item) {
- $item['options']['bundle'] = array(
+ $item['options']['bundle'] = [
'description' => 'Use a specific bundle namespace.',
- );
+ ];
}
return $items;
@@ -145,7 +146,7 @@ function _drush_features_options() {
if (!empty($bundle_name)) {
$bundle = $assigner->applyBundle($bundle_name);
if ($bundle->getMachineName() != $bundle_name) {
- drush_log(dt('Bundle @name not found. Using default.', array('@name' => $bundle_name)), 'warning');
+ drush_log(dt('Bundle @name not found. Using default.', ['@name' => $bundle_name]), 'warning');
}
}
else {
@@ -172,13 +173,13 @@ function drush_features_status() {
}
else {
drush_print(dt('Current bundle: @name (@machine_name)',
- array(
+ [
'@name' => $current_bundle->getName(),
'@machine_name' => $current_bundle->getMachineName(),
- )));
+ ]));
}
- drush_print(dt('Export folder: @folder', array('@folder' => $export_settings['folder'])));
- $dt_args = array('@methods' => implode(', ', array_keys($methods)));
+ drush_print(dt('Export folder: @folder', ['@folder' => $export_settings['folder']]));
+ $dt_args = ['@methods' => implode(', ', array_keys($methods))];
drush_print(dt('The following assignment methods are enabled:'));
drush_print(dt(' @methods', $dt_args));
@@ -204,18 +205,18 @@ function drush_features_status() {
function drush_features_list_packages($package_name = '') {
$assigner = _drush_features_options();
$current_bundle = $assigner->getBundle();
- $namespace = $current_bundle->isDefault() ? '' : $current_bundle->getMachineName();
+ $namespace = $current_bundle->isDefault() ? FeaturesBundleInterface::DEFAULT_BUNDLE : $current_bundle->getMachineName();
/** @var \Drupal\features\FeaturesManagerInterface $manager */
$manager = \Drupal::service('features.manager');
$packages = $manager->getPackages();
$packages = $manager->filterPackages($packages, $namespace);
- $result = array();
+ $result = [];
// If no package was specified, list all packages.
if (empty($package_name)) {
- drush_hide_output_fields(array('object'));
+ drush_hide_output_fields(['object']);
foreach ($packages as $package) {
$overrides = $manager->detectOverrides($package);
$state = $package->getState();
@@ -223,7 +224,7 @@ function drush_features_list_packages($package_name = '') {
$state = FeaturesManagerInterface::STATE_OVERRIDDEN;
}
- $result[$package->getMachineName()] = array(
+ $result[$package->getMachineName()] = [
'name' => $package->getName(),
'machine_name' => $package->getMachineName(),
'status' => $manager->statusLabel($package->getStatus()),
@@ -231,7 +232,7 @@ function drush_features_list_packages($package_name = '') {
'state' => ($state != FeaturesManagerInterface::STATE_DEFAULT)
? $manager->stateLabel($state)
: '',
- );
+ ];
}
return $result;
}
@@ -239,17 +240,17 @@ function drush_features_list_packages($package_name = '') {
else {
foreach ($packages as $package) {
if ($package->getMachineName() == $package_name) {
- drush_hide_output_fields(array(
+ drush_hide_output_fields([
'machine_name',
'name',
'status',
'version',
'state',
- ));
+ ]);
foreach ($package->getConfig() as $item_name) {
- $result[$item_name] = array(
+ $result[$item_name] = [
'object' => $item_name,
- );
+ ];
}
return $result;
}
@@ -258,7 +259,7 @@ function drush_features_list_packages($package_name = '') {
}
// If no matching package found, return an error.
- drush_log(dt('Package "@package" not found.', array('@package' => $package_name)), 'warning');
+ drush_log(dt('Package "@package" not found.', ['@package' => $package_name]), 'warning');
return FALSE;
}
@@ -269,13 +270,13 @@ function drush_features_list_packages($package_name = '') {
function drush_features_import_all() {
$assigner = _drush_features_options();
$current_bundle = $assigner->getBundle();
- $namespace = $current_bundle->isDefault() ? '' : $current_bundle->getMachineName();
+ $namespace = $current_bundle->isDefault() ? FeaturesBundleInterface::DEFAULT_BUNDLE : $current_bundle->getMachineName();
/** @var \Drupal\features\FeaturesManagerInterface $manager */
$manager = \Drupal::service('features.manager');
$packages = $manager->getPackages();
$packages = $manager->filterPackages($packages, $namespace);
- $overridden = array();
+ $overridden = [];
foreach ($packages as $package) {
$overrides = $manager->detectOverrides($package);
@@ -317,13 +318,13 @@ function drush_features_export($packages = NULL) {
$all_packages = $manager->getPackages();
foreach ($packages as $name) {
if (!isset($all_packages[$name])) {
- return drush_set_error('', dt("The package @name does not exist.", array('@name' => $name)));
+ return drush_set_error('', dt("The package @name does not exist.", ['@name' => $name]));
}
}
if (empty($packages)) {
$packages = $all_packages;
- $dt_args = array('@modules' => implode(', ', array_keys($packages)));
+ $dt_args = ['@modules' => implode(', ', array_keys($packages))];
drush_print(dt('The following extensions will be exported: @modules', $dt_args));
if (!drush_confirm(dt('Do you really want to continue?'))) {
return drush_user_abort('Aborting.');
@@ -333,7 +334,7 @@ function drush_features_export($packages = NULL) {
// If any packages exist, confirm before overwriting.
if ($existing_packages = $manager->listPackageDirectories($packages, $current_bundle)) {
foreach ($existing_packages as $name => $directory) {
- drush_print(dt("The extension @name already exists at @directory.", array('@name' => $name, '@directory' => $directory)));
+ drush_print(dt("The extension @name already exists at @directory.", ['@name' => $name, '@directory' => $directory]));
}
// Apparently, format_plural is not always available.
if (count($existing_packages) == 1) {
@@ -379,9 +380,9 @@ function drush_features_add() {
return drush_set_error('', 'No components supplied.');
}
$components = _drush_features_component_list();
- $options = array(
+ $options = [
'exported' => FALSE,
- );
+ ];
$filtered_components = _drush_features_component_filter($components, $args, $options);
$items = $filtered_components['components'];
@@ -390,11 +391,11 @@ function drush_features_add() {
return drush_set_error('', 'No components to add.');
}
- $packages = array($module);
+ $packages = [$module];
// If any packages exist, confirm before overwriting.
if ($existing_packages = $manager->listPackageDirectories($packages)) {
foreach ($existing_packages as $name => $directory) {
- drush_print(dt("The extension @name already exists at @directory.", array('@name' => $name, '@directory' => $directory)));
+ drush_print(dt("The extension @name already exists at @directory.", ['@name' => $name, '@directory' => $directory]));
}
// Apparently, format_plural is not always available.
if (count($existing_packages) == 1) {
@@ -410,7 +411,7 @@ function drush_features_add() {
else {
$package = $manager->initPackage($module, NULL, '', 'module', $current_bundle);
list($full_name, $path) = $manager->getExportInfo($package, $current_bundle);
- drush_print(dt('Will create a new extension @name in @directory', array('@name' => $full_name, '@directory' => $path)));
+ drush_print(dt('Will create a new extension @name in @directory', ['@name' => $full_name, '@directory' => $path]));
if (!drush_confirm(dt('Do you really want to continue?'))) {
drush_die('Aborting.');
}
@@ -452,15 +453,15 @@ function drush_features_components() {
return;
}
- $args = ($choice == 0) ? array('*') : array($types[$choice]);
+ $args = ($choice == 0) ? ['*'] : [$types[$choice]];
}
- $options = array(
+ $options = [
'provided by' => TRUE,
- );
- if (drush_get_option(array('exported', 'e'), NULL)) {
+ ];
+ if (drush_get_option(['exported', 'e'], NULL)) {
$options['not exported'] = FALSE;
}
- elseif (drush_get_option(array('not-exported', 'o'), NULL)) {
+ elseif (drush_get_option(['not-exported', 'o'], NULL)) {
$options['exported'] = FALSE;
}
@@ -496,7 +497,7 @@ function drush_features_diff() {
$feature = $manager->loadPackage($module, TRUE);
if (empty($feature)) {
- drush_log(dt('No such feature is available: @module', array('@module' => $module)), 'error');
+ drush_log(dt('No such feature is available: @module', ['@module' => $module]), 'error');
return;
}
@@ -521,7 +522,7 @@ function drush_features_diff() {
$overrides = array_merge($overrides, $missing);
if (empty($overrides)) {
- drush_print(dt('Active config matches stored config for @module.', array('@module' => $module)));
+ drush_print(dt('Active config matches stored config for @module.', ['@module' => $module]));
}
else {
/** @var \Drupal\config_update\ConfigDiffInterface $config_diff */
@@ -538,20 +539,20 @@ function drush_features_diff() {
$message = '';
if (in_array($name, $missing)) {
$message = sprintf($red, t('(missing from active)'));
- $extension = array();
+ $extension = [];
}
else {
$active = $manager->getActiveStorage()->read($name);
$extension = $manager->getExtensionStorages()->read($name);
if (empty($extension)) {
- $extension = array();
+ $extension = [];
$message = sprintf($green, t('(not exported)'));
}
$diff = $config_diff->diff($extension, $active);
$rows = explode("\n", $formatter->format($diff));
}
drush_print();
- drush_print(dt("Config @name @message", array('@name' => $name, '@message' => $message)));
+ drush_print(dt("Config @name @message", ['@name' => $name, '@message' => $message]));
if (!empty($extension)) {
foreach ($rows as $row) {
if (strpos($row, '>') === 0) {
@@ -588,7 +589,7 @@ function drush_features_import() {
$manager = \Drupal::service('features.manager');
// Parse list of arguments.
- $modules = array();
+ $modules = [];
foreach ($args as $arg) {
$arg = explode(':', $arg);
$module = array_shift($arg);
@@ -602,7 +603,7 @@ function drush_features_import() {
}
elseif ($modules[$module] !== TRUE) {
if (!isset($modules[$module])) {
- $modules[$module] = array();
+ $modules[$module] = [];
}
$modules[$module][] = $component;
}
@@ -692,7 +693,7 @@ function drush_features_import() {
function _drush_features_build_config(array $items) {
/** @var \Drupal\features\FeaturesManagerInterface $manager */
$manager = \Drupal::service('features.manager');
- $result = array();
+ $result = [];
foreach ($items as $config_type => $item) {
foreach ($item as $item_name => $title) {
$result[] = $manager->getFullName($config_type, $item_name);
@@ -705,7 +706,7 @@ function _drush_features_build_config(array $items) {
* Returns a listing of all known components, indexed by source.
*/
function _drush_features_component_list() {
- $result = array();
+ $result = [];
/** @var \Drupal\features\FeaturesManagerInterface $manager */
$manager = \Drupal::service('features.manager');
$config = $manager->getConfigCollection();
@@ -718,13 +719,13 @@ function _drush_features_component_list() {
/**
* Filters components by patterns.
*/
-function _drush_features_component_filter($all_components, $patterns = array(), $options = array()) {
- $options += array(
+function _drush_features_component_filter($all_components, $patterns = [], $options = []) {
+ $options += [
'exported' => TRUE,
'not exported' => TRUE,
'provided by' => FALSE,
- );
- $pool = array();
+ ];
+ $pool = [];
// Maps exported components to feature modules.
$components_map = _drush_features_get_component_map();
// First filter on exported state.
@@ -753,11 +754,11 @@ function _drush_features_component_filter($all_components, $patterns = array(),
$state_string = 'exported';
}
- $selected = array();
+ $selected = [];
foreach ($patterns as $pattern) {
// Rewrite * to %. Let users use both as wildcard.
- $pattern = strtr($pattern, array('*' => '%'));
- $sources = array();
+ $pattern = strtr($pattern, ['*' => '%']);
+ $sources = [];
list($source_pattern, $component_pattern) = explode(':', $pattern, 2);
// If source is empty, use a pattern.
if ($source_pattern == '') {
@@ -767,8 +768,8 @@ function _drush_features_component_filter($all_components, $patterns = array(),
$component_pattern = '%';
}
- $preg_source_pattern = strtr(preg_quote($source_pattern, '/'), array('%' => '.*'));
- $preg_component_pattern = strtr(preg_quote($component_pattern, '/'), array('%' => '.*'));
+ $preg_source_pattern = strtr(preg_quote($source_pattern, '/'), ['%' => '.*']);
+ $preg_component_pattern = strtr(preg_quote($component_pattern, '/'), ['%' => '.*']);
// If it isn't a pattern, but a simple string, we don't anchor the
// pattern. This allows for abbreviating. Otherwise, we do, as this seems
// more natural for patterns.
@@ -778,7 +779,7 @@ function _drush_features_component_filter($all_components, $patterns = array(),
if (strpos($component_pattern, '%') !== FALSE) {
$preg_component_pattern = '^' . $preg_component_pattern . '$';
}
- $matches = array();
+ $matches = [];
// Find the sources.
$all_sources = array_keys($pool);
@@ -789,20 +790,20 @@ function _drush_features_component_filter($all_components, $patterns = array(),
// use that, or error out.
if (count($matches) > 1 and $preg_source_pattern[0] != '^') {
if (in_array($source_pattern, $matches)) {
- $matches = array($source_pattern);
+ $matches = [$source_pattern];
}
else {
- return drush_set_error('', dt('Ambiguous source "@source", matches @matches', array(
+ return drush_set_error('', dt('Ambiguous source "@source", matches @matches', [
'@source' => $source_pattern,
'@matches' => implode(', ', $matches),
- )));
+ ]));
}
}
// Loose the indexes preg_grep preserved.
$sources = array_values($matches);
}
else {
- return drush_set_error('', dt('No @state sources match "@source"', array('@state' => $state_string, '@source' => $source_pattern)));
+ return drush_set_error('', dt('No @state sources match "@source"', ['@state' => $state_string, '@source' => $source_pattern]));
}
// Now find the components.
@@ -817,17 +818,17 @@ function _drush_features_component_filter($all_components, $patterns = array(),
// use that, or error out.
if (count($matches) > 1 and $preg_component_pattern[0] != '^') {
if (in_array($component_pattern, $matches)) {
- $matches = array($component_pattern);
+ $matches = [$component_pattern];
}
else {
- return drush_set_error('', dt('Ambiguous component "@component", matches @matches', array(
+ return drush_set_error('', dt('Ambiguous component "@component", matches @matches', [
'@component' => $component_pattern,
'@matches' => implode(', ', $matches),
- )));
+ ]));
}
}
if (!is_array($selected[$source])) {
- $selected[$source] = array();
+ $selected[$source] = [];
}
$selected[$source] += array_intersect_key($pool[$source], array_flip($matches));
}
@@ -835,11 +836,11 @@ function _drush_features_component_filter($all_components, $patterns = array(),
// No matches. If the source was a pattern, just carry on, else
// error out. Allows for patterns like :*field*
if ($preg_source_pattern[0] != '^') {
- return drush_set_error('', dt('No @state @source components match "@component"', array(
+ return drush_set_error('', dt('No @state @source components match "@component"', [
'@state' => $state_string,
'@component' => $component_pattern,
'@source' => $source,
- )));
+ ]));
}
}
}
@@ -847,7 +848,7 @@ function _drush_features_component_filter($all_components, $patterns = array(),
// Lastly, provide feature module information on the selected components, if
// requested.
- $provided_by = array();
+ $provided_by = [];
if ($options['provided by'] && $options['exported']) {
foreach ($selected as $source => $components) {
foreach ($components as $name => $title) {
@@ -859,17 +860,17 @@ function _drush_features_component_filter($all_components, $patterns = array(),
}
}
- return array(
+ return [
'components' => $selected,
'sources' => $provided_by,
- );
+ ];
}
/**
* Provides a component to feature map (port of features_get_component_map).
*/
function _drush_features_get_component_map() {
- $result = array();
+ $result = [];
/** @var \Drupal\features\FeaturesManagerInterface $manager */
$manager = \Drupal::service('features.manager');
// Recalc full config list without running assignments.
@@ -881,7 +882,7 @@ function _drush_features_get_component_map() {
$short_name = $item->getShortName();
$name = $item->getName();
if (!isset($result[$type][$short_name])) {
- $result[$type][$short_name] = array();
+ $result[$type][$short_name] = [];
}
if (!empty($item->getPackage())) {
$package = $packages[$item->getPackage()];
@@ -896,10 +897,10 @@ function _drush_features_get_component_map() {
* Prints a list of filtered components.
*/
function _drush_features_component_print($filtered_components) {
- $rows = array(array(dt('Available sources')));
+ $rows = [[dt('Available sources')]];
foreach ($filtered_components['components'] as $source => $components) {
foreach ($components as $name => $value) {
- $row = array($source . ':' . $name);
+ $row = [$source . ':' . $name];
if (isset($filtered_components['sources'][$source . ':' . $name])) {
$row[] = dt('Provided by') . ': ' . $filtered_components['sources'][$source . ':' . $name];
}
diff --git a/sites/all/modules/contrib/admin/features/features.info.yml b/sites/all/modules/contrib/admin/features/features.info.yml
index 197574cbd..65cef8a96 100644
--- a/sites/all/modules/contrib/admin/features/features.info.yml
+++ b/sites/all/modules/contrib/admin/features/features.info.yml
@@ -4,11 +4,11 @@ description: 'Enables administrators to package configuration into modules.'
package: Development
# core: 8.x
dependencies:
- - config
- - config_update
+ - drupal:config
+ - config_update:config_update
-# Information added by Drupal.org packaging script on 2018-02-27
-version: '8.x-3.7'
+# Information added by Drupal.org packaging script on 2018-09-09
+version: '8.x-3.8'
core: '8.x'
project: 'features'
-datestamp: 1519763291
+datestamp: 1536512288
diff --git a/sites/all/modules/contrib/admin/features/features.module b/sites/all/modules/contrib/admin/features/features.module
index 3fccc79c4..3bf4bf734 100644
--- a/sites/all/modules/contrib/admin/features/features.module
+++ b/sites/all/modules/contrib/admin/features/features.module
@@ -15,9 +15,9 @@ function features_help($route_name, RouteMatchInterface $route_match) {
case 'help.page.features':
$output = '';
$output .= '
' . t('About') . '
';
- $output .= '
' . t('The Features module provides a user interface for exporting bundles of configuration into modules. For more information, see the online documentation for Features module', array(
+ $output .= '
' . t('The Features module provides a user interface for exporting bundles of configuration into modules. For more information, see the online documentation for Features module', [
':url' => 'http://drupal.org/node/2404427',
- )) . '
' . t('Bundles are used to collect together groups of features. A bundle provides a shared namespace for all features included in it, which prevents conflicts and helps distinguish your features from those produced for other purposes. Common uses of bundles include:', array(':namespace' => 'http://en.wikipedia.org/wiki/Namespace'));
+ $output .= '
' . t('Bundles are used to collect together groups of features. A bundle provides a shared namespace for all features included in it, which prevents conflicts and helps distinguish your features from those produced for other purposes. Common uses of bundles include:', [':namespace' => 'http://en.wikipedia.org/wiki/Namespace']);
$output .= '
';
$output .= '
' . t('Custom features for use on a particular site.') . '
';
- $output .= '
' . t('The features of a given distribution.', array(':distributions' => 'https://www.drupal.org/documentation/build/distributions')) . '
';
+ $output .= '
' . t('The features of a given distribution.', [':distributions' => 'https://www.drupal.org/documentation/build/distributions']) . '
';
$output .= '
';
$output .= '
' . t('Use the form below to manage bundles. Each bundle comes with a set of assignment methods. By configuring and ordering the assignment methods, you can set the defaults for what does and doesn\'t get packaged into features for your bundle. Use the Bundle select to choose which bundle to edit, or chose --New-- to create a new bundle. The Default bundle does not include a namespace and cannot be deleted.') . '
',
- );
+ ];
return $element;
}
@@ -287,12 +287,12 @@ class FeaturesExportForm extends FormBase {
protected function buildPackageDetail(Package $package, FeaturesBundleInterface $bundle) {
$config_collection = $this->featuresManager->getConfigCollection();
- $url = Url::fromRoute('features.edit', array('featurename' => $package->getMachineName()));
+ $url = Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]);
- $element['name'] = array(
+ $element['name'] = [
'data' => \Drupal::l($package->getName(), $url),
- 'class' => array('feature-name'),
- );
+ 'class' => ['feature-name'],
+ ];
$machine_name = $package->getMachineName();
// Except for the 'unpackaged' pseudo-package, display the full name, since
// that's what will be generated.
@@ -300,128 +300,128 @@ class FeaturesExportForm extends FormBase {
$machine_name = $bundle->getFullName($machine_name);
}
$element['machine_name'] = $machine_name;
- $element['status'] = array(
+ $element['status'] = [
'data' => $this->featuresManager->statusLabel($package->getStatus()),
- 'class' => array('column-nowrap'),
- );
+ 'class' => ['column-nowrap'],
+ ];
// Use 'data' instead of plain string value so a blank version doesn't
// remove column from table.
- $element['version'] = array(
+ $element['version'] = [
'data' => Html::escape($package->getVersion()),
- 'class' => array('column-nowrap'),
- );
+ 'class' => ['column-nowrap'],
+ ];
$overrides = $this->featuresManager->detectOverrides($package);
$new_config = $this->featuresManager->detectNew($package);
- $conflicts = array();
- $missing = array();
- $moved = array();
+ $conflicts = [];
+ $missing = [];
+ $moved = [];
if ($package->getStatus() == FeaturesManagerInterface::STATUS_NO_EXPORT) {
- $overrides = array();
- $new_config = array();
+ $overrides = [];
+ $new_config = [];
}
// Bundle package configuration by type.
- $package_config = array();
+ $package_config = [];
foreach ($package->getConfig() as $item_name) {
if (isset($config_collection[$item_name])) {
$item = $config_collection[$item_name];
- $package_config[$item->getType()][] = array(
+ $package_config[$item->getType()][] = [
'name' => Html::escape($item_name),
'label' => Html::escape($item->getLabel()),
'class' => in_array($item_name, $overrides) ? 'features-override' :
(in_array($item_name, $new_config) ? 'features-detected' : ''),
- );
+ ];
}
}
// Conflict config from other modules.
foreach ($package->getConfigOrig() as $item_name) {
if (!isset($config_collection[$item_name])) {
$missing[] = $item_name;
- $package_config['missing'][] = array(
+ $package_config['missing'][] = [
'name' => Html::escape($item_name),
'label' => Html::escape($item_name),
'class' => 'features-missing',
- );
+ ];
}
elseif (!in_array($item_name, $package->getConfig())) {
$item = $config_collection[$item_name];
if (empty($item->getProvider())) {
$conflicts[] = $item_name;
$package_name = !empty($item->getPackage()) ? $item->getPackage() : $this->t('PACKAGE NOT ASSIGNED');
- $package_config[$item->getType()][] = array(
+ $package_config[$item->getType()][] = [
'name' => Html::escape($package_name),
'label' => Html::escape($item->getLabel()),
'class' => 'features-conflict',
- );
+ ];
}
else {
$moved[] = $item_name;
$package_name = !empty($item->getPackage()) ? $item->getPackage() : $this->t('PACKAGE NOT ASSIGNED');
- $package_config[$item->getType()][] = array(
- 'name' => $this->t('Moved to @package', array('@package' => $package_name)),
+ $package_config[$item->getType()][] = [
+ 'name' => $this->t('Moved to @package', ['@package' => $package_name]),
'label' => Html::escape($item->getLabel()),
'class' => 'features-moved',
- );
+ ];
}
}
}
// Add dependencies.
- $package_config['dependencies'] = array();
+ $package_config['dependencies'] = [];
foreach ($package->getDependencies() as $dependency) {
- $package_config['dependencies'][] = array(
+ $package_config['dependencies'][] = [
'name' => $dependency,
- 'label' => $this->moduleHandler->getName($dependency),
+ 'label' => $this->moduleHandler->moduleExists($dependency) ? $this->moduleHandler->getName($dependency) : $dependency,
'class' => '',
- );
+ ];
}
$class = '';
$state_links = [];
if (!empty($conflicts)) {
- $state_links[] = array(
+ $state_links[] = [
'#type' => 'link',
'#title' => $this->t('Conflicts'),
- '#url' => Url::fromRoute('features.edit', array('featurename' => $package->getMachineName())),
- '#attributes' => array('class' => array('features-conflict')),
- );
+ '#url' => Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]),
+ '#attributes' => ['class' => ['features-conflict']],
+ ];
}
if (!empty($overrides)) {
- $state_links[] = array(
+ $state_links[] = [
'#type' => 'link',
'#title' => $this->featuresManager->stateLabel(FeaturesManagerInterface::STATE_OVERRIDDEN),
- '#url' => Url::fromRoute('features.diff', array('featurename' => $package->getMachineName())),
- '#attributes' => array('class' => array('features-override')),
- );
+ '#url' => Url::fromRoute('features.diff', ['featurename' => $package->getMachineName()]),
+ '#attributes' => ['class' => ['features-override']],
+ ];
}
if (!empty($new_config)) {
- $state_links[] = array(
+ $state_links[] = [
'#type' => 'link',
'#title' => $this->t('New detected'),
- '#url' => Url::fromRoute('features.diff', array('featurename' => $package->getMachineName())),
- '#attributes' => array('class' => array('features-detected')),
- );
+ '#url' => Url::fromRoute('features.diff', ['featurename' => $package->getMachineName()]),
+ '#attributes' => ['class' => ['features-detected']],
+ ];
}
if (!empty($missing) && ($package->getStatus() == FeaturesManagerInterface::STATUS_INSTALLED)) {
- $state_links[] = array(
+ $state_links[] = [
'#type' => 'link',
'#title' => $this->t('Missing'),
- '#url' => Url::fromRoute('features.edit', array('featurename' => $package->getMachineName())),
- '#attributes' => array('class' => array('features-missing')),
- );
+ '#url' => Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]),
+ '#attributes' => ['class' => ['features-missing']],
+ ];
}
if (!empty($moved)) {
- $state_links[] = array(
+ $state_links[] = [
'#type' => 'link',
'#title' => $this->t('Moved'),
- '#url' => Url::fromRoute('features.edit', array('featurename' => $package->getMachineName())),
- '#attributes' => array('class' => array('features-moved')),
- );
+ '#url' => Url::fromRoute('features.edit', ['featurename' => $package->getMachineName()]),
+ '#attributes' => ['class' => ['features-moved']],
+ ];
}
if (!empty($state_links)) {
- $element['state'] = array(
+ $element['state'] = [
'data' => $state_links,
- 'class' => array('column-nowrap'),
- );
+ 'class' => ['column-nowrap'],
+ ];
}
else {
$element['state'] = '';
@@ -473,7 +473,7 @@ class FeaturesExportForm extends FormBase {
);
$details['table'] = array(
'#type' => 'details',
- '#title' => array('#markup' => $this->t('Included configuration')),
+ '#title' => $this->t('Included configuration'),
'#description' => array('data' => $element['table']),
);
$element['details'] = array(
diff --git a/sites/all/modules/contrib/admin/features/modules/features_ui/src/Tests/FeaturesUITest.php b/sites/all/modules/contrib/admin/features/modules/features_ui/src/Tests/FeaturesUITest.php
index 51c4abb9c..12f92ae5b 100644
--- a/sites/all/modules/contrib/admin/features/modules/features_ui/src/Tests/FeaturesUITest.php
+++ b/sites/all/modules/contrib/admin/features/modules/features_ui/src/Tests/FeaturesUITest.php
@@ -34,7 +34,7 @@ class FeaturesUITest extends WebTestBase {
$this->assertText($this->t('You have not yet created any bundles. Before generating features, you may wish to create a bundle to group your features within.'));
// Creating custom bundle.
$this->drupalGet('admin/config/development/features/bundle');
- $this->drupalPostAjaxForm(NULL, array('bundle[bundle_select]' => 'new'), 'bundle[bundle_select]');
+ $this->drupalPostAjaxForm(NULL, ['bundle[bundle_select]' => 'new'], 'bundle[bundle_select]');
$edit = [
'bundle[name]' => 'foo',
'bundle[machine_name]' => 'foo',
diff --git a/sites/all/modules/contrib/admin/features/src/Commands/FeaturesCommands.php b/sites/all/modules/contrib/admin/features/src/Commands/FeaturesCommands.php
index 79807b635..a0dec38e3 100644
--- a/sites/all/modules/contrib/admin/features/src/Commands/FeaturesCommands.php
+++ b/sites/all/modules/contrib/admin/features/src/Commands/FeaturesCommands.php
@@ -9,6 +9,7 @@ use Drupal\Core\Config\StorageInterface;
use Drupal\features\Exception\DomainException;
use Drupal\features\Exception\InvalidArgumentException;
use Drupal\features\FeaturesAssignerInterface;
+use Drupal\features\FeaturesBundleInterface;
use Drupal\features\FeaturesGeneratorInterface;
use Drupal\features\FeaturesManagerInterface;
use Drupal\features\Plugin\FeaturesGeneration\FeaturesGenerationWrite;
@@ -246,7 +247,7 @@ class FeaturesCommands extends DrushCommands {
public function listPackages($package_name = NULL, $options = self::OPTIONS_LIST) {
$assigner = $this->featuresOptions($options);
$current_bundle = $assigner->getBundle();
- $namespace = $current_bundle->isDefault() ? '' : $current_bundle->getMachineName();
+ $namespace = $current_bundle->isDefault() ? FeaturesBundleInterface::DEFAULT_BUNDLE : $current_bundle->getMachineName();
$manager = $this->manager;
$packages = $manager->getPackages();
@@ -312,7 +313,7 @@ class FeaturesCommands extends DrushCommands {
public function importAll($options = self::OPTIONS_IMPORT_ALL) {
$assigner = $this->featuresOptions($options);
$currentBundle = $assigner->getBundle();
- $namespace = $currentBundle->isDefault() ? '' : $currentBundle->getMachineName();
+ $namespace = $currentBundle->isDefault() ? FeaturesBundleInterface::DEFAULT_BUNDLE : $currentBundle->getMachineName();
$manager = $this->manager;
$packages = $manager->getPackages();
diff --git a/sites/all/modules/contrib/admin/features/src/Controller/FeaturesController.php b/sites/all/modules/contrib/admin/features/src/Controller/FeaturesController.php
index 701895aa2..e456577e3 100644
--- a/sites/all/modules/contrib/admin/features/src/Controller/FeaturesController.php
+++ b/sites/all/modules/contrib/admin/features/src/Controller/FeaturesController.php
@@ -69,7 +69,7 @@ class FeaturesController implements ContainerInjectionInterface {
throw new AccessDeniedHttpException();
}
- $request = new Request(array('file' => $uri));
+ $request = new Request(['file' => $uri]);
return $this->fileDownloadController->download($request, 'temporary');
}
}
diff --git a/sites/all/modules/contrib/admin/features/src/Entity/FeaturesBundle.php b/sites/all/modules/contrib/admin/features/src/Entity/FeaturesBundle.php
index 590143310..ced0be6de 100644
--- a/sites/all/modules/contrib/admin/features/src/Entity/FeaturesBundle.php
+++ b/sites/all/modules/contrib/admin/features/src/Entity/FeaturesBundle.php
@@ -193,7 +193,7 @@ class FeaturesBundle extends ConfigEntityBase implements FeaturesBundleInterface
* {@inheritdoc}
*/
public function getEnabledAssignments() {
- $list = array();
+ $list = [];
foreach ($this->assignments as $method_id => $method) {
if ($method['enabled']) {
$list[$method_id] = $method_id;
@@ -221,7 +221,7 @@ class FeaturesBundle extends ConfigEntityBase implements FeaturesBundleInterface
* {@inheritdoc}
*/
public function getAssignmentWeights() {
- $list = array();
+ $list = [];
foreach ($this->assignments as $method_id => $method) {
$list[$method_id] = $method['weight'];
}
@@ -275,7 +275,7 @@ class FeaturesBundle extends ConfigEntityBase implements FeaturesBundleInterface
}
}
else {
- $list = array();
+ $list = [];
foreach (array_keys($this->assignments) as $method_id) {
$list[$method_id] = $this->getAssignmentSettings($method_id);
}
diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesAssigner.php b/sites/all/modules/contrib/admin/features/src/FeaturesAssigner.php
index 75bf5a82d..f06b0d167 100644
--- a/sites/all/modules/contrib/admin/features/src/FeaturesAssigner.php
+++ b/sites/all/modules/contrib/admin/features/src/FeaturesAssigner.php
@@ -113,7 +113,7 @@ class FeaturesAssigner implements FeaturesAssignerInterface {
* {@inheritdoc}
*/
public function reset() {
- $this->methods = array();
+ $this->methods = [];
$this->featuresManager->reset();
}
@@ -181,7 +181,7 @@ class FeaturesAssigner implements FeaturesAssignerInterface {
*/
protected function getAssignmentMethodInstance($method_id) {
if (!isset($this->methods[$method_id])) {
- $instance = $this->assignerManager->createInstance($method_id, array());
+ $instance = $this->assignerManager->createInstance($method_id, []);
$instance->setFeaturesManager($this->featuresManager);
$instance->setAssigner($this);
$instance->setEntityTypeManager($this->entityTypeManager);
@@ -261,7 +261,7 @@ class FeaturesAssigner implements FeaturesAssignerInterface {
*/
public function getBundleList() {
if (empty($this->bundles)) {
- $this->bundles = array();
+ $this->bundles = [];
foreach ($this->entityTypeManager->getStorage('features_bundle')->loadMultiple() as $machine_name => $bundle) {
$this->bundles[$machine_name] = $bundle;
}
@@ -279,7 +279,7 @@ class FeaturesAssigner implements FeaturesAssignerInterface {
return $bundle;
}
}
- $machine_name = strtolower(str_replace(array(' ', '-'), '_', $name));
+ $machine_name = strtolower(str_replace([' ', '-'], '_', $name));
if (isset($bundles[$machine_name])) {
return $bundles[$machine_name];
}
@@ -311,7 +311,7 @@ class FeaturesAssigner implements FeaturesAssignerInterface {
$bundle->setDescription($description);
}
else {
- $bundle->setDescription(t('Auto-generated bundle from package @name', array('@name' => $name)));
+ $bundle->setDescription(t('Auto-generated bundle from package @name', ['@name' => $name]));
}
$bundle->setIsProfile($is_profile);
if (isset($profile_name)) {
@@ -374,7 +374,7 @@ class FeaturesAssigner implements FeaturesAssignerInterface {
*/
public function getBundleOptions() {
$list = $this->getBundleList();
- $result = array();
+ $result = [];
foreach ($list as $machine_name => $bundle) {
$result[$machine_name] = $bundle->getName();
}
diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesConfigDependencyManager.php b/sites/all/modules/contrib/admin/features/src/FeaturesConfigDependencyManager.php
index cca3507a1..ea01e305c 100644
--- a/sites/all/modules/contrib/admin/features/src/FeaturesConfigDependencyManager.php
+++ b/sites/all/modules/contrib/admin/features/src/FeaturesConfigDependencyManager.php
@@ -17,9 +17,9 @@ class FeaturesConfigDependencyManager extends ConfigDependencyManager{
* {@inheritdoc}
*/
public function getDependentEntities($type, $name) {
- $dependent_entities = array();
+ $dependent_entities = [];
- $entities_to_check = array();
+ $entities_to_check = [];
if ($type == 'config') {
$entities_to_check[] = $name;
}
@@ -42,7 +42,7 @@ class FeaturesConfigDependencyManager extends ConfigDependencyManager{
// always after field storages. This is because field storages need to be
// created before a field.
$this->sorted_graph = $this->getGraph();
- uasort($this->sorted_graph, array($this, 'sortGraph'));
+ uasort($this->sorted_graph, [$this, 'sortGraph']);
}
return array_replace(array_intersect_key($this->sorted_graph, $dependencies), $dependencies);
}
diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesConfigInstaller.php b/sites/all/modules/contrib/admin/features/src/FeaturesConfigInstaller.php
index 2d7edd0e6..da4c2a941 100644
--- a/sites/all/modules/contrib/admin/features/src/FeaturesConfigInstaller.php
+++ b/sites/all/modules/contrib/admin/features/src/FeaturesConfigInstaller.php
@@ -75,7 +75,7 @@ class FeaturesConfigInstaller extends ConfigInstaller {
$features_config = array_keys($this->featuresManager->listExistingConfig());
// Map array so we can use isset instead of in_array for faster access.
$features_config = array_combine($features_config, $features_config);
- $existing_configuration = array();
+ $existing_configuration = [];
// Gather information about all the supported collections.
$collection_info = $this->configManager->getConfigCollectionInfo();
diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesExtensionStoragesByDirectory.php b/sites/all/modules/contrib/admin/features/src/FeaturesExtensionStoragesByDirectory.php
new file mode 100644
index 000000000..6c0269e9e
--- /dev/null
+++ b/sites/all/modules/contrib/admin/features/src/FeaturesExtensionStoragesByDirectory.php
@@ -0,0 +1,24 @@
+configurationLists[$prefix])) {
+ $this->configurationLists[$prefix] = [];
+ foreach ($this->extensionStorages as $directory => $extension_storage) {
+ $this->configurationLists[$prefix] += array_fill_keys($extension_storage->listAll($prefix), $directory);
+ }
+ }
+ return $this->configurationLists[$prefix];
+ }
+
+}
diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesExtensionStoragesByDirectoryInterface.php b/sites/all/modules/contrib/admin/features/src/FeaturesExtensionStoragesByDirectoryInterface.php
new file mode 100644
index 000000000..e955cecce
--- /dev/null
+++ b/sites/all/modules/contrib/admin/features/src/FeaturesExtensionStoragesByDirectoryInterface.php
@@ -0,0 +1,26 @@
+featuresManager->getPackages();
diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesGenerationMethodInterface.php b/sites/all/modules/contrib/admin/features/src/FeaturesGenerationMethodInterface.php
index b3191f202..92b939280 100644
--- a/sites/all/modules/contrib/admin/features/src/FeaturesGenerationMethodInterface.php
+++ b/sites/all/modules/contrib/admin/features/src/FeaturesGenerationMethodInterface.php
@@ -37,7 +37,7 @@ interface FeaturesGenerationMethodInterface {
* @return array
* An array of packages data.
*/
- public function prepare(array &$packages = array(), FeaturesBundleInterface $bundle = NULL);
+ public function prepare(array &$packages = [], FeaturesBundleInterface $bundle = NULL);
/**
* Performs package generation.
@@ -56,7 +56,7 @@ interface FeaturesGenerationMethodInterface {
* - 'message': a message about the result of the operation.
* - 'variables': an array of substitutions to be used in the message.
*/
- public function generate(array $packages = array(), FeaturesBundleInterface $bundle = NULL);
+ public function generate(array $packages = [], FeaturesBundleInterface $bundle = NULL);
/**
* Responds to the submission of
diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesGenerator.php b/sites/all/modules/contrib/admin/features/src/FeaturesGenerator.php
index ce461cbf2..ae21e60b7 100644
--- a/sites/all/modules/contrib/admin/features/src/FeaturesGenerator.php
+++ b/sites/all/modules/contrib/admin/features/src/FeaturesGenerator.php
@@ -69,13 +69,13 @@ class FeaturesGenerator implements FeaturesGeneratorInterface {
* {@inheritdoc}
*/
public function reset() {
- $this->methods = array();
+ $this->methods = [];
}
/**
* {@inheritdoc}
*/
- public function applyGenerationMethod($method_id, array $packages = array(), FeaturesBundleInterface $bundle = NULL) {
+ public function applyGenerationMethod($method_id, array $packages = [], FeaturesBundleInterface $bundle = NULL) {
$method = $this->getGenerationMethodInstance($method_id);
$method->prepare($packages, $bundle);
return $method->generate($packages, $bundle);
@@ -107,7 +107,7 @@ class FeaturesGenerator implements FeaturesGeneratorInterface {
*/
protected function getGenerationMethodInstance($method_id) {
if (!isset($this->methods[$method_id])) {
- $instance = $this->generatorManager->createInstance($method_id, array());
+ $instance = $this->generatorManager->createInstance($method_id, []);
$instance->setFeaturesManager($this->featuresManager);
$instance->setAssigner($this->assigner);
$this->methods[$method_id] = $instance;
@@ -118,7 +118,7 @@ class FeaturesGenerator implements FeaturesGeneratorInterface {
/**
* {@inheritdoc}
*/
- public function generatePackages($method_id, FeaturesBundleInterface $bundle, array $package_names = array()) {
+ public function generatePackages($method_id, FeaturesBundleInterface $bundle, array $package_names = []) {
$this->featuresManager->setPackageBundleNames($bundle, $package_names);
return $this->generate($method_id, $bundle, $package_names);
}
@@ -144,7 +144,7 @@ class FeaturesGenerator implements FeaturesGeneratorInterface {
* - 'message': a message about the result of the operation.
* - 'variables': an array of substitutions to be used in the message.
*/
- protected function generate($method_id, FeaturesBundleInterface $bundle, array $package_names = array()) {
+ protected function generate($method_id, FeaturesBundleInterface $bundle, array $package_names = []) {
$packages = $this->featuresManager->getPackages();
// Filter out the packages that weren't requested.
diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesGeneratorInterface.php b/sites/all/modules/contrib/admin/features/src/FeaturesGeneratorInterface.php
index 485e71bea..0cafa1451 100644
--- a/sites/all/modules/contrib/admin/features/src/FeaturesGeneratorInterface.php
+++ b/sites/all/modules/contrib/admin/features/src/FeaturesGeneratorInterface.php
@@ -71,7 +71,7 @@ interface FeaturesGeneratorInterface {
* - 'message': a message about the result of the operation.
* - 'variables': an array of substitutions to be used in the message.
*/
- public function applyGenerationMethod($method_id, array $packages = array(), FeaturesBundleInterface $bundle = NULL);
+ public function applyGenerationMethod($method_id, array $packages = [], FeaturesBundleInterface $bundle = NULL);
/**
* Responds to the submission of
@@ -98,6 +98,6 @@ interface FeaturesGeneratorInterface {
* Array of names of packages to be generated. If none are specified, all
* available packages will be added.
*/
- public function generatePackages($method_id, FeaturesBundleInterface $bundle, array $package_names = array());
+ public function generatePackages($method_id, FeaturesBundleInterface $bundle, array $package_names = []);
}
diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesInstallStorage.php b/sites/all/modules/contrib/admin/features/src/FeaturesInstallStorage.php
index 3742ea17b..666b5d680 100644
--- a/sites/all/modules/contrib/admin/features/src/FeaturesInstallStorage.php
+++ b/sites/all/modules/contrib/admin/features/src/FeaturesInstallStorage.php
@@ -66,7 +66,7 @@ class FeaturesInstallStorage extends ExtensionInstallStorage {
*/
public function getAllFolders() {
if (!isset($this->folders)) {
- $this->folders = array();
+ $this->folders = [];
$this->folders += $this->getCoreNames();
$install_profile = Settings::get('install_profile');
@@ -117,8 +117,8 @@ class FeaturesInstallStorage extends ExtensionInstallStorage {
// CHANGED START: Put Features modules first in list returned.
// to allow features to override config provided by other extensions.
$featuresManager = \Drupal::service('features.manager');
- $features_list = array();
- $module_list = array();
+ $features_list = [];
+ $module_list = [];
foreach (array_keys($module_list_scan) as $module) {
if ($featuresManager->isFeatureModule($module_list_scan[$module])) {
$features_list[$module] = $module_list_scan[$module];
@@ -150,7 +150,7 @@ class FeaturesInstallStorage extends ExtensionInstallStorage {
$profile_list = $listing->scan('profile');
}
if (isset($profile_list[$profile])) {
- $profile_folders = $this->getComponentNames(array($profile_list[$profile]));
+ $profile_folders = $this->getComponentNames([$profile_list[$profile]]);
$this->folders = $profile_folders + $this->folders;
}
}
diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesManager.php b/sites/all/modules/contrib/admin/features/src/FeaturesManager.php
index cf9329707..07c46e042 100644
--- a/sites/all/modules/contrib/admin/features/src/FeaturesManager.php
+++ b/sites/all/modules/contrib/admin/features/src/FeaturesManager.php
@@ -39,7 +39,7 @@ class FeaturesManager implements FeaturesManagerInterface {
/**
* The extension storages.
*
- * @var \Drupal\features\FeaturesExtensionStoragesInterface
+ * @var \Drupal\features\FeaturesExtensionStoragesByDirectoryInterface
*/
protected $extensionStorages;
@@ -148,7 +148,7 @@ class FeaturesManager implements FeaturesManagerInterface {
$this->configFactory = $config_factory;
$this->configReverter = $config_reverter;
$this->settings = $config_factory->getEditable('features.settings');
- $this->extensionStorages = new FeaturesExtensionStorages($this->configStorage);
+ $this->extensionStorages = new FeaturesExtensionStoragesByDirectory($this->configStorage);
$this->extensionStorages->addStorage(InstallStorage::CONFIG_INSTALL_DIRECTORY);
$this->extensionStorages->addStorage(InstallStorage::CONFIG_OPTIONAL_DIRECTORY);
$this->packages = [];
@@ -196,10 +196,10 @@ class FeaturesManager implements FeaturesManagerInterface {
* {@inheritdoc}
*/
public function getConfigType($fullname) {
- $result = array(
+ $result = [
'type' => '',
'name_short' => '',
- );
+ ];
$prefix = FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG . '.';
if (strpos($fullname, $prefix) !== FALSE) {
$result['type'] = FeaturesManagerInterface::SYSTEM_SIMPLE_CONFIG;
@@ -320,7 +320,7 @@ class FeaturesManager implements FeaturesManagerInterface {
* {@inheritdoc}
*/
public function filterPackages(array $packages, $namespace = '', $only_exported = FALSE) {
- $result = array();
+ $result = [];
/** @var \Drupal\features\Package $package */
foreach ($packages as $key => $package) {
// A package matches the namespace if:
@@ -417,7 +417,7 @@ class FeaturesManager implements FeaturesManagerInterface {
/**
* {@inheritdoc}
*/
- public function listPackageDirectories(array $machine_names = array(), FeaturesBundleInterface $bundle = NULL) {
+ public function listPackageDirectories(array $machine_names = [], FeaturesBundleInterface $bundle = NULL) {
if (empty($machine_names)) {
$machine_names = array_keys($this->getPackages());
}
@@ -438,7 +438,7 @@ class FeaturesManager implements FeaturesManagerInterface {
return in_array($module->getName(), $machine_names);
});
- $directories = array();
+ $directories = [];
foreach ($modules as $module) {
$directories[$module->getName()] = $module->getPath();
}
@@ -546,7 +546,7 @@ class FeaturesManager implements FeaturesManagerInterface {
* @param array $module_list
* @return array $dependencies
*/
- protected function getConfigDependency(ConfigurationItem $config, $module_list = array()) {
+ protected function getConfigDependency(ConfigurationItem $config, $module_list = []) {
$dependencies = [];
$type = $config->getType();
@@ -737,7 +737,7 @@ class FeaturesManager implements FeaturesManagerInterface {
$packages = $this->getPackages();
}
else {
- $packages = array($package);
+ $packages = [$package];
}
$module_list = $this->moduleHandler->getModuleList();
$config_collection = $this->getConfigCollection();
@@ -940,7 +940,7 @@ class FeaturesManager implements FeaturesManagerInterface {
}
if ($package->getConfig()) {
- foreach (array('excluded', 'required') as $constraint) {
+ foreach (['excluded', 'required'] as $constraint) {
if (!empty($package->{'get' . $constraint}())) {
$features_info[$constraint] = $package->{'get' . $constraint}();
}
@@ -957,7 +957,7 @@ class FeaturesManager implements FeaturesManagerInterface {
// The name and description need to be cast as strings from the
// TranslatableMarkup objects returned by t() to avoid raising an
// InvalidDataTypeException on Yaml serialization.
- foreach (array('name', 'description') as $key) {
+ foreach (['name', 'description'] as $key) {
$info[$key] = (string) $info[$key];
}
@@ -1008,7 +1008,7 @@ class FeaturesManager implements FeaturesManagerInterface {
/**
* {@inheritdoc}
*/
- public function mergeInfoArray(array $info1, array $info2, array $keys = array()) {
+ public function mergeInfoArray(array $info1, array $info2, array $keys = []) {
// If keys were specified, use only those.
if (!empty($keys)) {
$info2 = array_intersect_key($info2, array_fill_keys($keys, NULL));
@@ -1061,7 +1061,7 @@ class FeaturesManager implements FeaturesManagerInterface {
* {@inheritdoc}
*/
public function listExistingConfig($installed = FALSE, FeaturesBundleInterface $bundle = NULL) {
- $config = array();
+ $config = [];
$existing = $this->getFeaturesModules($bundle, $installed);
foreach ($existing as $extension) {
// Keys are configuration item names and values are providing extension
@@ -1150,6 +1150,7 @@ class FeaturesManager implements FeaturesManagerInterface {
$dependency_manager = $this->getFeaturesConfigDependencyManager();
// List configuration provided by installed features.
$existing_config = $this->listExistingConfig(NULL);
+ $existing_config_by_directory = $this->extensionStorages->listAllByDirectory();
foreach (array_keys($config_types) as $config_type) {
$config = $this->listConfigByType($config_type);
foreach ($config as $item_name => $label) {
@@ -1162,7 +1163,7 @@ class FeaturesManager implements FeaturesManagerInterface {
'type' => $config_type,
'dependents' => array_keys($dependency_manager->getDependentEntities('config', $name)),
// Default to the install directory.
- 'subdirectory' => InstallStorage::CONFIG_INSTALL_DIRECTORY,
+ 'subdirectory' => isset($existing_config_by_directory[$name]) ? $existing_config_by_directory[$name] : InstallStorage::CONFIG_INSTALL_DIRECTORY,
'package' => '',
'providerExcluded' => NULL,
'provider' => isset($existing_config[$name]) ? $existing_config[$name] : NULL,
@@ -1211,7 +1212,7 @@ class FeaturesManager implements FeaturesManagerInterface {
$path = dirname($extension_path);
}
- return array($full_name, $path);
+ return [$full_name, $path];
}
/**
@@ -1221,11 +1222,11 @@ class FeaturesManager implements FeaturesManagerInterface {
/** @var \Drupal\config_update\ConfigDiffInterface $config_diff */
$config_diff = \Drupal::service('config_update.config_diff');
- $different = array();
+ $different = [];
foreach ($feature->getConfig() as $name) {
$active = $this->configStorage->read($name);
$extension = $this->extensionStorages->read($name);
- $extension = !empty($extension) ? $extension : array();
+ $extension = !empty($extension) ? $extension : [];
if (($include_new || !empty($extension)) && !$config_diff->same($extension, $active)) {
$different[] = $name;
}
@@ -1241,7 +1242,7 @@ class FeaturesManager implements FeaturesManagerInterface {
* {@inheritdoc}
*/
public function detectNew(Package $feature) {
- $result = array();
+ $result = [];
foreach ($feature->getConfig() as $name) {
$extension = $this->extensionStorages->read($name);
if (empty($extension)) {
@@ -1256,7 +1257,7 @@ class FeaturesManager implements FeaturesManagerInterface {
*/
public function detectMissing(Package $feature) {
$config = $this->getConfigCollection();
- $result = array();
+ $result = [];
foreach ($feature->getConfigOrig() as $name) {
if (!isset($config[$name])) {
$result[] = $name;
@@ -1269,8 +1270,8 @@ class FeaturesManager implements FeaturesManagerInterface {
* {@inheritdoc}
*/
public function reorderMissing(array $missing) {
- $list = array();
- $result = array();
+ $list = [];
+ $result = [];
foreach ($missing as $full_name) {
$this->addConfigList($full_name, $list);
}
diff --git a/sites/all/modules/contrib/admin/features/src/FeaturesManagerInterface.php b/sites/all/modules/contrib/admin/features/src/FeaturesManagerInterface.php
index 6416a647a..2f47e5248 100644
--- a/sites/all/modules/contrib/admin/features/src/FeaturesManagerInterface.php
+++ b/sites/all/modules/contrib/admin/features/src/FeaturesManagerInterface.php
@@ -328,7 +328,7 @@ interface FeaturesManagerInterface {
* @return array
* Array of package directories keyed by package machine name.
*/
- public function listPackageDirectories(array $machine_names = array(), FeaturesBundleInterface $bundle = NULL);
+ public function listPackageDirectories(array $machine_names = [], FeaturesBundleInterface $bundle = NULL);
/**
* Assigns a set of configuration items to a given package or profile.
@@ -414,7 +414,7 @@ interface FeaturesManagerInterface {
*
* @fixme Should this be moved to the package object or a related helper?
*/
- public function mergeInfoArray(array $info1, array $info2, array $keys = array());
+ public function mergeInfoArray(array $info1, array $info2, array $keys = []);
/**
* Lists the types of configuration available on the site.
diff --git a/sites/all/modules/contrib/admin/features/src/Package.php b/sites/all/modules/contrib/admin/features/src/Package.php
index 2fb459a1d..c7f2872a2 100644
--- a/sites/all/modules/contrib/admin/features/src/Package.php
+++ b/sites/all/modules/contrib/admin/features/src/Package.php
@@ -429,7 +429,7 @@ class Package {
$this->setBundle($features_info['bundle']);
}
$this->setRequired(isset($features_info['required']) ? $features_info['required'] : false);
- $this->setExcluded(isset($features_info['excluded']) ? $features_info['excluded'] : array());
+ $this->setExcluded(isset($features_info['excluded']) ? $features_info['excluded'] : []);
return $this;
}
diff --git a/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentBaseType.php b/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentBaseType.php
index 40fcbca85..a8f83cb64 100644
--- a/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentBaseType.php
+++ b/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentBaseType.php
@@ -2,7 +2,7 @@
namespace Drupal\features\Plugin\FeaturesAssignment;
-use Drupal\component\Utility\Unicode;
+use Drupal\Component\Utility\Unicode;
use Drupal\features\FeaturesAssignmentMethodBase;
/**
@@ -37,7 +37,7 @@ class FeaturesAssignmentBaseType extends FeaturesAssignmentMethodBase {
foreach ($config_collection as $item_name => $item) {
if (in_array($item->getType(), $config_base_types)) {
if (is_null($this->featuresManager->findPackage($item->getShortName())) && !$item->getPackage()) {
- $description = $this->t('Provides @label @type and related configuration.', array('@label' => $item->getLabel(), '@type' => Unicode::strtolower($config_types[$item->getType()])));
+ $description = $this->t('Provides @label @type and related configuration.', ['@label' => $item->getLabel(), '@type' => Unicode::strtolower($config_types[$item->getType()])]);
if (isset($item->getData()['description'])) {
$description .= ' ' . $item->getData()['description'];
}
@@ -59,7 +59,7 @@ class FeaturesAssignmentBaseType extends FeaturesAssignmentMethodBase {
foreach ($content_base_types as $entity_type_id) {
if (!isset($packages[$entity_type_id]) && isset($entity_types[$entity_type_id])) {
$label = $entity_types[$entity_type_id]->getLabel();
- $description = $this->t('Provide @label related configuration.', array('@label' => $label));
+ $description = $this->t('Provide @label related configuration.', ['@label' => $label]);
$this->featuresManager->initPackage($entity_type_id, $label, $description, 'module', $current_bundle);
}
}
diff --git a/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php b/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php
index 0783d4d54..81c503e07 100644
--- a/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php
+++ b/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesAssignment/FeaturesAssignmentProfile.php
@@ -71,7 +71,7 @@ class FeaturesAssignmentProfile extends FeaturesAssignmentMethodBase {
// Only read in from the Standard profile if this profile doesn't already
// exist.
- $package_directories = $this->featuresManager->listPackageDirectories(array(), $current_bundle);
+ $package_directories = $this->featuresManager->listPackageDirectories([], $current_bundle);
if (!isset($package_directories[$profile_name])) {
$standard_directory = 'core/profiles/standard';
// Conditionally add files from the 'standard' install profile.
diff --git a/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php b/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php
index 2565685b5..a40c7a6dc 100644
--- a/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php
+++ b/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesGeneration/FeaturesGenerationArchive.php
@@ -128,7 +128,7 @@ class FeaturesGenerationArchive extends FeaturesGenerationMethodBase implements
/**
* {@inheritdoc}
*/
- public function generate(array $packages = array(), FeaturesBundleInterface $bundle = NULL) {
+ public function generate(array $packages = [], FeaturesBundleInterface $bundle = NULL) {
// If no packages were specified, get all packages.
if (empty($packages)) {
diff --git a/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesGeneration/FeaturesGenerationWrite.php b/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesGeneration/FeaturesGenerationWrite.php
index 118108c7d..5844c0e2d 100644
--- a/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesGeneration/FeaturesGenerationWrite.php
+++ b/sites/all/modules/contrib/admin/features/src/Plugin/FeaturesGeneration/FeaturesGenerationWrite.php
@@ -101,7 +101,7 @@ class FeaturesGenerationWrite extends FeaturesGenerationMethodBase implements Co
/**
* {@inheritdoc}
*/
- public function generate(array $packages = array(), FeaturesBundleInterface $bundle = NULL) {
+ public function generate(array $packages = [], FeaturesBundleInterface $bundle = NULL) {
// If no packages were specified, get all packages.
if (empty($packages)) {
$packages = $this->featuresManager->getPackages();
diff --git a/sites/all/modules/contrib/admin/features/tests/modules/test_feature/test_feature.info.yml b/sites/all/modules/contrib/admin/features/tests/modules/test_feature/test_feature.info.yml
index 4f9d07045..b90578e88 100644
--- a/sites/all/modules/contrib/admin/features/tests/modules/test_feature/test_feature.info.yml
+++ b/sites/all/modules/contrib/admin/features/tests/modules/test_feature/test_feature.info.yml
@@ -6,8 +6,8 @@ package: Test
dependencies:
- features
-# Information added by Drupal.org packaging script on 2018-02-27
-version: '8.x-3.7'
+# Information added by Drupal.org packaging script on 2018-09-09
+version: '8.x-3.8'
core: '8.x'
project: 'features'
-datestamp: 1519763291
+datestamp: 1536512288
diff --git a/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml b/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml
index f3c033933..2f0e6404a 100644
--- a/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml
+++ b/sites/all/modules/contrib/admin/features/tests/modules/test_mybundle_core/test_mybundle_core.info.yml
@@ -6,8 +6,8 @@ package: Test
dependencies:
- features
-# Information added by Drupal.org packaging script on 2018-02-27
-version: '8.x-3.7'
+# Information added by Drupal.org packaging script on 2018-09-09
+version: '8.x-3.8'
core: '8.x'
project: 'features'
-datestamp: 1519763291
+datestamp: 1536512288
diff --git a/sites/all/modules/contrib/admin/features/tests/src/Kernel/FeaturesAssignerTest.php b/sites/all/modules/contrib/admin/features/tests/src/Kernel/FeaturesAssignerTest.php
index 6bf9f0371..0477ece05 100644
--- a/sites/all/modules/contrib/admin/features/tests/src/Kernel/FeaturesAssignerTest.php
+++ b/sites/all/modules/contrib/admin/features/tests/src/Kernel/FeaturesAssignerTest.php
@@ -18,6 +18,15 @@ class FeaturesAssignerTest extends KernelTestBase {
protected $strictConfigSchema = FALSE;
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+ // We need system.site in order to run $this->configImporter->import().
+ $this->installConfig('system');
+ }
+
/**
* Test bundle auto-creation during config import.
*
@@ -41,7 +50,7 @@ class FeaturesAssignerTest extends KernelTestBase {
// Uninstall modules.
$installer->uninstall(['features', 'test_feature']);
- // Restore the config from after install..
+ // Restore the config from after install.
$this->configImporter()->import();
// Find the auto-created bundle.
diff --git a/sites/all/modules/contrib/admin/pathauto/config/install/pathauto.settings.yml b/sites/all/modules/contrib/admin/pathauto/config/install/pathauto.settings.yml
index 74a75cdd2..03004aa1d 100644
--- a/sites/all/modules/contrib/admin/pathauto/config/install/pathauto.settings.yml
+++ b/sites/all/modules/contrib/admin/pathauto/config/install/pathauto.settings.yml
@@ -11,3 +11,10 @@ reduce_ascii : FALSE
case : TRUE
ignore_words : 'a, an, as, at, before, but, by, for, from, is, in, into, like, of, off, on, onto, per, since, than, the, this, that, to, up, via, with'
update_action : 2
+safe_tokens:
+ - alias
+ - path
+ - join-path
+ - login-url
+ - url
+ - url-brief
diff --git a/sites/all/modules/contrib/admin/pathauto/config/schema/pathauto.schema.yml b/sites/all/modules/contrib/admin/pathauto/config/schema/pathauto.schema.yml
index ca04411e8..1da59f187 100644
--- a/sites/all/modules/contrib/admin/pathauto/config/schema/pathauto.schema.yml
+++ b/sites/all/modules/contrib/admin/pathauto/config/schema/pathauto.schema.yml
@@ -22,14 +22,17 @@ pathauto.settings:
type: boolean
reduce_ascii:
type: boolean
- ignore_words:
- type: string
case:
type: boolean
ignore_words:
type: string
update_action:
type: integer
+ safe_tokens:
+ label: Tokens that are safe to use and do not need to be cleaned.
+ type: sequence
+ sequence:
+ type: string
action.configuration.pathauto_update_alias:
type: action_configuration_default
diff --git a/sites/all/modules/contrib/admin/pathauto/pathauto.api.php b/sites/all/modules/contrib/admin/pathauto/pathauto.api.php
index fc9272f8f..6595116fd 100644
--- a/sites/all/modules/contrib/admin/pathauto/pathauto.api.php
+++ b/sites/all/modules/contrib/admin/pathauto/pathauto.api.php
@@ -93,9 +93,8 @@ function hook_pathauto_is_alias_reserved($alias, $source, $langcode) {
* This hook will only be called if a default pattern is configured (on
* admin/config/search/path/patterns).
*
- * @param string $pattern
- * The alias pattern for Pathauto to pass to token_replace() to generate the
- * URL alias.
+ * @param \Drupal\pathauto\PathautoPatternInterface $pattern
+ * The Pathauto pattern to be used.
* @param array $context
* An associative array of additional options, with the following elements:
* - 'module': The module or entity type being aliased.
@@ -103,14 +102,14 @@ function hook_pathauto_is_alias_reserved($alias, $source, $langcode) {
* aliased. Can be either 'insert', 'update', 'return', or 'bulkupdate'.
* - 'source': A string of the source path for the alias (e.g. 'node/1').
* - 'data': An array of keyed objects to pass to token_replace().
- * - 'type': The sub-type or bundle of the object being aliased.
+ * - 'bundle': The sub-type or bundle of the object being aliased.
* - 'language': A string of the language code for the alias (e.g. 'en').
* This can be altered by reference.
*/
-function hook_pathauto_pattern_alter(&$pattern, array $context) {
+function hook_pathauto_pattern_alter(\Drupal\pathauto\PathautoPatternInterface $pattern, array $context) {
// Switch out any [node:created:*] tokens with [node:updated:*] on update.
if ($context['module'] == 'node' && ($context['op'] == 'update')) {
- $pattern = preg_replace('/\[node:created(\:[^]]*)?\]/', '[node:updated$1]', $pattern);
+ $pattern->setPattern(preg_replace('/\[node:created(\:[^]]*)?\]/', '[node:updated$1]', $pattern->getPattern()));
}
}
@@ -133,7 +132,7 @@ function hook_pathauto_pattern_alter(&$pattern, array $context) {
* - 'pattern': A string of the pattern used for aliasing the object.
*/
function hook_pathauto_alias_alter(&$alias, array &$context) {
- // Add a suffix so that all aliases get saved as 'content/my-title.html'
+ // Add a suffix so that all aliases get saved as 'content/my-title.html'.
$alias .= '.html';
// Force all aliases to be saved as language neutral.
@@ -143,7 +142,7 @@ function hook_pathauto_alias_alter(&$alias, array &$context) {
/**
* Alter the list of punctuation characters for Pathauto control.
*
- * @param $punctuation
+ * @param array $punctuation
* An array of punctuation to be controlled by Pathauto during replacement
* keyed by punctuation name. Each punctuation record should be an array
* with the following key/value pairs:
diff --git a/sites/all/modules/contrib/admin/pathauto/pathauto.info.yml b/sites/all/modules/contrib/admin/pathauto/pathauto.info.yml
index 2868629a0..c661dae56 100644
--- a/sites/all/modules/contrib/admin/pathauto/pathauto.info.yml
+++ b/sites/all/modules/contrib/admin/pathauto/pathauto.info.yml
@@ -6,6 +6,7 @@ type: module
dependencies:
- ctools:ctools
- drupal:path
+- drupal:system (>=8.5)
- token:token
configure: entity.pathauto_pattern.collection
@@ -13,8 +14,8 @@ configure: entity.pathauto_pattern.collection
recommends:
- redirect:redirect
-# Information added by Drupal.org packaging script on 2018-03-03
-version: '8.x-1.1'
+# Information added by Drupal.org packaging script on 2018-09-08
+version: '8.x-1.3'
core: '8.x'
project: 'pathauto'
-datestamp: 1520092688
+datestamp: 1536407890
diff --git a/sites/all/modules/contrib/admin/pathauto/pathauto.install b/sites/all/modules/contrib/admin/pathauto/pathauto.install
index f8de322f6..4b160ba10 100644
--- a/sites/all/modules/contrib/admin/pathauto/pathauto.install
+++ b/sites/all/modules/contrib/admin/pathauto/pathauto.install
@@ -8,15 +8,13 @@
*/
use Drupal\Core\Entity\Entity\EntityFormDisplay;
-use Drupal\Core\Plugin\Context\Context;
-use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\pathauto\Entity\PathautoPattern;
/**
* Implements hook_install().
*/
function pathauto_install() {
- // Set the weight to 1
+ // Set the weight to 1.
module_set_weight('pathauto', 1);
// Ensure the url_alias table exists.
@@ -170,7 +168,8 @@ function pathauto_update_8100() {
continue;
}
- // This is a pattern for a bundle and a language, such as "node_article_es".
+ // This is a pattern for a bundle and a language, such as
+ // "node_article_es".
$pattern = PathautoPattern::create([
'id' => $entity_type . '_' . $extracted_bundle . '_' . str_replace('-', '_', $langcode),
'label' => $entity_label . ' ' . $bundle_info[$extracted_bundle]['label'] . ' ' . $language->getName(),
@@ -299,3 +298,23 @@ function pathauto_update_8106() {
$config->set('enabled_entity_types', ['user']);
$config->save();
}
+
+/**
+ * Initialize the new safe tokens setting.
+ */
+function pathauto_update_8107() {
+
+ $safe_tokens = [
+ 'alias',
+ 'alias',
+ 'path',
+ 'join-path',
+ 'login-url',
+ 'url',
+ 'url-brief',
+ ];
+
+ \Drupal::configFactory()->getEditable('pathauto.settings')
+ ->set('safe_tokens', $safe_tokens)
+ ->save();
+}
diff --git a/sites/all/modules/contrib/admin/pathauto/pathauto.js b/sites/all/modules/contrib/admin/pathauto/pathauto.js
index d4e068f6b..3bdc3d561 100644
--- a/sites/all/modules/contrib/admin/pathauto/pathauto.js
+++ b/sites/all/modules/contrib/admin/pathauto/pathauto.js
@@ -2,9 +2,9 @@
'use strict';
Drupal.behaviors.pathFieldsetSummaries = {
attach: function (context) {
- $('fieldset.path-form', context).drupalSetSummary(function (context) {
- var path = $('.form-item-path-alias input', context).val();
- var automatic = $('.form-item-path-pathauto input', context).attr('checked');
+ $(context).find('.path-form').drupalSetSummary(function (context) {
+ var path = $('.js-form-item-path-0-alias input', context).val();
+ var automatic = $('.js-form-item-path-0-pathauto input', context).prop('checked');
if (automatic) {
return Drupal.t('Automatic alias');
diff --git a/sites/all/modules/contrib/admin/pathauto/pathauto.links.action.yml b/sites/all/modules/contrib/admin/pathauto/pathauto.links.action.yml
index d68b94a88..0afa384db 100644
--- a/sites/all/modules/contrib/admin/pathauto/pathauto.links.action.yml
+++ b/sites/all/modules/contrib/admin/pathauto/pathauto.links.action.yml
@@ -3,4 +3,3 @@ entity.pathauto_pattern.add_form:
title: 'Add Pathauto pattern'
appears_on:
- entity.pathauto_pattern.collection
-
diff --git a/sites/all/modules/contrib/admin/pathauto/pathauto.module b/sites/all/modules/contrib/admin/pathauto/pathauto.module
index 11d4234c6..ac7d9b0c0 100644
--- a/sites/all/modules/contrib/admin/pathauto/pathauto.module
+++ b/sites/all/modules/contrib/admin/pathauto/pathauto.module
@@ -18,6 +18,8 @@
* @ingroup pathauto
*/
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Form\FormStateInterface;
@@ -82,6 +84,30 @@ function pathauto_help($route_name, RouteMatchInterface $route_match) {
}
}
+/**
+ * Implements hook_entity_insert().
+ */
+function pathauto_entity_insert(EntityInterface $entity) {
+ \Drupal::service('pathauto.generator')->updateEntityAlias($entity, 'insert');
+}
+
+/**
+ * Implements hook_entity_update().
+ */
+function pathauto_entity_update(EntityInterface $entity) {
+ \Drupal::service('pathauto.generator')->updateEntityAlias($entity, 'update');
+}
+
+/**
+ * Implements hook_entity_delete().
+ */
+function pathauto_entity_delete(EntityInterface $entity) {
+ if ($entity->hasLinkTemplate('canonical') && $entity instanceof ContentEntityInterface && $entity->hasField('path')) {
+ \Drupal::service('pathauto.alias_storage_helper')->deleteEntityPathAll($entity);
+ $entity->get('path')->first()->get('pathauto')->purge();
+ }
+}
+
/**
* Implements hook_field_info_alter().
*/
diff --git a/sites/all/modules/contrib/admin/pathauto/pathauto.services.yml b/sites/all/modules/contrib/admin/pathauto/pathauto.services.yml
index 3ce704ec7..8848f7f33 100644
--- a/sites/all/modules/contrib/admin/pathauto/pathauto.services.yml
+++ b/sites/all/modules/contrib/admin/pathauto/pathauto.services.yml
@@ -15,7 +15,7 @@ services:
arguments: ['@config.factory', '@pathauto.alias_storage_helper','@module_handler', '@router.route_provider', '@path.alias_manager']
pathauto.verbose_messenger:
class: Drupal\pathauto\VerboseMessenger
- arguments: ['@config.factory', '@current_user']
+ arguments: ['@config.factory', '@current_user', '@messenger']
plugin.manager.alias_type:
class: Drupal\pathauto\AliasTypeManager
parent: default_plugin_manager
diff --git a/sites/all/modules/contrib/admin/pathauto/src/AliasCleaner.php b/sites/all/modules/contrib/admin/pathauto/src/AliasCleaner.php
index 340a26673..cb8b6d125 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/AliasCleaner.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/AliasCleaner.php
@@ -104,7 +104,7 @@ class AliasCleaner implements AliasCleanerInterface {
// Trim duplicate, leading, and trailing separators. Do this before cleaning
// backslashes since a pattern like "[token1]/[token2]-[token3]/[token4]"
// could end up like "value1/-/value2" and if backslashes were cleaned first
- // this would result in a duplicate blackslash.
+ // this would result in a duplicate backslash.
$output = $this->getCleanSeparators($output);
// Trim duplicate, leading, and trailing backslashes.
@@ -247,7 +247,7 @@ class AliasCleaner implements AliasCleanerInterface {
// Get rid of words that are on the ignore list.
if ($this->cleanStringCache['ignore_words_regex']) {
$words_removed = $this->cleanStringCache['ignore_words_callback']($this->cleanStringCache['ignore_words_regex'], '', $output);
- if (Unicode::strlen(trim($words_removed)) > 0) {
+ if (mb_strlen(trim($words_removed)) > 0) {
$output = $words_removed;
}
}
@@ -260,7 +260,7 @@ class AliasCleaner implements AliasCleanerInterface {
// Optionally convert to lower case.
if ($this->cleanStringCache['lowercase']) {
- $output = Unicode::strtolower($output);
+ $output = mb_strtolower($output);
}
// Shorten to a logical place based on word boundaries.
@@ -335,7 +335,9 @@ class AliasCleaner implements AliasCleanerInterface {
public function cleanTokenValues(&$replacements, $data = array(), $options = array()) {
foreach ($replacements as $token => $value) {
// Only clean non-path tokens.
- if (!preg_match('/(path|alias|url|url-brief)\]$/', $token)) {
+ $config = $this->configFactory->get('pathauto.settings');
+ $safe_tokens = implode('|', (array) $config->get('safe_tokens'));
+ if (!preg_match('/:(' . $safe_tokens . ')(:|\]$)/', $token)) {
$replacements[$token] = $this->cleanString($value, $options);
}
}
diff --git a/sites/all/modules/contrib/admin/pathauto/src/AliasCleanerInterface.php b/sites/all/modules/contrib/admin/pathauto/src/AliasCleanerInterface.php
index 87cc27e7d..95d2920f7 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/AliasCleanerInterface.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/AliasCleanerInterface.php
@@ -72,8 +72,8 @@ interface AliasCleanerInterface {
/**
* Return an array of arrays for punctuation values.
*
- * Returns an array of arrays for punctuation values keyed by a name, including
- * the value and a textual description.
+ * Returns an array of arrays for punctuation values keyed by a name,
+ * including the value and a textual description.
* Can and should be expanded to include "all" non text punctuation values.
*
* @return array
diff --git a/sites/all/modules/contrib/admin/pathauto/src/AliasStorageHelperInterface.php b/sites/all/modules/contrib/admin/pathauto/src/AliasStorageHelperInterface.php
index 4f1788017..9b3b2bd86 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/AliasStorageHelperInterface.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/AliasStorageHelperInterface.php
@@ -1,6 +1,7 @@
configFactory = $config_factory;
diff --git a/sites/all/modules/contrib/admin/pathauto/src/AliasUniquifierInterface.php b/sites/all/modules/contrib/admin/pathauto/src/AliasUniquifierInterface.php
index 2da4ba27a..89649eab3 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/AliasUniquifierInterface.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/AliasUniquifierInterface.php
@@ -1,6 +1,7 @@
entityFieldManager = $entity_field_manager;
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoAdminDelete.php b/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoAdminDelete.php
index a23052520..277c30700 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoAdminDelete.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoAdminDelete.php
@@ -133,14 +133,14 @@ class PathautoAdminDelete extends FormBase {
}
else if ($delete_all) {
\Drupal::service('pathauto.alias_storage_helper')->deleteAll();
- drupal_set_message($this->t('All of your path aliases have been deleted.'));
+ $this->messenger()->addMessage($this->t('All of your path aliases have been deleted.'));
}
else {
$storage_helper = \Drupal::service('pathauto.alias_storage_helper');
foreach (array_keys(array_filter($form_state->getValue(['delete', 'plugins']))) as $id) {
$alias_type = $this->aliasTypeManager->createInstance($id);
$storage_helper->deleteBySourcePrefix((string) $alias_type->getSourcePrefix());
- drupal_set_message($this->t('All of your %label path aliases have been deleted.', ['%label' => $alias_type->getLabel()]));
+ $this->messenger()->addMessage($this->t('All of your %label path aliases have been deleted.', ['%label' => $alias_type->getLabel()]));
}
}
}
@@ -168,17 +168,25 @@ class PathautoAdminDelete extends FormBase {
public static function batchFinished($success, $results, $operations) {
if ($success) {
if ($results['delete_all']) {
- drupal_set_message(t('All of your automatically generated path aliases have been deleted.'));
+ \Drupal::service('messenger')
+ ->addMessage(t('All of your automatically generated path aliases have been deleted.'));
}
else if (isset($results['deletions'])) {
foreach (array_values($results['deletions']) as $label) {
- drupal_set_message(t('All of your automatically generated %label path aliases have been deleted.', ['%label' => $label]));
+ \Drupal::service('messenger')
+ ->addMessage(t('All of your automatically generated %label path aliases have been deleted.', [
+ '%label' => $label,
+ ]));
}
}
}
else {
$error_operation = reset($operations);
- drupal_set_message(t('An error occurred while processing @operation with arguments : @args', array('@operation' => $error_operation[0], '@args' => print_r($error_operation[0], TRUE))));
+ \Drupal::service('messenger')
+ ->addMessage(t('An error occurred while processing @operation with arguments : @args', [
+ '@operation' => $error_operation[0],
+ '@args' => print_r($error_operation[0]),
+ ]));
}
}
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoBulkUpdateForm.php b/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoBulkUpdateForm.php
index e66cd9df5..67a026652 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoBulkUpdateForm.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoBulkUpdateForm.php
@@ -149,15 +149,21 @@ class PathautoBulkUpdateForm extends FormBase {
public static function batchFinished($success, $results, $operations) {
if ($success) {
if ($results['updates']) {
- drupal_set_message(\Drupal::translation()->formatPlural($results['updates'], 'Generated 1 URL alias.', 'Generated @count URL aliases.'));
+ \Drupal::service('messenger')->addMessage(\Drupal::translation()
+ ->formatPlural($results['updates'], 'Generated 1 URL alias.', 'Generated @count URL aliases.'));
}
else {
- drupal_set_message(t('No new URL aliases to generate.'));
+ \Drupal::service('messenger')
+ ->addMessage(t('No new URL aliases to generate.'));
}
}
else {
$error_operation = reset($operations);
- drupal_set_message(t('An error occurred while processing @operation with arguments : @args', array('@operation' => $error_operation[0], '@args' => print_r($error_operation[0], TRUE))));
+ \Drupal::service('messenger')
+ ->addMessage(t('An error occurred while processing @operation with arguments : @args'), [
+ '@operation' => $error_operation[0],
+ '@args' => print_r($error_operation[0]),
+ ]);
}
}
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoSettingsForm.php b/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoSettingsForm.php
index cbf240798..64a7f6053 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoSettingsForm.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Form/PathautoSettingsForm.php
@@ -35,7 +35,7 @@ class PathautoSettingsForm extends ConfigFormBase {
protected $aliasTypeManager;
/**
- * {@inheritDoc}
+ * {@inheritdoc}
*/
public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, AliasTypeManager $alias_type_manager) {
parent::__construct($config_factory);
@@ -45,7 +45,7 @@ class PathautoSettingsForm extends ConfigFormBase {
}
/**
- * {@inheritDoc}
+ * {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
@@ -195,7 +195,13 @@ class PathautoSettingsForm extends ConfigFormBase {
'#title' => $this->t('Strings to Remove'),
'#default_value' => $config->get('ignore_words'),
'#description' => $this->t('Words to strip out of the URL alias, separated by commas. Do not use this to remove punctuation.'),
- '#wysiwyg' => FALSE,
+ );
+
+ $form['safe_tokens'] = array(
+ '#type' => 'textarea',
+ '#title' => $this->t('Safe tokens'),
+ '#default_value' => implode(', ', $config->get('safe_tokens')),
+ '#description' => $this->t('List of tokens that are safe to use in alias patterns and do not need to be cleaned. For example urls, aliases, machine names. Separated with a comma.'),
);
$form['punctuation'] = array(
@@ -254,6 +260,9 @@ class PathautoSettingsForm extends ConfigFormBase {
}
$value = $enabled_entity_types;
}
+ elseif ($key == 'safe_tokens') {
+ $value = array_filter(array_map('trim', explode(',', $value)));
+ }
$config->set($key, $value);
}
$config->save();
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Form/PatternDisableForm.php b/sites/all/modules/contrib/admin/pathauto/src/Form/PatternDisableForm.php
index c87b88b6a..1e1ac3f9c 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Form/PatternDisableForm.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Form/PatternDisableForm.php
@@ -44,7 +44,9 @@ class PatternDisableForm extends EntityConfirmFormBase {
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->entity->disable()->save();
- drupal_set_message($this->t('Disabled pattern %label.', array('%label' => $this->entity->label())));
+ $this->messenger()->addMessage($this->t('Disabled pattern %label.', [
+ '%label' => $this->entity->label(),
+ ]));
$form_state->setRedirectUrl($this->getCancelUrl());
}
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Form/PatternEditForm.php b/sites/all/modules/contrib/admin/pathauto/src/Form/PatternEditForm.php
index 49efc7e77..454c4a1b1 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Form/PatternEditForm.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Form/PatternEditForm.php
@@ -16,6 +16,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
class PatternEditForm extends EntityForm {
/**
+ * The alias type manager.
+ *
* @var \Drupal\pathauto\AliasTypeManager
*/
protected $manager;
@@ -33,11 +35,15 @@ class PatternEditForm extends EntityForm {
protected $entityTypeBundleInfo;
/**
+ * The entity manager service.
+ *
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
+ * The language manager service.
+ *
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
@@ -58,9 +64,13 @@ class PatternEditForm extends EntityForm {
* PatternEditForm constructor.
*
* @param \Drupal\pathauto\AliasTypeManager $manager
+ * The alias type manager.
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
+ * The entity type bundle info service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+ * The entity manager service.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
+ * The language manager service.
*/
function __construct(AliasTypeManager $manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityTypeManagerInterface $entity_type_manager, LanguageManagerInterface $language_manager) {
$this->manager = $manager;
@@ -70,7 +80,7 @@ class PatternEditForm extends EntityForm {
}
/**
- * {@inheritDoc}
+ * {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
@@ -199,7 +209,7 @@ class PatternEditForm extends EntityForm {
}
/**
- * {@inheritDoc}
+ * {@inheritdoc}
*/
public function buildEntity(array $form, FormStateInterface $form_state) {
/** @var \Drupal\pathauto\PathautoPatternInterface $entity */
@@ -259,11 +269,13 @@ class PatternEditForm extends EntityForm {
}
/**
- * {@inheritDoc}
+ * {@inheritdoc}
*/
public function save(array $form, FormStateInterface $form_state) {
parent::save($form, $form_state);
- drupal_set_message($this->t('Pattern @label saved.', ['@label' => $this->entity->label()]));
+ $this->messenger()->addMessage($this->t('Pattern %label saved.', [
+ '%label' => $this->entity->label(),
+ ]));
$form_state->setRedirectUrl($this->entity->toUrl('collection'));
}
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Form/PatternEnableForm.php b/sites/all/modules/contrib/admin/pathauto/src/Form/PatternEnableForm.php
index 253ca319e..18f136b55 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Form/PatternEnableForm.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Form/PatternEnableForm.php
@@ -44,7 +44,9 @@ class PatternEnableForm extends EntityConfirmFormBase {
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->entity->enable()->save();
- drupal_set_message($this->t('Enabled pattern %label.', array('%label' => $this->entity->label())));
+ $this->messenger()->addMessage($this->t('Enabled pattern %label.', [
+ '%label' => $this->entity->label(),
+ ]));
$form_state->setRedirectUrl($this->getCancelUrl());
}
diff --git a/sites/all/modules/contrib/admin/pathauto/src/PathautoFieldItemList.php b/sites/all/modules/contrib/admin/pathauto/src/PathautoFieldItemList.php
index 8b6b73bd6..300675ca9 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/PathautoFieldItemList.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/PathautoFieldItemList.php
@@ -7,7 +7,7 @@ use Drupal\path\Plugin\Field\FieldType\PathFieldItemList;
class PathautoFieldItemList extends PathFieldItemList {
/**
- * @inheritDoc
+ * @{inheritdoc}
*/
protected function delegateMethod($method) {
// @todo Workaround until this is fixed, see
@@ -27,7 +27,7 @@ class PathautoFieldItemList extends PathFieldItemList {
}
/**
- * @inheritDoc
+ * @{inheritdoc}
*/
protected function computeValue() {
parent::computeValue();
@@ -38,12 +38,4 @@ class PathautoFieldItemList extends PathFieldItemList {
}
}
- /**
- * @inheritDoc
- */
- public function delete() {
- \Drupal::service('pathauto.alias_storage_helper')->deleteEntityPathAll($this->getEntity());
- $this->first()->get('pathauto')->purge();
- }
-
}
diff --git a/sites/all/modules/contrib/admin/pathauto/src/PathautoGenerator.php b/sites/all/modules/contrib/admin/pathauto/src/PathautoGenerator.php
index 6c56a5c34..d70ce3b6f 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/PathautoGenerator.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/PathautoGenerator.php
@@ -2,7 +2,6 @@
namespace Drupal\pathauto;
-use Drupal\Component\Utility\Unicode;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
@@ -87,12 +86,16 @@ class PathautoGenerator implements PathautoGeneratorInterface {
protected $messenger;
/**
+ * The token entity mapper.
+ *
* @var \Drupal\token\TokenEntityMapperInterface
*/
protected $tokenEntityMapper;
/**
- * @var Drupal\Core\Entity\EntityTypeManagerInterface
+ * The entity type manager.
+ *
+ * @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
@@ -115,10 +118,12 @@ class PathautoGenerator implements PathautoGeneratorInterface {
* The messenger service.
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* The string translation service.
- * @param Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
- * The entity type manager
+ * @param \Drupal\token\TokenEntityMapperInterface $token_entity_mapper
+ * The token entity mapper.
+ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+ * The entity type manager.
*/
- public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, Token $token, AliasCleanerInterface $alias_cleaner, AliasStorageHelperInterface $alias_storage_helper, AliasUniquifierInterface $alias_uniquifier, MessengerInterface $messenger, TranslationInterface $string_translation, TokenEntityMapperInterface $token_entity_mappper, EntityTypeManagerInterface $entity_type_manager) {
+ public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, Token $token, AliasCleanerInterface $alias_cleaner, AliasStorageHelperInterface $alias_storage_helper, AliasUniquifierInterface $alias_uniquifier, MessengerInterface $messenger, TranslationInterface $string_translation, TokenEntityMapperInterface $token_entity_mapper, EntityTypeManagerInterface $entity_type_manager) {
$this->configFactory = $config_factory;
$this->moduleHandler = $module_handler;
$this->token = $token;
@@ -127,7 +132,7 @@ class PathautoGenerator implements PathautoGeneratorInterface {
$this->aliasUniquifier = $alias_uniquifier;
$this->messenger = $messenger;
$this->stringTranslation = $string_translation;
- $this->tokenEntityMapper = $token_entity_mappper;
+ $this->tokenEntityMapper = $token_entity_mapper;
$this->entityTypeManager = $entity_type_manager;
}
@@ -165,8 +170,9 @@ class PathautoGenerator implements PathautoGeneratorInterface {
'bundle' => $entity->bundle(),
'language' => &$langcode,
);
- // @todo Is still hook still useful?
+ $pattern_original = $pattern->getPattern();
$this->moduleHandler->alter('pathauto_pattern', $pattern, $context);
+ $pattern_altered = $pattern->getPattern();
// Special handling when updating an item which is already aliased.
$existing_alias = NULL;
@@ -209,7 +215,7 @@ class PathautoGenerator implements PathautoGeneratorInterface {
$this->moduleHandler->alter('pathauto_alias', $alias, $context);
// If we have arrived at an empty string, discontinue.
- if (!Unicode::strlen($alias)) {
+ if (!mb_strlen($alias)) {
return NULL;
}
@@ -236,11 +242,19 @@ class PathautoGenerator implements PathautoGeneratorInterface {
'language' => $langcode,
);
- return $this->aliasStorageHelper->save($path, $existing_alias, $op);
+ $return = $this->aliasStorageHelper->save($path, $existing_alias, $op);
+
+ // Because there is no way to set an altered pattern to not be cached,
+ // change it back to the original value.
+ if ($pattern_altered !== $pattern_original) {
+ $pattern->setPattern($pattern_original);
+ }
+
+ return $return;
}
/**
- * Loads pathauto patterns for a given entity type ID
+ * Loads pathauto patterns for a given entity type ID.
*
* @param string $entity_type_id
* An entity type ID.
@@ -335,7 +349,7 @@ class PathautoGenerator implements PathautoGeneratorInterface {
$result = $this->createEntityAlias($entity, $op);
}
catch (\InvalidArgumentException $e) {
- drupal_set_message($e->getMessage(), 'error');
+ $this->messenger->addError($e->getMessage());
return NULL;
}
diff --git a/sites/all/modules/contrib/admin/pathauto/src/PathautoGeneratorInterface.php b/sites/all/modules/contrib/admin/pathauto/src/PathautoGeneratorInterface.php
index 5880adbc6..337df3c53 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/PathautoGeneratorInterface.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/PathautoGeneratorInterface.php
@@ -49,6 +49,7 @@ interface PathautoGeneratorInterface {
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* An entity.
+ *
* @return \Drupal\pathauto\PathautoPatternInterface|null
*/
public function getPatternByEntity(EntityInterface $entity);
diff --git a/sites/all/modules/contrib/admin/pathauto/src/PathautoItem.php b/sites/all/modules/contrib/admin/pathauto/src/PathautoItem.php
index 422958b21..a7799930e 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/PathautoItem.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/PathautoItem.php
@@ -33,9 +33,6 @@ class PathautoItem extends PathItem {
if ($this->pathauto == PathautoState::SKIP) {
parent::postSave($update);
}
- else {
- \Drupal::service('pathauto.generator')->updateEntityAlias($this->getEntity(), $update ? 'update' : 'insert');
- }
$this->get('pathauto')->persist();
}
diff --git a/sites/all/modules/contrib/admin/pathauto/src/PathautoState.php b/sites/all/modules/contrib/admin/pathauto/src/PathautoState.php
index 466db1c38..4e1f63bc3 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/PathautoState.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/PathautoState.php
@@ -88,6 +88,7 @@ class PathautoState extends TypedData {
/**
* Returns the key value collection that should be used for the given entity.
+ *
* @return string
*/
protected function getCollection() {
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Plugin/Deriver/EntityAliasTypeDeriver.php b/sites/all/modules/contrib/admin/pathauto/src/Plugin/Deriver/EntityAliasTypeDeriver.php
index cf7b4a2fa..c6b03311a 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Plugin/Deriver/EntityAliasTypeDeriver.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Plugin/Deriver/EntityAliasTypeDeriver.php
@@ -26,6 +26,8 @@ class EntityAliasTypeDeriver extends DeriverBase implements ContainerDeriverInte
protected $entityTypeManager;
/**
+ * The entity field manager.
+ *
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
@@ -44,7 +46,7 @@ class EntityAliasTypeDeriver extends DeriverBase implements ContainerDeriverInte
* The entity field manager.
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* The string translation service.
- * @apram \Drupal\Token\TokenEntityMapperInterface $token_entity_mapper
+ * @param \Drupal\Token\TokenEntityMapperInterface $token_entity_mapper
* The token entity mapper.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, TranslationInterface $string_translation, TokenEntityMapperInterface $token_entity_mapper) {
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Plugin/pathauto/AliasType/EntityAliasTypeBase.php b/sites/all/modules/contrib/admin/pathauto/src/Plugin/pathauto/AliasType/EntityAliasTypeBase.php
index c612a2b6d..cdade9424 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Plugin/pathauto/AliasType/EntityAliasTypeBase.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Plugin/pathauto/AliasType/EntityAliasTypeBase.php
@@ -11,6 +11,7 @@ use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\ContextAwarePluginBase;
+use Drupal\Core\Messenger\MessengerTrait;
use Drupal\pathauto\AliasTypeBatchUpdateInterface;
use Drupal\pathauto\AliasTypeInterface;
use Drupal\pathauto\PathautoState;
@@ -26,6 +27,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*/
class EntityAliasTypeBase extends ContextAwarePluginBase implements AliasTypeInterface, AliasTypeBatchUpdateInterface, ContainerFactoryPluginInterface {
+ use MessengerTrait;
+
/**
* The module handler service.
*
@@ -151,12 +154,15 @@ class EntityAliasTypeBase extends ContextAwarePluginBase implements AliasTypeInt
case 'create':
$query->isNull('ua.source');
break;
+
case 'update':
$query->isNotNull('ua.source');
break;
+
case 'all':
// Nothing to do. We want all paths.
break;
+
default:
// Unknown action. Abort!
return;
@@ -182,7 +188,7 @@ class EntityAliasTypeBase extends ContextAwarePluginBase implements AliasTypeInt
$updates = $this->bulkUpdate($ids);
$context['sandbox']['count'] += count($ids);
- $context['sandbox']['current'] = max($ids);
+ $context['sandbox']['current'] = !empty($ids) ? max($ids) : 0;
$context['results']['updates'] += $updates;
$context['message'] = $this->t('Updated alias for %label @id.', array('%label' => $entity_type->getLabel(), '@id' => end($ids)));
@@ -255,7 +261,7 @@ class EntityAliasTypeBase extends ContextAwarePluginBase implements AliasTypeInt
* An optional array of additional options.
*
* @return int
- * The number of updated URL aliases.
+ * The number of updated URL aliases.
*/
protected function bulkUpdate(array $ids, array $options = array()) {
$options += array('message' => FALSE);
@@ -274,7 +280,10 @@ class EntityAliasTypeBase extends ContextAwarePluginBase implements AliasTypeInt
}
if (!empty($options['message'])) {
- drupal_set_message(\Drupal::translation()->formatPlural(count($ids), 'Updated 1 %label URL alias.', 'Updated @count %label URL aliases.'), array('%label' => $this->getLabel()));
+ $this->messenger->addMessage($this->translationManager
+ ->formatPlural(count($ids), 'Updated 1 %label URL alias.', 'Updated @count %label URL aliases.'), [
+ '%label' => $this->getLabel(),
+ ]);
}
return $updates;
@@ -330,5 +339,4 @@ class EntityAliasTypeBase extends ContextAwarePluginBase implements AliasTypeInt
return $this;
}
-
}
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoBulkUpdateTest.php b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoBulkUpdateTest.php
index 2fa2194ab..1db84e9d3 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoBulkUpdateTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoBulkUpdateTest.php
@@ -44,7 +44,7 @@ class PathautoBulkUpdateTest extends WebTestBase {
protected $patterns;
/**
- * {inheritdoc}
+ * {@inheritdoc}
*/
function setUp() {
parent::setUp();
@@ -103,7 +103,7 @@ class PathautoBulkUpdateTest extends WebTestBase {
$this->assertText('No new URL aliases to generate.');
$this->assertNoEntityAliasExists($new_node);
- // Make sure existing aliases can be overriden.
+ // Make sure existing aliases can be overridden.
$this->drupalPostForm('admin/config/search/path/settings', ['update_action' => PathautoGeneratorInterface::UPDATE_ACTION_DELETE], t('Save configuration'));
// Patterns did not change, so no aliases should be regenerated.
@@ -111,16 +111,17 @@ class PathautoBulkUpdateTest extends WebTestBase {
$this->drupalPostForm('admin/config/search/path/update_bulk', $edit, t('Update'));
$this->assertText('No new URL aliases to generate.');
- // Update the node pattern, and leave other patterns alone. Existing nodes should get a new alias,
- // except the node above whose alias is manually set. Other aliases must be left alone.
+ // Update the node pattern, and leave other patterns alone. Existing nodes
+ // should get a new alias, except the node above whose alias is manually
+ // set. Other aliases must be left alone.
$this->patterns['node']->delete();
$this->patterns['node'] = $this->createPattern('node', '/archive/node-[node:nid]');
$this->drupalPostForm('admin/config/search/path/update_bulk', $edit, t('Update'));
$this->assertText('Generated 5 URL aliases.');
- // Prevent existing aliases to be overriden. The bulk generate page should only offer
- // to create an alias for paths which have none.
+ // Prevent existing aliases to be overridden. The bulk generate page should
+ // only offer to create an alias for paths which have none.
$this->drupalPostForm('admin/config/search/path/settings', ['update_action' => PathautoGeneratorInterface::UPDATE_ACTION_NO_NEW], t('Save configuration'));
$this->drupalGet('admin/config/search/path/update_bulk');
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoEnablingEntityTypesTest.php b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoEnablingEntityTypesTest.php
index c8cc1fff9..acaa87be7 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoEnablingEntityTypesTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoEnablingEntityTypesTest.php
@@ -13,6 +13,7 @@ use Drupal\comment\Tests\CommentTestTrait;
class PathautoEnablingEntityTypesTest extends WebTestBase {
use PathautoTestHelperTrait;
+
use CommentTestTrait;
/**
@@ -30,7 +31,7 @@ class PathautoEnablingEntityTypesTest extends WebTestBase {
protected $adminUser;
/**
- * {inheritdoc}
+ * {@inheritdoc}
*/
function setUp() {
parent::setUp();
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoMassDeleteTest.php b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoMassDeleteTest.php
index 93f4ca32d..691e5a89c 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoMassDeleteTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoMassDeleteTest.php
@@ -49,9 +49,8 @@ class PathautoMassDeleteTest extends WebTestBase {
*/
protected $terms;
-
/**
- * {inheritdoc}
+ * {@inheritdoc}
*/
function setUp() {
parent::setUp();
@@ -136,14 +135,16 @@ class PathautoMassDeleteTest extends WebTestBase {
* Helper function to generate aliases.
*/
function generateAliases() {
- // Delete all aliases to avoid duplicated aliases. They will be recreated below.
+ // Delete all aliases to avoid duplicated aliases. They will be recreated
+ // below.
$this->deleteAllAliases();
// We generate a bunch of aliases for nodes, users and taxonomy terms. If
// the entities are already created we just update them, otherwise we create
// them.
if (empty($this->nodes)) {
- // Create a large number of nodes (100+) to make sure that the batch code works.
+ // Create a large number of nodes (100+) to make sure that the batch code
+ // works.
for ($i = 1; $i <= 105; $i++) {
// Set the alias of two nodes manually.
$settings = ($i > 103) ? ['path' => ['alias' => "/custom_alias_$i", 'pathauto' => PathautoState::SKIP]] : [];
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoNodeWebTest.php b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoNodeWebTest.php
index 78213d2bc..a9376f7ac 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoNodeWebTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoNodeWebTest.php
@@ -1,6 +1,7 @@
drupalGet('node/add/page');
$this->assertFieldChecked('edit-path-0-pathauto');
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoSettingsFormWebTest.php b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoSettingsFormWebTest.php
index 40ede78bc..cbcb6b856 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoSettingsFormWebTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoSettingsFormWebTest.php
@@ -85,7 +85,7 @@ class PathautoSettingsFormWebTest extends WebTestBase {
);
/**
- * {inheritdoc}
+ * {@inheritdoc}
*/
function setUp() {
parent::setUp();
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoTaxonomyWebTest.php b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoTaxonomyWebTest.php
index e1a7e88a1..3b92569f7 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoTaxonomyWebTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoTaxonomyWebTest.php
@@ -27,7 +27,7 @@ class PathautoTaxonomyWebTest extends WebTestBase {
protected $adminUser;
/**
- * {inheritdoc}
+ * {@inheritdoc}
*/
function setUp() {
parent::setUp();
@@ -45,7 +45,6 @@ class PathautoTaxonomyWebTest extends WebTestBase {
$this->createPattern('taxonomy_term', '/[term:vocabulary]/[term:name]');
}
-
/**
* Basic functional testing of Pathauto with taxonomy terms.
*/
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoTestHelperTrait.php b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoTestHelperTrait.php
index 5fc6b4070..8c5c97045 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoTestHelperTrait.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoTestHelperTrait.php
@@ -2,7 +2,6 @@
namespace Drupal\pathauto\Tests;
-use Drupal\Component\Utility\Unicode;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Language\Language;
use Drupal\Core\Render\BubbleableMetadata;
@@ -34,7 +33,7 @@ trait PathautoTestHelperTrait {
$type = ($entity_type_id == 'forum') ? 'forum' : 'canonical_entities:' . $entity_type_id;
$pattern = PathautoPattern::create([
- 'id' => Unicode::strtolower($this->randomMachineName()),
+ 'id' => mb_strtolower($this->randomMachineName()),
'type' => $type,
'pattern' => $pattern,
'weight' => $weight,
@@ -51,7 +50,7 @@ trait PathautoTestHelperTrait {
* @param string $entity_type
* The entity type ID.
* @param string $bundle
- * The bundle
+ * The bundle.
*/
protected function addBundleCondition(PathautoPatternInterface $pattern, $entity_type, $bundle) {
$plugin_id = $entity_type == 'node' ? 'node_type' : 'entity_bundle:' . $entity_type;
@@ -142,10 +141,11 @@ trait PathautoTestHelperTrait {
/**
* @param array $values
+ *
* @return \Drupal\taxonomy\VocabularyInterface
*/
public function addVocabulary(array $values = array()) {
- $name = Unicode::strtolower($this->randomMachineName(5));
+ $name = mb_strtolower($this->randomMachineName(5));
$values += array(
'name' => $name,
'vid' => $name,
@@ -158,7 +158,7 @@ trait PathautoTestHelperTrait {
public function addTerm(VocabularyInterface $vocabulary, array $values = array()) {
$values += array(
- 'name' => Unicode::strtolower($this->randomMachineName(5)),
+ 'name' => mb_strtolower($this->randomMachineName(5)),
'vid' => $vocabulary->id(),
);
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoUiTest.php b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoUiTest.php
index 9d461b5f5..b6b9e6643 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoUiTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoUiTest.php
@@ -30,7 +30,7 @@ class PathautoUiTest extends WebTestBase {
protected $adminUser;
/**
- * {inheritdoc}
+ * {@inheritdoc}
*/
function setUp() {
parent::setUp();
diff --git a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoUserWebTest.php b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoUserWebTest.php
index 54832df9d..8d73a3f34 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoUserWebTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/Tests/PathautoUserWebTest.php
@@ -1,7 +1,7 @@
createPattern('user', '/users/[user:name]');
}
-
/**
* Basic functional testing of Pathauto with users.
*/
@@ -71,7 +70,6 @@ class PathautoUserWebTest extends WebTestBase {
$view->initDisplay();
$view->preview('page_1');
-
foreach ($view->result as $key => $row) {
if ($view->field['name']->getValue($row) == $account->getUsername()) {
break;
@@ -85,7 +83,7 @@ class PathautoUserWebTest extends WebTestBase {
$this->drupalPostForm('admin/people', $edit, t('Apply to selected items'));
$this->assertText('Update URL alias was applied to 1 item.');
- $this->assertEntityAlias($account, '/users/' . Unicode::strtolower($account->getUsername()));
+ $this->assertEntityAlias($account, '/users/' . mb_strtolower($account->getUsername()));
$this->assertEntityAlias($this->adminUser, '/user/' . $this->adminUser->id());
}
diff --git a/sites/all/modules/contrib/admin/pathauto/src/VerboseMessenger.php b/sites/all/modules/contrib/admin/pathauto/src/VerboseMessenger.php
index bc60b5c90..a151b9507 100644
--- a/sites/all/modules/contrib/admin/pathauto/src/VerboseMessenger.php
+++ b/sites/all/modules/contrib/admin/pathauto/src/VerboseMessenger.php
@@ -3,6 +3,7 @@
namespace Drupal\pathauto;
use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Messenger\MessengerInterface as CoreMessengerInterface;
use Drupal\Core\Session\AccountInterface;
/**
@@ -32,11 +33,26 @@ class VerboseMessenger implements MessengerInterface {
protected $account;
/**
- * Creates a verbose messenger.
+ * The messenger service.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
*/
- public function __construct(ConfigFactoryInterface $config_factory, AccountInterface $account) {
+ protected $messenger;
+
+ /**
+ * Creates a verbose messenger.
+ *
+ * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+ * The config factory.
+ * @param \Drupal\Core\Session\AccountInterface $account
+ * The current user account.
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger service.
+ */
+ public function __construct(ConfigFactoryInterface $config_factory, AccountInterface $account, CoreMessengerInterface $messenger) {
$this->configFactory = $config_factory;
$this->account = $account;
+ $this->messenger = $messenger;
}
/**
@@ -54,7 +70,7 @@ class VerboseMessenger implements MessengerInterface {
}
if ($message) {
- drupal_set_message($message);
+ $this->messenger->addMessage($message);
}
return TRUE;
diff --git a/sites/all/modules/contrib/admin/pathauto/tests/modules/pathauto_string_id_test/pathauto_string_id_test.info.yml b/sites/all/modules/contrib/admin/pathauto/tests/modules/pathauto_string_id_test/pathauto_string_id_test.info.yml
index cffb456be..c95b45a7d 100644
--- a/sites/all/modules/contrib/admin/pathauto/tests/modules/pathauto_string_id_test/pathauto_string_id_test.info.yml
+++ b/sites/all/modules/contrib/admin/pathauto/tests/modules/pathauto_string_id_test/pathauto_string_id_test.info.yml
@@ -6,8 +6,8 @@ package: Testing
dependencies:
- token
-# Information added by Drupal.org packaging script on 2018-03-03
-version: '8.x-1.1'
+# Information added by Drupal.org packaging script on 2018-09-08
+version: '8.x-1.3'
core: '8.x'
project: 'pathauto'
-datestamp: 1520092688
+datestamp: 1536407890
diff --git a/sites/all/modules/contrib/admin/pathauto/tests/modules/pathauto_views_test/pathauto_views_test.info.yml b/sites/all/modules/contrib/admin/pathauto/tests/modules/pathauto_views_test/pathauto_views_test.info.yml
index 3b8dd0837..c11eb783a 100644
--- a/sites/all/modules/contrib/admin/pathauto/tests/modules/pathauto_views_test/pathauto_views_test.info.yml
+++ b/sites/all/modules/contrib/admin/pathauto/tests/modules/pathauto_views_test/pathauto_views_test.info.yml
@@ -7,8 +7,8 @@ package: Testing
dependencies:
- views
-# Information added by Drupal.org packaging script on 2018-03-03
-version: '8.x-1.1'
+# Information added by Drupal.org packaging script on 2018-09-08
+version: '8.x-1.3'
core: '8.x'
project: 'pathauto'
-datestamp: 1520092688
+datestamp: 1536407890
diff --git a/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoEntityWithStringIdTest.php b/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoEntityWithStringIdTest.php
index f134d6666..e72f42d40 100644
--- a/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoEntityWithStringIdTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoEntityWithStringIdTest.php
@@ -61,7 +61,7 @@ class PathautoEntityWithStringIdTest extends KernelTestBase {
protected function setUp() {
parent::setUp();
$this->installSchema('system', ['key_value']);
- $this->installConfig(['system']);
+ $this->installConfig(['system', 'pathauto']);
$this->installEntitySchema('pathauto_string_id_test');
$this->createPattern('pathauto_string_id_test', '/[pathauto_string_id_test:name]');
/** @var \Drupal\pathauto\AliasTypeManager $alias_type_manager */
@@ -87,7 +87,7 @@ class PathautoEntityWithStringIdTest extends KernelTestBase {
$entity->save();
// Check that the path was generated.
- $this->assertEntityAlias($entity, "/$name");
+ $this->assertEntityAlias($entity, mb_strtolower("/$name"));
// Check that the path auto state was saved with the expected key.
$value = \Drupal::keyValue('pathauto_state.pathauto_string_id_test')->get($expected_key);
$this->assertEquals(PathautoState::CREATE, $value);
diff --git a/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoKernelTest.php b/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoKernelTest.php
index 1d5db68b2..1fffa4d08 100644
--- a/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoKernelTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoKernelTest.php
@@ -3,7 +3,6 @@
namespace Drupal\Tests\pathauto\Kernel;
use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\Unicode;
use Drupal\Core\Language\Language;
use Drupal\Core\Language\LanguageInterface;
use Drupal\language\Entity\ConfigurableLanguage;
@@ -285,7 +284,7 @@ class PathautoKernelTest extends KernelTestBase {
$this->assertEntityAlias($node, '/content/second-title');
$this->assertNoAliasExists(array('alias' => '/content/first-title'));
- // Test PATHAUTO_UPDATE_ACTION_LEAVE
+ // Test PATHAUTO_UPDATE_ACTION_LEAVE.
$config->set('update_action', PathautoGeneratorInterface::UPDATE_ACTION_LEAVE);
$config->save();
$node->setTitle('Third title');
@@ -323,8 +322,8 @@ class PathautoKernelTest extends KernelTestBase {
}
/**
- * Test that \Drupal::service('pathauto.generator')->createEntityAlias() will not create an alias for a pattern
- * that does not get any tokens replaced.
+ * Test that \Drupal::service('pathauto.generator')->createEntityAlias() will
+ * not create an alias for a pattern that does not get any tokens replaced.
*/
public function testNoTokensNoAlias() {
$this->installConfig(['filter']);
@@ -365,12 +364,11 @@ class PathautoKernelTest extends KernelTestBase {
function testParentChildPathTokens() {
// First create a field which will be used to create the path. It must
// begin with a letter.
-
$this->installEntitySchema('taxonomy_term');
Vocabulary::create(['vid' => 'tags'])->save();
- $fieldname = 'a' . Unicode::strtolower($this->randomMachineName());
+ $fieldname = 'a' . mb_strtolower($this->randomMachineName());
$field_storage = FieldStorageConfig::create(['entity_type' => 'taxonomy_term', 'field_name' => $fieldname, 'type' => 'string']);
$field_storage->save();
$field = FieldConfig::create(['field_storage' => $field_storage, 'bundle' => 'tags']);
@@ -391,11 +389,11 @@ class PathautoKernelTest extends KernelTestBase {
// Create the child term.
$child = Term::create(['vid' => 'tags', $fieldname => $this->randomMachineName(), 'parent' => $parent, 'name' => $this->randomMachineName()]);
$child->save();
- $this->assertEntityAlias($child, '/' . Unicode::strtolower($parent->getName() . '/' . $child->$fieldname->value));
+ $this->assertEntityAlias($child, '/' . mb_strtolower($parent->getName() . '/' . $child->$fieldname->value));
// Re-saving the parent term should not modify the child term's alias.
$parent->save();
- $this->assertEntityAlias($child, '/' . Unicode::strtolower($parent->getName() . '/' . $child->$fieldname->value));
+ $this->assertEntityAlias($child, '/' . mb_strtolower($parent->getName() . '/' . $child->$fieldname->value));
}
/**
@@ -506,7 +504,7 @@ class PathautoKernelTest extends KernelTestBase {
}
/**
- * Tests that enabled entity types genrates the necessary fields and plugins.
+ * Tests that enabled entity types generates the necessary fields and plugins.
*/
public function testSettingChangeInvalidatesCache() {
diff --git a/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoTokenTest.php b/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoTokenTest.php
index 30c5ad1d2..1a05007f6 100644
--- a/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoTokenTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/tests/src/Kernel/PathautoTokenTest.php
@@ -39,6 +39,42 @@ class PathautoTokenTest extends KernelTestBase {
$alias_cleaner = \Drupal::service('pathauto.alias_cleaner');
$alias_cleaner->cleanTokenValues($replacements, $data, array());
$this->assertEqual($replacements['[array:join-path]'], 'test-first-arg/array-value');
+
+ // Test additional token cleaning and its configuration.
+ $safe_tokens = $this->config('pathauto.settings')->get('safe_tokens');
+ $safe_tokens[] = 'safe';
+ $this->config('pathauto.settings')
+ ->set('safe_tokens', $safe_tokens)
+ ->save();
+
+ $safe_tokens = [
+ '[example:path]',
+ '[example:url]',
+ '[example:url-brief]',
+ '[example:login-url]',
+ '[example:login-url:relative]',
+ '[example:url:relative]',
+ '[example:safe]',
+ ];
+ $unsafe_tokens = [
+ '[example:path_part]',
+ '[example:something_url]',
+ '[example:unsafe]',
+ ];
+ foreach ($safe_tokens as $token) {
+ $replacements = [
+ $token => 'this/is/a/path',
+ ];
+ $alias_cleaner->cleanTokenValues($replacements);
+ $this->assertEquals('this/is/a/path', $replacements[$token], "Token $token cleaned.");
+ }
+ foreach ($unsafe_tokens as $token) {
+ $replacements = [
+ $token => 'This is not a / path',
+ ];
+ $alias_cleaner->cleanTokenValues($replacements);
+ $this->assertEquals('not-path', $replacements[$token], "Token $token not cleaned.");
+ }
}
/**
diff --git a/sites/all/modules/contrib/admin/pathauto/tests/src/Unit/VerboseMessengerTest.php b/sites/all/modules/contrib/admin/pathauto/tests/src/Unit/VerboseMessengerTest.php
index 9567dd54b..13c5c058e 100644
--- a/sites/all/modules/contrib/admin/pathauto/tests/src/Unit/VerboseMessengerTest.php
+++ b/sites/all/modules/contrib/admin/pathauto/tests/src/Unit/VerboseMessengerTest.php
@@ -1,59 +1,54 @@
getConfigFactoryStub(['pathauto.settings' => ['verbose' => TRUE]]);
+ $account = $this->createMock(AccountInterface::class);
+ $account->expects($this->once())
+ ->method('hasPermission')
+ ->withAnyParameters()
+ ->willReturn(TRUE);
+ $messenger = $this->createMock(MessengerInterface::class);
- /**
- * {@inheritdoc}
- */
- protected function setUp() {
- $config_factory = $this->getConfigFactoryStub(array('pathauto.settings' => array('verbose' => TRUE)));
- $account = $this->getMock('\Drupal\Core\Session\AccountInterface');
- $account->expects($this->once())
- ->method('hasPermission')
- ->withAnyParameters()
- ->willReturn(TRUE);
-
- $this->messenger = new VerboseMessenger($config_factory, $account);
- }
-
- /**
- * Tests add messages.
- * @covers ::addMessage
- */
- public function testAddMessage() {
- $this->assertTrue($this->messenger->addMessage("Test message"), "The message was added");
- }
-
- /**
- * @covers ::addMessage
- */
- public function testDoNotAddMessageWhileBulkupdate() {
- $this->assertFalse($this->messenger->addMessage("Test message", "bulkupdate"), "The message was NOT added");
- }
-
-}
-
-}
-namespace {
- // @todo Delete after https://drupal.org/node/1858196 is in.
- if (!function_exists('drupal_set_message')) {
- function drupal_set_message() {
- }
+ $this->messenger = new VerboseMessenger($config_factory, $account, $messenger);
}
+
+ /**
+ * Tests add messages.
+ *
+ * @covers ::addMessage
+ */
+ public function testAddMessage() {
+ $this->assertTrue($this->messenger->addMessage("Test message"), "The message was added");
+ }
+
+ /**
+ * @covers ::addMessage
+ */
+ public function testDoNotAddMessageWhileBulkupdate() {
+ $this->assertFalse($this->messenger->addMessage("Test message", "bulkupdate"), "The message was NOT added");
+ }
+
}
diff --git a/sites/all/modules/contrib/admin/redirect/config/install/system.action.redirect_delete_action.yml b/sites/all/modules/contrib/admin/redirect/config/install/system.action.redirect_delete_action.yml
index dccf94ced..4b23fc81b 100644
--- a/sites/all/modules/contrib/admin/redirect/config/install/system.action.redirect_delete_action.yml
+++ b/sites/all/modules/contrib/admin/redirect/config/install/system.action.redirect_delete_action.yml
@@ -4,6 +4,8 @@ dependencies:
enforced:
module:
- redirect
+ module:
+ - redirect
id: redirect_delete_action
label: 'Delete redirect'
type: redirect
diff --git a/sites/all/modules/contrib/admin/redirect/config/install/views.view.redirect.yml b/sites/all/modules/contrib/admin/redirect/config/install/views.view.redirect.yml
index 8a2829af6..42555ccc3 100644
--- a/sites/all/modules/contrib/admin/redirect/config/install/views.view.redirect.yml
+++ b/sites/all/modules/contrib/admin/redirect/config/install/views.view.redirect.yml
@@ -575,6 +575,8 @@ display:
- url.query_args
- user.permissions
cacheable: false
+ max-age: 0
+ tags: { }
page_1:
display_plugin: page
id: page_1
@@ -591,3 +593,5 @@ display:
- url.query_args
- user.permissions
cacheable: false
+ max-age: 0
+ tags: { }
diff --git a/sites/all/modules/contrib/admin/redirect/config/optional/language.content_settings.redirect.redirect.yml b/sites/all/modules/contrib/admin/redirect/config/optional/language.content_settings.redirect.redirect.yml
index ce3bd07d2..e6dfad3fd 100644
--- a/sites/all/modules/contrib/admin/redirect/config/optional/language.content_settings.redirect.redirect.yml
+++ b/sites/all/modules/contrib/admin/redirect/config/optional/language.content_settings.redirect.redirect.yml
@@ -1,5 +1,8 @@
+langcode: en
status: true
-dependencies: { }
+dependencies:
+ module:
+ - redirect
id: redirect.redirect
target_entity_type_id: redirect
target_bundle: redirect
diff --git a/sites/all/modules/contrib/admin/redirect/modules/redirect_404/redirect_404.info.yml b/sites/all/modules/contrib/admin/redirect/modules/redirect_404/redirect_404.info.yml
index 96819d27b..b1b96997b 100644
--- a/sites/all/modules/contrib/admin/redirect/modules/redirect_404/redirect_404.info.yml
+++ b/sites/all/modules/contrib/admin/redirect/modules/redirect_404/redirect_404.info.yml
@@ -7,8 +7,8 @@ dependencies:
- redirect
- views
-# Information added by Drupal.org packaging script on 2018-03-12
-version: '8.x-1.1'
+# Information added by Drupal.org packaging script on 2018-05-04
+version: '8.x-1.2'
core: '8.x'
project: 'redirect'
-datestamp: 1520897884
+datestamp: 1525419807
diff --git a/sites/all/modules/contrib/admin/redirect/modules/redirect_domain/redirect_domain.info.yml b/sites/all/modules/contrib/admin/redirect/modules/redirect_domain/redirect_domain.info.yml
index 31153f01c..a9c7ce006 100644
--- a/sites/all/modules/contrib/admin/redirect/modules/redirect_domain/redirect_domain.info.yml
+++ b/sites/all/modules/contrib/admin/redirect/modules/redirect_domain/redirect_domain.info.yml
@@ -6,8 +6,8 @@ description: 'Allows users to redirect between domains.'
dependencies:
- redirect
-# Information added by Drupal.org packaging script on 2018-03-12
-version: '8.x-1.1'
+# Information added by Drupal.org packaging script on 2018-05-04
+version: '8.x-1.2'
core: '8.x'
project: 'redirect'
-datestamp: 1520897884
+datestamp: 1525419807
diff --git a/sites/all/modules/contrib/admin/redirect/redirect.info.yml b/sites/all/modules/contrib/admin/redirect/redirect.info.yml
index b5f4921cd..3472dab6e 100644
--- a/sites/all/modules/contrib/admin/redirect/redirect.info.yml
+++ b/sites/all/modules/contrib/admin/redirect/redirect.info.yml
@@ -8,8 +8,8 @@ dependencies:
- drupal:link
- drupal:views
-# Information added by Drupal.org packaging script on 2018-03-12
-version: '8.x-1.1'
+# Information added by Drupal.org packaging script on 2018-05-04
+version: '8.x-1.2'
core: '8.x'
project: 'redirect'
-datestamp: 1520897884
+datestamp: 1525419807
diff --git a/sites/all/modules/contrib/admin/redirect/redirect.module b/sites/all/modules/contrib/admin/redirect/redirect.module
index f7a241b92..bf4d4f902 100644
--- a/sites/all/modules/contrib/admin/redirect/redirect.module
+++ b/sites/all/modules/contrib/admin/redirect/redirect.module
@@ -22,6 +22,7 @@ use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\Core\Site\Settings;
use Drupal\redirect\Entity\Redirect;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
/**
* Implements hook_hook_info().
@@ -79,9 +80,15 @@ function redirect_help($route_name, RouteMatchInterface $route_match) {
* Will delete redirects based on the entity URL.
*/
function redirect_entity_delete(EntityInterface $entity) {
- if ($entity->getEntityType()->hasLinkTemplate('canonical')) {
- redirect_delete_by_path('internal:/' . $entity->toUrl('canonical')->getInternalPath());
- redirect_delete_by_path('entity:' . $entity->getEntityTypeId() . '/' . $entity->id());
+ try {
+ if ($entity->getEntityType()->hasLinkTemplate('canonical') && $entity->toUrl('canonical')->isRouted()) {
+ redirect_delete_by_path('internal:/' . $entity->toUrl('canonical')->getInternalPath());
+ redirect_delete_by_path('entity:' . $entity->getEntityTypeId() . '/' . $entity->id());
+ }
+ }
+ catch (RouteNotFoundException $e) {
+ // This can happen if a module incorrectly defines a link template, ignore
+ // such errors.
}
}
diff --git a/sites/all/modules/contrib/admin/redirect/src/EventSubscriber/RouteNormalizerRequestSubscriber.php b/sites/all/modules/contrib/admin/redirect/src/EventSubscriber/RouteNormalizerRequestSubscriber.php
index b8eae4df0..800e022a5 100644
--- a/sites/all/modules/contrib/admin/redirect/src/EventSubscriber/RouteNormalizerRequestSubscriber.php
+++ b/sites/all/modules/contrib/admin/redirect/src/EventSubscriber/RouteNormalizerRequestSubscriber.php
@@ -128,12 +128,6 @@ class RouteNormalizerRequestSubscriber implements EventSubscriberInterface {
$response = new TrustedRedirectResponse($redirect_uri, $this->config->get('default_status_code'));
$response->headers->set('X-Drupal-Route-Normalizer', 1);
$event->setResponse($response);
- // Disable page cache for redirects as that results in unpredictable
- // behavior, e.g. when a trailing ? without query parameters is
- // involved.
- // @todo Remove when https://www.drupal.org/node/2761639 is fixed in
- // Drupal core.
- \Drupal::service('page_cache_kill_switch')->trigger();
}
}
}
diff --git a/sites/all/modules/contrib/admin/redirect/src/Plugin/migrate/source/PathRedirect.php b/sites/all/modules/contrib/admin/redirect/src/Plugin/migrate/source/PathRedirect.php
index 973b3a79d..3ffd4b64e 100644
--- a/sites/all/modules/contrib/admin/redirect/src/Plugin/migrate/source/PathRedirect.php
+++ b/sites/all/modules/contrib/admin/redirect/src/Plugin/migrate/source/PathRedirect.php
@@ -9,7 +9,7 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
*
* @MigrateSource(
* id = "d6_path_redirect",
- * source_module = "redirect"
+ * source_module = "path_redirect"
* )
*/
class PathRedirect extends DrupalSqlBase {
diff --git a/sites/all/modules/contrib/admin/redirect/tests/fixtures/drupal6.php b/sites/all/modules/contrib/admin/redirect/tests/fixtures/drupal6.php
index fa474aae9..e6f9c4758 100644
--- a/sites/all/modules/contrib/admin/redirect/tests/fixtures/drupal6.php
+++ b/sites/all/modules/contrib/admin/redirect/tests/fixtures/drupal6.php
@@ -173,15 +173,14 @@ $connection->insert('system')
'info',
))
->values(array(
- 'filename' => 'modules/contrib/redirect/redirect.module',
- 'name' => 'redirect',
+ 'filename' => 'modules/contrib/path_redirect/path_redirect.module',
+ 'name' => 'path_redirect',
'type' => 'module',
'owner' => '',
'status' => '1',
'bootstrap' => '0',
'schema_version' => '7000',
'weight' => '0',
- 'info' => 'a:10:{s:4:"name";s:8:"Redirect";s:11:"description";s:51:"Allows users to redirect from old URLs to new URLs.";s:7:"package";s:5:"Other";s:7:"version";s:3:"6.0";s:4:"core";s:3:"6.x";s:7:"project";s:8:"redirect";s:9:"datestamp";s:10:"1347989995";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}',
+ 'info' => 'a:10:{s:4:"name";s:13:"Path Redirect";s:11:"description";s:51:"Allows users to redirect from old URLs to new URLs.";s:7:"package";s:5:"Other";s:7:"version";s:3:"6.0";s:4:"core";s:3:"6.x";s:7:"project";s:13:"path_redirect";s:9:"datestamp";s:10:"1347989995";s:12:"dependencies";a:0:{}s:10:"dependents";a:0:{}s:3:"php";s:5:"4.3.5";}',
))
->execute();
-
diff --git a/sites/all/modules/contrib/dev/entity/entity.info.yml b/sites/all/modules/contrib/dev/entity/entity.info.yml
index e5aab28c3..972bfe4c0 100644
--- a/sites/all/modules/contrib/dev/entity/entity.info.yml
+++ b/sites/all/modules/contrib/dev/entity/entity.info.yml
@@ -5,8 +5,8 @@ type: module
dependencies:
- drupal:system (>=8.5.0)
-# Information added by Drupal.org packaging script on 2018-03-12
-version: '8.x-1.0-beta2'
+# Information added by Drupal.org packaging script on 2018-06-08
+version: '8.x-1.0-beta4'
core: '8.x'
project: 'entity'
-datestamp: 1520873296
+datestamp: 1528452194
diff --git a/sites/all/modules/contrib/dev/entity/src/Access/EntityRevisionRouteAccessChecker.php b/sites/all/modules/contrib/dev/entity/src/Access/EntityRevisionRouteAccessChecker.php
index 84f431707..4e1573c2a 100644
--- a/sites/all/modules/contrib/dev/entity/src/Access/EntityRevisionRouteAccessChecker.php
+++ b/sites/all/modules/contrib/dev/entity/src/Access/EntityRevisionRouteAccessChecker.php
@@ -69,6 +69,20 @@ class EntityRevisionRouteAccessChecker implements AccessInterface {
}
}
+ /**
+ * Performs access checks.
+ *
+ * @param \Drupal\Core\Entity\ContentEntityInterface $entity
+ * The entity for which to check access.
+ * @param \Drupal\Core\Session\AccountInterface $account
+ * The user for which to check access.
+ * @param string $operation
+ * The entity operation. Usually one of 'view', 'view label', 'update' or
+ * 'delete'.
+ *
+ * @return bool
+ * The access result.
+ */
protected function checkAccess(ContentEntityInterface $entity, AccountInterface $account, $operation = 'view') {
$entity_type = $entity->getEntityType();
$entity_type_id = $entity->getEntityTypeId();
@@ -126,7 +140,6 @@ class EntityRevisionRouteAccessChecker implements AccessInterface {
return $this->accessCache[$cid];
}
-
/**
* Counts the number of revisions in the default language.
*
diff --git a/sites/all/modules/contrib/dev/entity/src/BundleEntityAccessControlHandler.php b/sites/all/modules/contrib/dev/entity/src/BundleEntityAccessControlHandler.php
new file mode 100644
index 000000000..be9bba591
--- /dev/null
+++ b/sites/all/modules/contrib/dev/entity/src/BundleEntityAccessControlHandler.php
@@ -0,0 +1,49 @@
+id();
+ $entity_type_id = $this->entityType->getBundleOf();
+ $permissions = [
+ "administer $entity_type_id",
+ // View permissions provided by EntityPermissionProvider.
+ "view $entity_type_id",
+ "view $bundle $entity_type_id",
+ // View permissions provided by UncacheableEntityPermissionProvider.
+ "view own $entity_type_id",
+ "view any $entity_type_id",
+ "view own $bundle $entity_type_id",
+ "view any $bundle $entity_type_id",
+ ];
+
+ return AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
+ }
+ else {
+ return parent::checkAccess($entity, $operation, $account);
+ }
+ }
+
+}
diff --git a/sites/all/modules/contrib/dev/entity/src/BundlePlugin/BundlePluginUninstallValidator.php b/sites/all/modules/contrib/dev/entity/src/BundlePlugin/BundlePluginUninstallValidator.php
index 09531df84..c21f625ac 100644
--- a/sites/all/modules/contrib/dev/entity/src/BundlePlugin/BundlePluginUninstallValidator.php
+++ b/sites/all/modules/contrib/dev/entity/src/BundlePlugin/BundlePluginUninstallValidator.php
@@ -60,7 +60,7 @@ class BundlePluginUninstallValidator implements ModuleUninstallValidatorInterfac
});
$bundles_with_content = array_intersect_key($bundles_filtered_by_module, array_flip($bundle_keys_with_content));
-
+
foreach ($bundles_with_content as $bundle) {
$reasons[] = $this->t('There is data for the bundle @bundle on the entity type @entity_type. Please remove all content before uninstalling the module.', [
'@bundle' => $bundle['label'],
diff --git a/sites/all/modules/contrib/dev/entity/src/Entity/RevisionableEntityBundleInterface.php b/sites/all/modules/contrib/dev/entity/src/Entity/RevisionableEntityBundleInterface.php
new file mode 100644
index 000000000..18d392a06
--- /dev/null
+++ b/sites/all/modules/contrib/dev/entity/src/Entity/RevisionableEntityBundleInterface.php
@@ -0,0 +1,14 @@
+hasHandlerClass('permission_provider') || !is_a($entity_type->getHandlerClass('permission_provider'), EntityPermissionProvider::class, TRUE)) {
- throw new \Exception("This entity access control handler requires the entity permissions provider: {EntityPermissionProvider::class}");
+ throw new \Exception('\Drupal\entity\EntityAccessControlHandler requires the \Drupal\entity\EntityPermissionProvider permission provider.');
}
}
-
/**
* {@inheritdoc}
*/
- protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
- $account = $this->prepareUser($account);
- /** @var \Drupal\Core\Access\AccessResult $result */
- $result = parent::checkAccess($entity, $operation, $account);
-
- if ($result->isNeutral()) {
- if ($entity instanceof EntityOwnerInterface) {
- $result = $this->checkEntityOwnerPermissions($entity, $operation, $account);
- }
- else {
- $result = $this->checkEntityPermissions($entity, $operation, $account);
- }
- }
-
- // Ensure that access is evaluated again when the entity changes.
- return $result->addCacheableDependency($entity);
- }
-
- /**
- * Checks the entity operation and bundle permissions.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity for which to check access.
- * @param string $operation
- * The entity operation. Usually one of 'view', 'view label', 'update' or
- * 'delete'.
- * @param \Drupal\Core\Session\AccountInterface $account
- * The user for which to check access.
- *
- * @return \Drupal\Core\Access\AccessResultInterface
- * The access result.
- */
- protected function checkEntityPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
- if ($operation === 'view') {
- $permissions = [
- "view {$entity->getEntityTypeId()}"
- ];
- }
- else {
- $permissions = [
- "$operation {$entity->getEntityTypeId()}",
- "$operation {$entity->bundle()} {$entity->getEntityTypeId()}",
- ];
- }
- return AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
- }
-
- /**
- * Checks the entity operation and bundle permissions, with owners.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity for which to check access.
- * @param string $operation
- * The entity operation. Usually one of 'view', 'view label', 'update' or
- * 'delete'.
- * @param \Drupal\Core\Session\AccountInterface $account
- * The user for which to check access.
- *
- * @return \Drupal\Core\Access\AccessResultInterface
- * The access result.
- */
protected function checkEntityOwnerPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
+ /** @var \Drupal\user\EntityOwnerInterface $entity */
if ($operation === 'view') {
if ($entity instanceof EntityPublishedInterface && !$entity->isPublished()) {
- if (($account->id() == $entity->getOwnerId())) {
- $permissions = [
- "view own unpublished {$entity->getEntityTypeId()}",
- ];
- return AccessResult::allowedIfHasPermissions($account, $permissions)->cachePerUser();
+ if ($account->id() != $entity->getOwnerId()) {
+ // There's no permission for viewing other user's unpublished entity.
+ return AccessResult::neutral()->cachePerUser();
}
- return AccessResult::neutral()->cachePerUser();
+
+ $permissions = [
+ "view own unpublished {$entity->getEntityTypeId()}",
+ ];
+ $result = AccessResult::allowedIfHasPermissions($account, $permissions)->cachePerUser();
}
else {
- return AccessResult::allowedIfHasPermissions($account, [
+ $result = AccessResult::allowedIfHasPermissions($account, [
"view {$entity->getEntityTypeId()}",
- ]);
+ "view {$entity->bundle()} {$entity->getEntityTypeId()}",
+ ], 'OR');
}
}
else {
- if (($account->id() == $entity->getOwnerId())) {
- $result = AccessResult::allowedIfHasPermissions($account, [
- "$operation own {$entity->getEntityTypeId()}",
- "$operation any {$entity->getEntityTypeId()}",
- "$operation own {$entity->bundle()} {$entity->getEntityTypeId()}",
- "$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
- ], 'OR');
- }
- else {
- $result = AccessResult::allowedIfHasPermissions($account, [
- "$operation any {$entity->getEntityTypeId()}",
- "$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
- ], 'OR');
- }
- return $result;
- }
- }
-
- /**
- * {@inheritdoc}
- */
- protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
- $result = parent::checkCreateAccess($account, $context, $entity_bundle);
- if ($result->isNeutral()) {
- $permissions = [
- 'administer ' . $this->entityTypeId,
- 'create ' . $this->entityTypeId,
- ];
- if ($entity_bundle) {
- $permissions[] = 'create ' . $entity_bundle . ' ' . $this->entityTypeId;
- }
-
- $result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
+ $result = parent::checkEntityOwnerPermissions($entity, $operation, $account);
}
return $result;
diff --git a/sites/all/modules/contrib/dev/entity/src/EntityAccessControlHandlerBase.php b/sites/all/modules/contrib/dev/entity/src/EntityAccessControlHandlerBase.php
new file mode 100644
index 000000000..c0a63c7cb
--- /dev/null
+++ b/sites/all/modules/contrib/dev/entity/src/EntityAccessControlHandlerBase.php
@@ -0,0 +1,115 @@
+prepareUser($account);
+ /** @var \Drupal\Core\Access\AccessResult $result */
+ $result = parent::checkAccess($entity, $operation, $account);
+
+ if ($result->isNeutral()) {
+ if ($entity instanceof EntityOwnerInterface) {
+ $result = $this->checkEntityOwnerPermissions($entity, $operation, $account);
+ }
+ else {
+ $result = $this->checkEntityPermissions($entity, $operation, $account);
+ }
+ }
+
+ // Ensure that access is evaluated again when the entity changes.
+ return $result->addCacheableDependency($entity);
+ }
+
+ /**
+ * Checks the entity operation and bundle permissions.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ * The entity for which to check access.
+ * @param string $operation
+ * The entity operation. Usually one of 'view', 'view label', 'update' or
+ * 'delete'.
+ * @param \Drupal\Core\Session\AccountInterface $account
+ * The user for which to check access.
+ *
+ * @return \Drupal\Core\Access\AccessResultInterface
+ * The access result.
+ */
+ protected function checkEntityPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
+ $permissions = [
+ "$operation {$entity->getEntityTypeId()}",
+ "$operation {$entity->bundle()} {$entity->getEntityTypeId()}",
+ ];
+
+ return AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
+ }
+
+ /**
+ * Checks the entity operation and bundle permissions, with owners.
+ *
+ * @param \Drupal\Core\Entity\EntityInterface $entity
+ * The entity for which to check access.
+ * @param string $operation
+ * The entity operation. Usually one of 'view', 'view label', 'update' or
+ * 'delete'.
+ * @param \Drupal\Core\Session\AccountInterface $account
+ * The user for which to check access.
+ *
+ * @return \Drupal\Core\Access\AccessResultInterface
+ * The access result.
+ */
+ protected function checkEntityOwnerPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
+ /** @var \Drupal\user\EntityOwnerInterface $entity */
+ if ($account->id() == $entity->getOwnerId()) {
+ $permissions = [
+ "$operation own {$entity->getEntityTypeId()}",
+ "$operation any {$entity->getEntityTypeId()}",
+ "$operation own {$entity->bundle()} {$entity->getEntityTypeId()}",
+ "$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
+ ];
+ }
+ else {
+ $permissions = [
+ "$operation any {$entity->getEntityTypeId()}",
+ "$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
+ ];
+ }
+ $result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR')->cachePerUser();
+
+ return $result;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+ $result = parent::checkCreateAccess($account, $context, $entity_bundle);
+ if ($result->isNeutral()) {
+ $permissions = [
+ 'administer ' . $this->entityTypeId,
+ 'create ' . $this->entityTypeId,
+ ];
+ if ($entity_bundle) {
+ $permissions[] = 'create ' . $entity_bundle . ' ' . $this->entityTypeId;
+ }
+
+ $result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
+ }
+
+ return $result;
+ }
+
+}
diff --git a/sites/all/modules/contrib/dev/entity/src/EntityPermissionProvider.php b/sites/all/modules/contrib/dev/entity/src/EntityPermissionProvider.php
index 88c06ee10..d583db337 100644
--- a/sites/all/modules/contrib/dev/entity/src/EntityPermissionProvider.php
+++ b/sites/all/modules/contrib/dev/entity/src/EntityPermissionProvider.php
@@ -5,24 +5,25 @@ namespace Drupal\entity;
use Drupal\Core\Entity\EntityTypeInterface;
/**
- * Provides generic entity permissions which are still cacheable.
+ * Provides generic entity permissions.
*
- * This includes:
+ * Intended for content entity types, since config entity types usually rely
+ * on a single "administer" permission.
*
+ * Provided permissions:
* - administer $entity_type
* - access $entity_type overview
- * - view $entity_type
+ * - view ($bundle) $entity_type
* - view own unpublished $entity_type
* - update (own|any) ($bundle) $entity_type
* - delete (own|any) ($bundle) $entity_type
* - create $bundle $entity_type
*
- * This class does not support "view own ($bundle) $entity_type", because this
- * results in caching per user. If you need this use case, please use
- * \Drupal\entity\UncacheableEntityPermissionProvider instead.
+ * Does not provide "view own ($bundle) $entity_type" permissions, because
+ * they require caching pages per user. Please use
+ * \Drupal\entity\UncacheableEntityPermissionProvider if those permissions
+ * are necessary.
*
- * Intended for content entity types, since config entity types usually rely
- * on a single "administer" permission.
* Example annotation:
* @code
* handlers = {
@@ -37,23 +38,58 @@ use Drupal\Core\Entity\EntityTypeInterface;
class EntityPermissionProvider extends EntityPermissionProviderBase {
/**
- * {@inheritdoc}
+ * Builds permissions for the entity_type granularity.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type.
+ *
+ * @return array
+ * The permissions.
*/
- public function buildPermissions(EntityTypeInterface $entity_type) {
+ protected function buildEntityTypePermissions(EntityTypeInterface $entity_type) {
+ $permissions = parent::buildEntityTypePermissions($entity_type);
$entity_type_id = $entity_type->id();
$plural_label = $entity_type->getPluralLabel();
- $permissions = parent::buildPermissions($entity_type);
-
- // View permissions are the same for both granularities.
$permissions["view {$entity_type_id}"] = [
'title' => $this->t('View @type', [
'@type' => $plural_label,
]),
];
- return $this->processPermissions($permissions, $entity_type);
+ return $permissions;
}
+ /**
+ * Builds permissions for the bundle granularity.
+ *
+ * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+ * The entity type.
+ *
+ * @return array
+ * The permissions.
+ */
+ protected function buildBundlePermissions(EntityTypeInterface $entity_type) {
+ $permissions = parent::buildBundlePermissions($entity_type);
+ $entity_type_id = $entity_type->id();
+ $bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id);
+ $plural_label = $entity_type->getPluralLabel();
+
+ $permissions["view {$entity_type_id}"] = [
+ 'title' => $this->t('View @type', [
+ '@type' => $plural_label,
+ ]),
+ ];
+ foreach ($bundles as $bundle_name => $bundle_info) {
+ $permissions["view {$bundle_name} {$entity_type_id}"] = [
+ 'title' => $this->t('@bundle: View @type', [
+ '@bundle' => $bundle_info['label'],
+ '@type' => $plural_label,
+ ]),
+ ];
+ }
+
+ return $permissions;
+ }
}
diff --git a/sites/all/modules/contrib/dev/entity/src/EntityPermissionProviderBase.php b/sites/all/modules/contrib/dev/entity/src/EntityPermissionProviderBase.php
index 53d83f8ac..c48e45634 100644
--- a/sites/all/modules/contrib/dev/entity/src/EntityPermissionProviderBase.php
+++ b/sites/all/modules/contrib/dev/entity/src/EntityPermissionProviderBase.php
@@ -56,9 +56,11 @@ class EntityPermissionProviderBase implements EntityPermissionProviderInterface,
'title' => $this->t('Administer @type', ['@type' => $plural_label]),
'restrict access' => TRUE,
];
- $permissions["access {$entity_type_id} overview"] = [
- 'title' => $this->t('Access the @type overview page', ['@type' => $plural_label]),
- ];
+ if ($entity_type->hasLinkTemplate('collection')) {
+ $permissions["access {$entity_type_id} overview"] = [
+ 'title' => $this->t('Access the @type overview page', ['@type' => $plural_label]),
+ ];
+ }
if ($has_owner && $entity_type->entityClassImplements(EntityPublishedInterface::class)) {
$permissions["view own unpublished {$entity_type_id}"] = [
'title' => $this->t('View own unpublished @type', [
@@ -82,7 +84,7 @@ class EntityPermissionProviderBase implements EntityPermissionProviderInterface,
* Adds the provider and converts the titles to strings to allow sorting.
*
* @param array $permissions
- * The array of permissions
+ * The array of permissions.
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type.
*
diff --git a/sites/all/modules/contrib/dev/entity/src/EntityViewBuilder.php b/sites/all/modules/contrib/dev/entity/src/EntityViewBuilder.php
new file mode 100644
index 000000000..1efe0ebe6
--- /dev/null
+++ b/sites/all/modules/contrib/dev/entity/src/EntityViewBuilder.php
@@ -0,0 +1,17 @@
+getBundleEntity();
+
+ // Set up default values, if required.
+ if (!$this->entity->isNew()) {
+ $this->entity->setRevisionLogMessage(NULL);
+ }
+
+ if ($bundle_entity instanceof RevisionableEntityBundleInterface) {
+ // Always use the default revision setting.
+ $this->entity->setNewRevision($bundle_entity && $bundle_entity->shouldCreateNewRevision());
+ }
+ }
+
+ /**
+ * Gets the bundle entity of the current entity.
+ *
+ * @return \Drupal\Core\Entity\EntityInterface|null
+ * The bundle entity, or NULL if there is none.
+ */
+ protected function getBundleEntity() {
+ if ($bundle_key = $this->entity->getEntityType()->getKey('bundle')) {
+ return $this->entity->{$bundle_key}->referencedEntities()[0];
+ }
+ return NULL;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function form(array $form, FormStateInterface $form_state) {
+ $entity_type = $this->entity->getEntityType();
+ $bundle_entity = $this->getBundleEntity();
+ $account = $this->currentUser();
+
+ if ($this->operation == 'edit') {
+ $form['#title'] = $this->t('Edit %bundle_label @label', [
+ '%bundle_label' => $bundle_entity ? $bundle_entity->label() : '',
+ '@label' => $this->entity->label(),
+ ]);
+ }
+
+ $form['advanced'] = [
+ '#type' => 'vertical_tabs',
+ '#weight' => 99,
+ ];
+
+ // Add a log field if the "Create new revision" option is checked, or if the
+ // current user has the ability to check that option.
+ // @todo Could we autogenerate this form by using some widget on the
+ // revision info field.
+ $form['revision_information'] = [
+ '#type' => 'details',
+ '#title' => $this->t('Revision information'),
+ // Open by default when "Create new revision" is checked.
+ '#open' => $this->entity->isNewRevision(),
+ '#group' => 'advanced',
+ '#weight' => 20,
+ '#access' => $this->entity->isNewRevision() || $account->hasPermission($entity_type->get('admin_permission')),
+ ];
+
+ $form['revision_information']['revision'] = [
+ '#type' => 'checkbox',
+ '#title' => $this->t('Create new revision'),
+ '#default_value' => $this->entity->isNewRevision(),
+ '#access' => $account->hasPermission($entity_type->get('admin_permission')),
+ ];
+
+ // Check the revision log checkbox when the log textarea is filled in.
+ // This must not happen if "Create new revision" is enabled by default,
+ // since the state would auto-disable the checkbox otherwise.
+ if (!$this->entity->isNewRevision()) {
+ $form['revision_information']['revision']['#states'] = [
+ 'checked' => [
+ 'textarea[name="revision_log"]' => ['empty' => FALSE],
+ ],
+ ];
+ }
+
+ $form['revision_information']['revision_log'] = [
+ '#type' => 'textarea',
+ '#title' => $this->t('Revision log message'),
+ '#rows' => 4,
+ '#default_value' => $this->entity->getRevisionLogMessage(),
+ '#description' => $this->t('Briefly describe the changes you have made.'),
+ ];
+
+ return parent::form($form, $form_state);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function save(array $form, FormStateInterface $form_state) {
+ // Save as a new revision if requested to do so.
+ if (!$form_state->isValueEmpty('revision')) {
+ $this->entity->setNewRevision();
+ }
+
+ $insert = $this->entity->isNew();
+ $this->entity->save();
+ $context = ['@type' => $this->entity->bundle(), '%info' => $this->entity->label()];
+ $logger = $this->logger('content');
+ $bundle_entity = $this->getBundleEntity();
+ $t_args = ['@type' => $bundle_entity ? $bundle_entity->label() : 'None', '%info' => $this->entity->label()];
+
+ if ($insert) {
+ $logger->notice('@type: added %info.', $context);
+ drupal_set_message($this->t('@type %info has been created.', $t_args));
+ }
+ else {
+ $logger->notice('@type: updated %info.', $context);
+ drupal_set_message($this->t('@type %info has been updated.', $t_args));
+ }
+
+ if ($this->entity->id()) {
+ $form_state->setValue('id', $this->entity->id());
+ $form_state->set('id', $this->entity->id());
+
+ if ($this->entity->getEntityType()->hasLinkTemplate('collection')) {
+ $form_state->setRedirectUrl($this->entity->toUrl('collection'));
+ }
+ else {
+ $form_state->setRedirectUrl($this->entity->toUrl('canonical'));
+ }
+ }
+ else {
+ // In the unlikely case something went wrong on save, the entity will be
+ // rebuilt and entity form redisplayed.
+ drupal_set_message($this->t('The entity could not be saved.'), 'error');
+ $form_state->setRebuild();
+ }
+ }
+
+}
diff --git a/sites/all/modules/contrib/dev/entity/src/Plugin/Action/DeleteAction.php b/sites/all/modules/contrib/dev/entity/src/Plugin/Action/DeleteAction.php
index c99d4c9ec..51c9d39c1 100644
--- a/sites/all/modules/contrib/dev/entity/src/Plugin/Action/DeleteAction.php
+++ b/sites/all/modules/contrib/dev/entity/src/Plugin/Action/DeleteAction.php
@@ -44,7 +44,7 @@ class DeleteAction extends ActionBase implements ContainerFactoryPluginInterface
* The plugin implementation definition.
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
- * @param AccountInterface $current_user
+ * @param \Drupal\Core\Session\AccountInterface $current_user
* Current user.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
diff --git a/sites/all/modules/contrib/dev/entity/src/UncacheableEntityAccessControlHandler.php b/sites/all/modules/contrib/dev/entity/src/UncacheableEntityAccessControlHandler.php
index df6a4001b..a53724bed 100644
--- a/sites/all/modules/contrib/dev/entity/src/UncacheableEntityAccessControlHandler.php
+++ b/sites/all/modules/contrib/dev/entity/src/UncacheableEntityAccessControlHandler.php
@@ -3,12 +3,10 @@
namespace Drupal\entity;
use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Entity\EntityAccessControlHandler as CoreEntityAccessControlHandler;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Session\AccountInterface;
-use Drupal\user\EntityOwnerInterface;
/**
* Controls access based on the uncacheable entity permissions.
@@ -17,7 +15,7 @@ use Drupal\user\EntityOwnerInterface;
*
* Note: this access control handler will cause pages to be cached per user.
*/
-class UncacheableEntityAccessControlHandler extends CoreEntityAccessControlHandler {
+class UncacheableEntityAccessControlHandler extends EntityAccessControlHandlerBase {
/**
* {@inheritdoc}
@@ -26,110 +24,28 @@ class UncacheableEntityAccessControlHandler extends CoreEntityAccessControlHandl
parent::__construct($entity_type);
if (!$entity_type->hasHandlerClass('permission_provider') || !is_a($entity_type->getHandlerClass('permission_provider'), UncacheableEntityPermissionProvider::class, TRUE)) {
- throw new \Exception("This entity access control handler requires the entity permissions provider: {EntityPermissionProvider::class}");
+ throw new \Exception('\Drupal\entity\UncacheableEntityAccessControlHandler requires the \Drupal\entity\UncacheableEntityPermissionProvider permission provider.');
}
}
-
/**
* {@inheritdoc}
*/
- protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
- $account = $this->prepareUser($account);
- /** @var \Drupal\Core\Access\AccessResult $result */
- $result = parent::checkAccess($entity, $operation, $account);
-
- if ($result->isNeutral()) {
- if ($entity instanceof EntityOwnerInterface) {
- $result = $this->checkEntityOwnerPermissions($entity, $operation, $account);
- }
- else {
- $result = $this->checkEntityPermissions($entity, $operation, $account);
- }
- }
-
- // Ensure that access is evaluated again when the entity changes.
- return $result->addCacheableDependency($entity);
- }
-
- /**
- * Checks the entity operation and bundle permissions.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity for which to check access.
- * @param string $operation
- * The entity operation. Usually one of 'view', 'view label', 'update' or
- * 'delete'.
- * @param \Drupal\Core\Session\AccountInterface $account
- * The user for which to check access.
- *
- * @return \Drupal\Core\Access\AccessResultInterface
- * The access result.
- */
- protected function checkEntityPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
- return AccessResult::allowedIfHasPermissions($account, [
- "$operation {$entity->getEntityTypeId()}",
- "$operation {$entity->bundle()} {$entity->getEntityTypeId()}",
- ], 'OR');
- }
-
- /**
- * Checks the entity operation and bundle permissions, with owners.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity for which to check access.
- * @param string $operation
- * The entity operation. Usually one of 'view', 'view label', 'update' or
- * 'delete'.
- * @param \Drupal\Core\Session\AccountInterface $account
- * The user for which to check access.
- *
- * @return \Drupal\Core\Access\AccessResultInterface
- * The access result.
- */
protected function checkEntityOwnerPermissions(EntityInterface $entity, $operation, AccountInterface $account) {
- /** @var \Drupal\Core\Entity\EntityInterface|\Drupal\user\EntityOwnerInterface $entity */
- if (($account->id() == $entity->getOwnerId())) {
- if ($operation === 'view' && $entity instanceof EntityPublishedInterface && !$entity->isPublished()) {
- $permissions = [
- "view own unpublished {$entity->getEntityTypeId()}",
- ];
+ /** @var \Drupal\user\EntityOwnerInterface $entity */
+ if ($operation === 'view' && $entity instanceof EntityPublishedInterface && !$entity->isPublished()) {
+ if ($account->id() != $entity->getOwnerId()) {
+ // There's no permission for viewing other user's unpublished entity.
+ return AccessResult::neutral()->cachePerUser();
}
- else {
- $permissions = [
- "$operation own {$entity->getEntityTypeId()}",
- "$operation any {$entity->getEntityTypeId()}",
- "$operation own {$entity->bundle()} {$entity->getEntityTypeId()}",
- "$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
- ];
- }
- $result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
+
+ $permissions = [
+ "view own unpublished {$entity->getEntityTypeId()}",
+ ];
+ $result = AccessResult::allowedIfHasPermissions($account, $permissions)->cachePerUser();
}
else {
- $result = AccessResult::allowedIfHasPermissions($account, [
- "$operation any {$entity->getEntityTypeId()}",
- "$operation any {$entity->bundle()} {$entity->getEntityTypeId()}",
- ], 'OR');
- }
-
- return $result->cachePerUser();
- }
-
- /**
- * {@inheritdoc}
- */
- protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
- $result = parent::checkCreateAccess($account, $context, $entity_bundle);
- if ($result->isNeutral()) {
- $permissions = [
- 'administer ' . $this->entityTypeId,
- 'create ' . $this->entityTypeId,
- ];
- if ($entity_bundle) {
- $permissions[] = 'create ' . $entity_bundle . ' ' . $this->entityTypeId;
- }
-
- $result = AccessResult::allowedIfHasPermissions($account, $permissions, 'OR');
+ $result = parent::checkEntityOwnerPermissions($entity, $operation, $account);
}
return $result;
diff --git a/sites/all/modules/contrib/dev/entity/src/UncacheableEntityPermissionProvider.php b/sites/all/modules/contrib/dev/entity/src/UncacheableEntityPermissionProvider.php
index 4d105c0ae..9a2fdf01b 100644
--- a/sites/all/modules/contrib/dev/entity/src/UncacheableEntityPermissionProvider.php
+++ b/sites/all/modules/contrib/dev/entity/src/UncacheableEntityPermissionProvider.php
@@ -8,24 +8,25 @@ use Drupal\user\EntityOwnerInterface;
/**
* Provides generic entity permissions which are cached per user.
*
- * This includes:
+ * Intended for content entity types, since config entity types usually rely
+ * on a single "administer" permission.
*
+ * Provided permissions:
* - administer $entity_type
* - access $entity_type overview
- * - view an ($bundle) $entity_type
+ * - view any ($bundle) $entity_type
* - view own ($bundle) $entity_type
* - view own unpublished $entity_type
* - update (own|any) ($bundle) $entity_type
* - delete (own|any) ($bundle) $entity_type
* - create $bundle $entity_type
*
- * As this class supports "view own ($bundle) $entity_type" it is just cacheable
- * per user, which might harm performance of sites. Given that please use
- * \Drupal\entity\EntityPermissionProvider unless you need the feature, or your
- * entity type is not really user facing (commerce orders for example).
+ * Important:
+ * Provides "view own ($bundle) $entity_type" permissions, which require
+ * caching pages per user. This can significantly increase the size of caches,
+ * impacting site performance. Use \Drupal\entity\EntityPermissionProvider
+ * if those permissions are not necessary.
*
- * Intended for content entity types, since config entity types usually rely
- * on a single "administer" permission.
* Example annotation:
* @code
* handlers = {
diff --git a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_examples_test/entity_module_bundle_plugin_examples_test.info.yml b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_examples_test/entity_module_bundle_plugin_examples_test.info.yml
index 30a86e39b..ea21c3d13 100644
--- a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_examples_test/entity_module_bundle_plugin_examples_test.info.yml
+++ b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_examples_test/entity_module_bundle_plugin_examples_test.info.yml
@@ -6,8 +6,8 @@ package: Testing
dependencies:
- entity
-# Information added by Drupal.org packaging script on 2018-03-12
-version: '8.x-1.0-beta2'
+# Information added by Drupal.org packaging script on 2018-06-08
+version: '8.x-1.0-beta4'
core: '8.x'
project: 'entity'
-datestamp: 1520873296
+datestamp: 1528452194
diff --git a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.info.yml b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.info.yml
index 5beb85c6a..f3931409a 100644
--- a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.info.yml
+++ b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_bundle_plugin_test/entity_module_bundle_plugin_test.info.yml
@@ -6,8 +6,8 @@ package: Testing
dependencies:
- entity
-# Information added by Drupal.org packaging script on 2018-03-12
-version: '8.x-1.0-beta2'
+# Information added by Drupal.org packaging script on 2018-06-08
+version: '8.x-1.0-beta4'
core: '8.x'
project: 'entity'
-datestamp: 1520873296
+datestamp: 1528452194
diff --git a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/entity_module_test.info.yml b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/entity_module_test.info.yml
index bb830cff3..65fd30379 100644
--- a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/entity_module_test.info.yml
+++ b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/entity_module_test.info.yml
@@ -3,8 +3,8 @@ type: module
package: Testing
# core: 8.x
-# Information added by Drupal.org packaging script on 2018-03-12
-version: '8.x-1.0-beta2'
+# Information added by Drupal.org packaging script on 2018-06-08
+version: '8.x-1.0-beta4'
core: '8.x'
project: 'entity'
-datestamp: 1520873296
+datestamp: 1528452194
diff --git a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php
index c5df7d2d5..f9f7b9b6c 100644
--- a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php
+++ b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntity.php
@@ -24,8 +24,8 @@ use Drupal\entity\Revision\RevisionableContentEntityBase;
* "access" = "\Drupal\Core\Entity\EntityAccessControlHandler",
* "permission_provider" = "\Drupal\entity\EntityPermissionProvider",
* "form" = {
- * "add" = "\Drupal\Core\Entity\ContentEntityForm",
- * "edit" = "\Drupal\Core\Entity\ContentEntityForm",
+ * "add" = "\Drupal\entity\Form\RevisionableContentEntityForm",
+ * "edit" = "\Drupal\entity\Form\RevisionableContentEntityForm",
* "delete" = "\Drupal\Core\Entity\EntityDeleteForm",
* },
* "route_provider" = {
diff --git a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntityBundle.php b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntityBundle.php
index 48524a828..4b3a14bc9 100644
--- a/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntityBundle.php
+++ b/sites/all/modules/contrib/dev/entity/tests/modules/entity_module_test/src/Entity/EnhancedEntityBundle.php
@@ -15,6 +15,9 @@ use Drupal\Core\Entity\RevisionableEntityBundleInterface;
* admin_permission = "administer entity_test_enhanced",
* config_prefix = "entity_test_enhanced_bundle",
* bundle_of = "entity_test_enhanced",
+ * handlers = {
+ * "access" = "\Drupal\entity\BundleEntityAccessControlHandler",
+ * },
* entity_keys = {
* "id" = "id",
* "label" = "label"
diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Functional/RevisionRouteAccessTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Functional/RevisionRouteAccessTest.php
index f3c205a20..c581cf0e5 100644
--- a/sites/all/modules/contrib/dev/entity/tests/src/Functional/RevisionRouteAccessTest.php
+++ b/sites/all/modules/contrib/dev/entity/tests/src/Functional/RevisionRouteAccessTest.php
@@ -23,7 +23,7 @@ class RevisionRouteAccessTest extends BrowserTestBase {
/**
* The current user.
*
- * @var \Drupal\Core\Session\AccountInterface;
+ * @var \Drupal\Core\Session\AccountInterface
*/
protected $account;
diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Kernel/BundleEntityAccessControlHandlerTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Kernel/BundleEntityAccessControlHandlerTest.php
new file mode 100644
index 000000000..9ba0412ca
--- /dev/null
+++ b/sites/all/modules/contrib/dev/entity/tests/src/Kernel/BundleEntityAccessControlHandlerTest.php
@@ -0,0 +1,56 @@
+installEntitySchema('entity_test_enhanced');
+ }
+
+ /**
+ * Tests the "view label" access checking.
+ */
+ public function testAccess() {
+ $bundle = EnhancedEntityBundle::create([
+ 'id' => 'default',
+ 'label' => 'Default',
+ ]);
+ $bundle->save();
+
+ // The default user has no permissions related to entity_test_enhanced.
+ $this->assertFalse($bundle->access('view label'));
+
+ $permissions = [
+ 'administer entity_test_enhanced',
+ 'view entity_test_enhanced',
+ 'view default entity_test_enhanced',
+ ];
+ foreach ($permissions as $permission) {
+ $account = $this->createUser([], [$permission]);
+ $this->assertTrue($bundle->access('view label', $account));
+ }
+ }
+
+}
diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Kernel/DeleteActionTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Kernel/DeleteActionTest.php
index 68680f09d..3d138d6f5 100644
--- a/sites/all/modules/contrib/dev/entity/tests/src/Kernel/DeleteActionTest.php
+++ b/sites/all/modules/contrib/dev/entity/tests/src/Kernel/DeleteActionTest.php
@@ -11,6 +11,7 @@ use Drupal\KernelTests\KernelTestBase;
/**
* Tests the delete entity action.
+ *
* @group entity
*/
class DeleteActionTest extends KernelTestBase {
@@ -25,8 +26,9 @@ class DeleteActionTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
- public static $modules = ['action', 'node', 'entity_module_test', 'entity',
- 'user', 'system'];
+ public static $modules = [
+ 'action', 'node', 'entity_module_test', 'entity', 'user', 'system',
+ ];
/**
* {@inheritdoc}
diff --git a/sites/all/modules/contrib/dev/entity/tests/Kernel/RevisionOverviewIntegrationTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Kernel/RevisionOverviewIntegrationTest.php
similarity index 98%
rename from sites/all/modules/contrib/dev/entity/tests/Kernel/RevisionOverviewIntegrationTest.php
rename to sites/all/modules/contrib/dev/entity/tests/src/Kernel/RevisionOverviewIntegrationTest.php
index 118fea62f..bc28c24e5 100644
--- a/sites/all/modules/contrib/dev/entity/tests/Kernel/RevisionOverviewIntegrationTest.php
+++ b/sites/all/modules/contrib/dev/entity/tests/src/Kernel/RevisionOverviewIntegrationTest.php
@@ -10,6 +10,8 @@ use Symfony\Component\Routing\Route;
*
* - Are the routes added properly.
* - Are the local tasks added properly.
+ *
+ * @group entity
*/
class RevisionOverviewIntegrationTest extends KernelTestBase {
diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Unit/EntityAccessControlHandlerTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Unit/EntityAccessControlHandlerTest.php
index f90ade56a..dbae5dc41 100644
--- a/sites/all/modules/contrib/dev/entity/tests/src/Unit/EntityAccessControlHandlerTest.php
+++ b/sites/all/modules/contrib/dev/entity/tests/src/Unit/EntityAccessControlHandlerTest.php
@@ -77,84 +77,71 @@ class EntityAccessControlHandlerTest extends UnitTestCase {
* A list of testAccess method arguments.
*/
public function accessProvider() {
- $data = [];
-
$entity_type = $this->prophesize(ContentEntityTypeInterface::class);
$entity_type->id()->willReturn('green_entity');
$entity_type->getAdminPermission()->willReturn('administer green_entity');
$entity_type->hasHandlerClass('permission_provider')->willReturn(TRUE);
$entity_type->getHandlerClass('permission_provider')->willReturn(EntityPermissionProvider::class);
-
- // User with the admin permission can do anything.
- $entity = $this->buildMockEntity($entity_type->reveal());
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('administer green_entity')->willReturn(TRUE);
- $data[] = [$entity->reveal(), 'view', $account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'update', $account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'delete', $account->reveal(), TRUE];
-
- // Entity with no owner.
- $entity = $this->buildMockEntity($entity_type->reveal());
- // User who has access.
- $first_account = $this->prophesize(AccountInterface::class);
- $first_account->id()->willReturn(6);
- $first_account->hasPermission('view green_entity')->willReturn(TRUE);
- $first_account->hasPermission(Argument::any())->willReturn(FALSE);
- // User who doesn't have access.
- $second_account = $this->prophesize(AccountInterface::class);
- $second_account->id()->willReturn(7);
- $second_account->hasPermission('view green_entity')->willReturn(FALSE);
- $second_account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity->reveal(), 'view', $first_account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'view', $second_account->reveal(), FALSE];
-
- // Entity with owner.
$entity = $this->buildMockEntity($entity_type->reveal(), 6);
- // Owner.
- $first_account = $this->prophesize(AccountInterface::class);
- $first_account->id()->willReturn(6);
- $first_account->hasPermission('update own green_entity')->willReturn(TRUE);
- $first_account->hasPermission(Argument::any())->willReturn(FALSE);
- // Non-owner.
- $second_account = $this->prophesize(AccountInterface::class);
- $second_account->id()->willReturn(7);
- $second_account->hasPermission('update own green_entity')->willReturn(TRUE);
- $second_account->hasPermission(Argument::any())->willReturn(FALSE);
- // User who can update any.
- $third_account = $this->prophesize(AccountInterface::class);
- $third_account->id()->willReturn(8);
- $third_account->hasPermission('update any green_entity')->willReturn(TRUE);
- $third_account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity->reveal(), 'update', $first_account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'update', $second_account->reveal(), FALSE];
- $data[] = [$entity->reveal(), 'update', $third_account->reveal(), TRUE];
- // Test the unpublished permissions.
- $entity_first_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'first', FALSE);
- $entity_first_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'first', FALSE);
- $entity_first_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'first', FALSE);
+ $data = [];
+ // Admin permission.
+ $admin_user = $this->buildMockUser(5, 'administer green_entity');
+ $data[] = [$entity->reveal(), 'view', $admin_user->reveal(), TRUE];
+ $data[] = [$entity->reveal(), 'update', $admin_user->reveal(), TRUE];
+ $data[] = [$entity->reveal(), 'delete', $admin_user->reveal(), TRUE];
- $entity_second_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'second', FALSE);
- $entity_second_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'second', FALSE);
- $entity_second_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'second', FALSE);
+ // View, Update, delete permissions, entity without an owner.
+ $second_entity = $this->buildMockEntity($entity_type->reveal());
+ foreach (['view', 'update', 'delete'] as $operation) {
+ $first_user = $this->buildMockUser(6, $operation . ' green_entity');
+ $second_user = $this->buildMockUser(7, 'access content');
- $user_view_own_up = $this->buildMockUser(14, 'view own unpublished green_entity');
- $user_view_other = $this->buildMockUser(15, 'view green_entity');
+ $data[] = [$second_entity->reveal(), $operation, $first_user->reveal(), TRUE];
+ $data[] = [$second_entity->reveal(), $operation, $second_user->reveal(), FALSE];
+ }
- $data['entity_first_other_up user_view_own_up'] = [$entity_first_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_first_own_up user_view_own_up'] = [$entity_first_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
- $data['entity_first_own_bundle_up user_view_own_up'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_second_other_up user_view_own_up'] = [$entity_second_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_second_own_up user_view_own_up'] = [$entity_second_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
- $data['entity_second_own_bundle_up user_view_own_up'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
+ // Update and delete permissions.
+ foreach (['update', 'delete'] as $operation) {
+ // Owner, non-owner, user with "any" permission.
+ $first_user = $this->buildMockUser(6, $operation . ' own green_entity');
+ $second_user = $this->buildMockUser(7, $operation . ' own green_entity');
+ $third_user = $this->buildMockUser(8, $operation . ' any green_entity');
- $data['entity_first_other_up user_view_other'] = [$entity_first_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_first_own_up user_view_other'] = [$entity_first_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_first_own_bundle_up user_view_other'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_other_up user_view_other'] = [$entity_second_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_own_up user_view_other'] = [$entity_second_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_own_bundle_up user_view_other'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
+ $data[] = [$entity->reveal(), $operation, $first_user->reveal(), TRUE];
+ $data[] = [$entity->reveal(), $operation, $second_user->reveal(), FALSE];
+ $data[] = [$entity->reveal(), $operation, $third_user->reveal(), TRUE];
+ }
+
+ // View permissions.
+ $first_user = $this->buildMockUser(9, 'view green_entity');
+ $second_user = $this->buildMockUser(10, 'view first green_entity');
+ $third_user = $this->buildMockUser(14, 'view own unpublished green_entity');
+ $fourth_user = $this->buildMockUser(14, 'access content');
+
+ $first_entity = $this->buildMockEntity($entity_type->reveal(), 1, 'first');
+ $second_entity = $this->buildMockEntity($entity_type->reveal(), 1, 'second');
+ $third_entity = $this->buildMockEntity($entity_type->reveal(), 14, 'first', FALSE);
+
+ // The first user can view the two published entities.
+ $data[] = [$first_entity->reveal(), 'view', $first_user->reveal(), TRUE];
+ $data[] = [$second_entity->reveal(), 'view', $first_user->reveal(), TRUE];
+ $data[] = [$third_entity->reveal(), 'view', $first_user->reveal(), FALSE];
+
+ // The second user can only view published entities of bundle "first".
+ $data[] = [$first_entity->reveal(), 'view', $second_user->reveal(), TRUE];
+ $data[] = [$second_entity->reveal(), 'view', $second_user->reveal(), FALSE];
+ $data[] = [$third_entity->reveal(), 'view', $second_user->reveal(), FALSE];
+
+ // The third user can view their own unpublished entity.
+ $data[] = [$first_entity->reveal(), 'view', $third_user->reveal(), FALSE];
+ $data[] = [$second_entity->reveal(), 'view', $third_user->reveal(), FALSE];
+ $data[] = [$third_entity->reveal(), 'view', $third_user->reveal(), TRUE];
+
+ // The fourth user can't view anything.
+ $data[] = [$first_entity->reveal(), 'view', $fourth_user->reveal(), FALSE];
+ $data[] = [$second_entity->reveal(), 'view', $fourth_user->reveal(), FALSE];
+ $data[] = [$third_entity->reveal(), 'view', $fourth_user->reveal(), FALSE];
return $data;
}
@@ -175,29 +162,19 @@ class EntityAccessControlHandlerTest extends UnitTestCase {
$entity_type->getHandlerClass('permission_provider')->willReturn(EntityPermissionProvider::class);
// User with the admin permission.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('administer green_entity')->willReturn(TRUE);
+ $account = $this->buildMockUser('6', 'administer green_entity');
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
// Ordinary user.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('create green_entity')->willReturn(TRUE);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
+ $account = $this->buildMockUser('6', 'create green_entity');
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
// Ordinary user, entity with a bundle.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('create first_bundle green_entity')->willReturn(TRUE);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
+ $account = $this->buildMockUser('6', 'create first_bundle green_entity');
$data[] = [$entity_type->reveal(), 'first_bundle', $account->reveal(), TRUE];
// User with no permissions.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
+ $account = $this->buildMockUser('6', 'access content');
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), FALSE];
return $data;
@@ -210,6 +187,10 @@ class EntityAccessControlHandlerTest extends UnitTestCase {
* The entity type.
* @param string $owner_id
* The owner ID.
+ * @param string $bundle
+ * The bundle.
+ * @param bool $published
+ * Whether the entity is published.
*
* @return \Prophecy\Prophecy\ObjectProphecy
* The entity mock.
@@ -242,15 +223,26 @@ class EntityAccessControlHandlerTest extends UnitTestCase {
$entity->getCacheTags()->willReturn([]);
$entity->getCacheMaxAge()->willReturn(Cache::PERMANENT);
-
return $entity;
}
+ /**
+ * Builds a mock user.
+ *
+ * @param int $uid
+ * The user ID.
+ * @param string $permission
+ * The permission to grant.
+ *
+ * @return \Prophecy\Prophecy\ObjectProphecy
+ * The user mock.
+ */
protected function buildMockUser($uid, $permission) {
$account = $this->prophesize(AccountInterface::class);
$account->id()->willReturn($uid);
$account->hasPermission($permission)->willReturn(TRUE);
$account->hasPermission(Argument::any())->willReturn(FALSE);
+
return $account;
}
diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Unit/EntityPermissionProviderTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Unit/EntityPermissionProviderTest.php
index e38021438..9bb8842c3 100644
--- a/sites/all/modules/contrib/dev/entity/tests/src/Unit/EntityPermissionProviderTest.php
+++ b/sites/all/modules/contrib/dev/entity/tests/src/Unit/EntityPermissionProviderTest.php
@@ -72,12 +72,12 @@ class EntityPermissionProviderTest extends UnitTestCase {
$entity_type->id()->willReturn('green_entity');
$entity_type->getSingularLabel()->willReturn('green entity');
$entity_type->getPluralLabel()->willReturn('green entities');
+ $entity_type->hasLinkTemplate('collection')->willReturn(FALSE);
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
$entity_type->getPermissionGranularity()->willReturn('entity_type');
$expected_permissions = [
'administer green_entity' => 'Administer green entities',
- 'access green_entity overview' => 'Access the green entities overview page',
'create green_entity' => 'Create green entities',
'update green_entity' => 'Update green entities',
'delete green_entity' => 'Delete green entities',
@@ -91,6 +91,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
$entity_type->id()->willReturn('blue_entity');
$entity_type->getSingularLabel()->willReturn('blue entity');
$entity_type->getPluralLabel()->willReturn('blue entities');
+ $entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
$entity_type->getPermissionGranularity()->willReturn('entity_type');
@@ -112,6 +113,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
$entity_type->id()->willReturn('white_entity');
$entity_type->getSingularLabel()->willReturn('white entity');
$entity_type->getPluralLabel()->willReturn('white entities');
+ $entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
$entity_type->getPermissionGranularity()->willReturn('bundle');
@@ -125,6 +127,8 @@ class EntityPermissionProviderTest extends UnitTestCase {
'update second white_entity' => 'Second: Update white entities',
'delete second white_entity' => 'Second: Delete white entities',
'view white_entity' => 'View white entities',
+ 'view first white_entity' => 'First: View white entities',
+ 'view second white_entity' => 'Second: View white entities',
];
$data[] = [$entity_type->reveal(), $expected_permissions];
@@ -134,6 +138,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
$entity_type->id()->willReturn('black_entity');
$entity_type->getSingularLabel()->willReturn('black entity');
$entity_type->getPluralLabel()->willReturn('black entities');
+ $entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
$entity_type->getPermissionGranularity()->willReturn('bundle');
@@ -146,6 +151,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
'delete any third black_entity' => 'Third: Delete any black entity',
'delete own third black_entity' => 'Third: Delete own black entities',
'view black_entity' => 'View black entities',
+ 'view third black_entity' => 'Third: View black entities',
];
$data[] = [$entity_type->reveal(), $expected_permissions];
@@ -155,6 +161,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
$entity_type->id()->willReturn('pink_entity');
$entity_type->getSingularLabel()->willReturn('pink entity');
$entity_type->getPluralLabel()->willReturn('pink entities');
+ $entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(TRUE);
$entity_type->getPermissionGranularity()->willReturn('bundle');
@@ -168,6 +175,7 @@ class EntityPermissionProviderTest extends UnitTestCase {
'delete any third pink_entity' => 'Third: Delete any pink entity',
'delete own third pink_entity' => 'Third: Delete own pink entities',
'view pink_entity' => 'View pink entities',
+ 'view third pink_entity' => 'Third: View pink entities',
];
$data[] = [$entity_type->reveal(), $expected_permissions];
diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Unit/UncacheableEntityAccessControlHandlerTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Unit/UncacheableEntityAccessControlHandlerTest.php
index c788a5b48..1cc84676d 100644
--- a/sites/all/modules/contrib/dev/entity/tests/src/Unit/UncacheableEntityAccessControlHandlerTest.php
+++ b/sites/all/modules/contrib/dev/entity/tests/src/Unit/UncacheableEntityAccessControlHandlerTest.php
@@ -21,7 +21,7 @@ use Drupal\user\EntityOwnerInterface;
use Prophecy\Argument;
/**
- * @coversDefaultClass \Drupal\entity\EntityAccessControlHandler
+ * @coversDefaultClass \Drupal\entity\UncacheableEntityAccessControlHandler
* @group entity
*/
class UncacheableEntityAccessControlHandlerTest extends UnitTestCase {
@@ -77,126 +77,75 @@ class UncacheableEntityAccessControlHandlerTest extends UnitTestCase {
* A list of testAccess method arguments.
*/
public function accessProvider() {
- $data = [];
-
$entity_type = $this->prophesize(ContentEntityTypeInterface::class);
$entity_type->id()->willReturn('green_entity');
$entity_type->getAdminPermission()->willReturn('administer green_entity');
$entity_type->hasHandlerClass('permission_provider')->willReturn(TRUE);
$entity_type->getHandlerClass('permission_provider')->willReturn(UncacheableEntityPermissionProvider::class);
-
- // User with the admin permission can do anything.
- $entity = $this->buildMockEntity($entity_type->reveal());
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('administer green_entity')->willReturn(TRUE);
- $data[] = [$entity->reveal(), 'view', $account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'update', $account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'delete', $account->reveal(), TRUE];
-
- // Entity with no owner.
- $entity = $this->buildMockEntity($entity_type->reveal());
- // User who has access.
- $first_account = $this->prophesize(AccountInterface::class);
- $first_account->id()->willReturn(6);
- $first_account->hasPermission('view green_entity')->willReturn(TRUE);
- $first_account->hasPermission(Argument::any())->willReturn(FALSE);
- // User who doesn't have access.
- $second_account = $this->prophesize(AccountInterface::class);
- $second_account->id()->willReturn(7);
- $second_account->hasPermission('view green_entity')->willReturn(FALSE);
- $second_account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity->reveal(), 'view', $first_account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'view', $second_account->reveal(), FALSE];
-
- // Entity with owner.
$entity = $this->buildMockEntity($entity_type->reveal(), 6);
- // Owner.
- $first_account = $this->prophesize(AccountInterface::class);
- $first_account->id()->willReturn(6);
- $first_account->hasPermission('update own green_entity')->willReturn(TRUE);
- $first_account->hasPermission(Argument::any())->willReturn(FALSE);
- // Non-owner.
- $second_account = $this->prophesize(AccountInterface::class);
- $second_account->id()->willReturn(7);
- $second_account->hasPermission('update own green_entity')->willReturn(TRUE);
- $second_account->hasPermission(Argument::any())->willReturn(FALSE);
- // User who can update any.
- $third_account = $this->prophesize(AccountInterface::class);
- $third_account->id()->willReturn(8);
- $third_account->hasPermission('update any green_entity')->willReturn(TRUE);
- $third_account->hasPermission(Argument::any())->willReturn(FALSE);
- $data[] = [$entity->reveal(), 'update', $first_account->reveal(), TRUE];
- $data[] = [$entity->reveal(), 'update', $second_account->reveal(), FALSE];
- $data[] = [$entity->reveal(), 'update', $third_account->reveal(), TRUE];
- // Per bundle permissions.
- $entity_first_other = $this->buildMockEntity($entity_type->reveal(), 9999, 'first');
- $entity_first_own = $this->buildMockEntity($entity_type->reveal(), 10, 'first');
- $entity_first_own_bundle = $this->buildMockEntity($entity_type->reveal(), 12, 'first');
+ $data = [];
+ // Admin permission.
+ $admin_user = $this->buildMockUser(5, 'administer green_entity');
+ $data[] = [$entity->reveal(), 'view', $admin_user->reveal(), TRUE];
+ $data[] = [$entity->reveal(), 'update', $admin_user->reveal(), TRUE];
+ $data[] = [$entity->reveal(), 'delete', $admin_user->reveal(), TRUE];
- $entity_second_other = $this->buildMockEntity($entity_type->reveal(), 9999, 'second');
- $entity_second_own = $this->buildMockEntity($entity_type->reveal(), 10, 'second');
- $entity_second_own_bundle = $this->buildMockEntity($entity_type->reveal(), 12, 'second');
-
- $user_view_any = $this->buildMockUser(9, 'view any green_entity');
- $user_view_own = $this->buildMockUser(10, 'view own green_entity');
- $user_view_bundle_any = $this->buildMockUser(11, 'view any first green_entity');
- $user_view_bundle_own = $this->buildMockUser(12, 'view own first green_entity');
+ // View, update, delete permissions, entity without an owner.
+ $second_entity = $this->buildMockEntity($entity_type->reveal());
+ foreach (['view', 'update', 'delete'] as $operation) {
+ $first_user = $this->buildMockUser(6, $operation . ' green_entity');
+ $second_user = $this->buildMockUser(7, 'access content');
- $data['entity_first_other user_view_any'] = [$entity_first_other->reveal(), 'view', $user_view_any->reveal(), TRUE];
- $data['entity_first_own user_view_any'] = [$entity_first_own->reveal(), 'view', $user_view_any->reveal(), TRUE];
- $data['entity_first_own_bundle user_view_any'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_any->reveal(), TRUE];
- $data['entity_second_other user_view_any'] = [$entity_second_other->reveal(), 'view', $user_view_any->reveal(), TRUE];
- $data['entity_second_own user_view_any'] = [$entity_second_own->reveal(), 'view', $user_view_any->reveal(), TRUE];
- $data['entity_second_own_bundle user_view_any'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_any->reveal(), TRUE];
+ $data[] = [$second_entity->reveal(), $operation, $first_user->reveal(), TRUE];
+ $data[] = [$second_entity->reveal(), $operation, $second_user->reveal(), FALSE];
+ }
- $data['entity_first_other user_view_own'] = [$entity_first_other->reveal(), 'view', $user_view_own->reveal(), FALSE];
- $data['entity_first_own user_view_own'] = [$entity_first_own->reveal(), 'view', $user_view_own->reveal(), TRUE];
- $data['entity_first_own_bundle user_view_own'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_own->reveal(), FALSE];
- $data['entity_second_other user_view_own'] = [$entity_second_other->reveal(), 'view', $user_view_own->reveal(), FALSE];
- $data['entity_second_own user_view_own'] = [$entity_second_own->reveal(), 'view', $user_view_own->reveal(), TRUE];
- $data['entity_second_own_bundle user_view_own'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_own->reveal(), FALSE];
+ // View, update, delete permissions.
+ foreach (['view', 'update', 'delete'] as $operation) {
+ // Owner, non-owner, user with "any" permission.
+ $first_user = $this->buildMockUser(6, $operation . ' own green_entity');
+ $second_user = $this->buildMockUser(7, $operation . ' own green_entity');
+ $third_user = $this->buildMockUser(8, $operation . ' any green_entity');
- $data['entity_first_other user_view_bundle_any'] = [$entity_first_other->reveal(), 'view', $user_view_bundle_any->reveal(), TRUE];
- $data['entity_first_own user_view_bundle_any'] = [$entity_first_own->reveal(), 'view', $user_view_bundle_any->reveal(), TRUE];
- $data['entity_first_own_bundle user_view_bundle_any'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_bundle_any->reveal(), TRUE];
- $data['entity_second_other user_view_bundle_any'] = [$entity_second_other->reveal(), 'view', $user_view_bundle_any->reveal(), FALSE];
- $data['entity_second_own user_view_bundle_any'] = [$entity_second_own->reveal(), 'view', $user_view_bundle_any->reveal(), FALSE];
- $data['entity_second_own_bundle user_view_bundle_any'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_bundle_any->reveal(), FALSE];
+ $data[] = [$entity->reveal(), $operation, $first_user->reveal(), TRUE];
+ $data[] = [$entity->reveal(), $operation, $second_user->reveal(), FALSE];
+ $data[] = [$entity->reveal(), $operation, $third_user->reveal(), TRUE];
+ }
- $data['entity_first_other user_view_bundle_any'] = [$entity_first_other->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
- $data['entity_first_own user_view_bundle_any'] = [$entity_first_own->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
- $data['entity_first_own_bundle user_view_bundle_any'] = [$entity_first_own_bundle->reveal(), 'view', $user_view_bundle_own->reveal(), TRUE];
- $data['entity_second_other user_view_bundle_any'] = [$entity_second_other->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
- $data['entity_second_own user_view_bundle_any'] = [$entity_second_own->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
- $data['entity_second_own_bundle user_view_bundle_any'] = [$entity_second_own_bundle->reveal(), 'view', $user_view_bundle_own->reveal(), FALSE];
+ // Per bundle and unpublished view permissions.
+ $first_user = $this->buildMockUser(11, 'view any first green_entity');
+ $second_user = $this->buildMockUser(12, 'view own first green_entity');
+ $third_user = $this->buildMockUser(13, 'view own unpublished green_entity');
- // Test the unpublished permissions.
- $entity_first_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'first', FALSE);
- $entity_first_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'first', FALSE);
- $entity_first_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'first', FALSE);
+ $first_entity = $this->buildMockEntity($entity_type->reveal(), 9999, 'first');
+ $second_entity = $this->buildMockEntity($entity_type->reveal(), 12, 'first');
+ $third_entity = $this->buildMockEntity($entity_type->reveal(), 9999, 'second');
+ $fourth_entity = $this->buildMockEntity($entity_type->reveal(), 10, 'second');
+ $fifth_entity = $this->buildMockEntity($entity_type->reveal(), 13, 'first', FALSE);
- $entity_second_other_up = $this->buildMockEntity($entity_type->reveal(), 9999, 'second', FALSE);
- $entity_second_own_up = $this->buildMockEntity($entity_type->reveal(), 14, 'second', FALSE);
- $entity_second_own_bundle_up = $this->buildMockEntity($entity_type->reveal(), 15, 'second', FALSE);
+ // The first user can view the two entities of bundle "first".
+ $data[] = [$first_entity->reveal(), 'view', $first_user->reveal(), TRUE];
+ $data[] = [$second_entity->reveal(), 'view', $first_user->reveal(), TRUE];
+ $data[] = [$third_entity->reveal(), 'view', $first_user->reveal(), FALSE];
+ $data[] = [$fourth_entity->reveal(), 'view', $first_user->reveal(), FALSE];
+ $data[] = [$fifth_entity->reveal(), 'view', $first_user->reveal(), FALSE];
- $user_view_own_up = $this->buildMockUser(14, 'view own unpublished green_entity');
- $user_view_other = $this->buildMockUser(15, 'view green_entity');
+ // The second user can view their own entity of bundle "first".
+ $data[] = [$first_entity->reveal(), 'view', $second_user->reveal(), FALSE];
+ $data[] = [$second_entity->reveal(), 'view', $second_user->reveal(), TRUE];
+ $data[] = [$third_entity->reveal(), 'view', $second_user->reveal(), FALSE];
+ $data[] = [$fourth_entity->reveal(), 'view', $second_user->reveal(), FALSE];
+ $data[] = [$fourth_entity->reveal(), 'view', $second_user->reveal(), FALSE];
+ $data[] = [$fifth_entity->reveal(), 'view', $second_user->reveal(), FALSE];
- $data['entity_first_other_up user_view_own_up'] = [$entity_first_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_first_own_up user_view_own_up'] = [$entity_first_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
- $data['entity_first_own_bundle_up user_view_own_up'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_second_other_up user_view_own_up'] = [$entity_second_other_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
- $data['entity_second_own_up user_view_own_up'] = [$entity_second_own_up->reveal(), 'view', $user_view_own_up->reveal(), TRUE];
- $data['entity_second_own_bundle_up user_view_own_up'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_own_up->reveal(), FALSE];
-
- $data['entity_first_other_up user_view_other'] = [$entity_first_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_first_own_up user_view_other'] = [$entity_first_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_first_own_bundle_up user_view_other'] = [$entity_first_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_other_up user_view_other'] = [$entity_second_other_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_own_up user_view_other'] = [$entity_second_own_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
- $data['entity_second_own_bundle_up user_view_other'] = [$entity_second_own_bundle_up->reveal(), 'view', $user_view_other->reveal(), FALSE];
+ // The third user can only view their own unpublished entity.
+ $data[] = [$first_entity->reveal(), 'view', $third_user->reveal(), FALSE];
+ $data[] = [$second_entity->reveal(), 'view', $third_user->reveal(), FALSE];
+ $data[] = [$third_entity->reveal(), 'view', $third_user->reveal(), FALSE];
+ $data[] = [$fourth_entity->reveal(), 'view', $third_user->reveal(), FALSE];
+ $data[] = [$fourth_entity->reveal(), 'view', $third_user->reveal(), FALSE];
+ $data[] = [$fifth_entity->reveal(), 'view', $third_user->reveal(), TRUE];
return $data;
}
@@ -217,29 +166,19 @@ class UncacheableEntityAccessControlHandlerTest extends UnitTestCase {
$entity_type->getHandlerClass('permission_provider')->willReturn(UncacheableEntityPermissionProvider::class);
// User with the admin permission.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('administer green_entity')->willReturn(TRUE);
+ $account = $this->buildMockUser('6', 'administer green_entity');
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
// Ordinary user.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('create green_entity')->willReturn(TRUE);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
+ $account = $this->buildMockUser('6', 'create green_entity');
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), TRUE];
// Ordinary user, entity with a bundle.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission('create first_bundle green_entity')->willReturn(TRUE);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
+ $account = $this->buildMockUser('6', 'create first_bundle green_entity');
$data[] = [$entity_type->reveal(), 'first_bundle', $account->reveal(), TRUE];
// User with no permissions.
- $account = $this->prophesize(AccountInterface::class);
- $account->id()->willReturn(6);
- $account->hasPermission(Argument::any())->willReturn(FALSE);
+ $account = $this->buildMockUser('6', 'access content');
$data[] = [$entity_type->reveal(), NULL, $account->reveal(), FALSE];
return $data;
@@ -252,6 +191,10 @@ class UncacheableEntityAccessControlHandlerTest extends UnitTestCase {
* The entity type.
* @param string $owner_id
* The owner ID.
+ * @param string $bundle
+ * The bundle.
+ * @param bool $published
+ * Whether the entity is published.
*
* @return \Prophecy\Prophecy\ObjectProphecy
* The entity mock.
@@ -284,15 +227,26 @@ class UncacheableEntityAccessControlHandlerTest extends UnitTestCase {
$entity->getCacheTags()->willReturn([]);
$entity->getCacheMaxAge()->willReturn(Cache::PERMANENT);
-
return $entity;
}
+ /**
+ * Builds a mock user.
+ *
+ * @param int $uid
+ * The user ID.
+ * @param string $permission
+ * The permission to grant.
+ *
+ * @return \Prophecy\Prophecy\ObjectProphecy
+ * The user mock.
+ */
protected function buildMockUser($uid, $permission) {
$account = $this->prophesize(AccountInterface::class);
$account->id()->willReturn($uid);
$account->hasPermission($permission)->willReturn(TRUE);
$account->hasPermission(Argument::any())->willReturn(FALSE);
+
return $account;
}
diff --git a/sites/all/modules/contrib/dev/entity/tests/src/Unit/UncacheableEntityPermissionProviderTest.php b/sites/all/modules/contrib/dev/entity/tests/src/Unit/UncacheableEntityPermissionProviderTest.php
index afaab7ce2..a3dd02194 100644
--- a/sites/all/modules/contrib/dev/entity/tests/src/Unit/UncacheableEntityPermissionProviderTest.php
+++ b/sites/all/modules/contrib/dev/entity/tests/src/Unit/UncacheableEntityPermissionProviderTest.php
@@ -72,12 +72,12 @@ class UncacheableEntityPermissionProviderTest extends UnitTestCase {
$entity_type->id()->willReturn('green_entity');
$entity_type->getSingularLabel()->willReturn('green entity');
$entity_type->getPluralLabel()->willReturn('green entities');
+ $entity_type->hasLinkTemplate('collection')->willReturn(FALSE);
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
$entity_type->getPermissionGranularity()->willReturn('entity_type');
$expected_permissions = [
'administer green_entity' => 'Administer green entities',
- 'access green_entity overview' => 'Access the green entities overview page',
'create green_entity' => 'Create green entities',
'update green_entity' => 'Update green entities',
'delete green_entity' => 'Delete green entities',
@@ -91,6 +91,7 @@ class UncacheableEntityPermissionProviderTest extends UnitTestCase {
$entity_type->id()->willReturn('blue_entity');
$entity_type->getSingularLabel()->willReturn('blue entity');
$entity_type->getPluralLabel()->willReturn('blue entities');
+ $entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
$entity_type->getPermissionGranularity()->willReturn('entity_type');
@@ -113,6 +114,7 @@ class UncacheableEntityPermissionProviderTest extends UnitTestCase {
$entity_type->id()->willReturn('white_entity');
$entity_type->getSingularLabel()->willReturn('white entity');
$entity_type->getPluralLabel()->willReturn('white entities');
+ $entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(FALSE);
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
$entity_type->getPermissionGranularity()->willReturn('bundle');
@@ -137,6 +139,7 @@ class UncacheableEntityPermissionProviderTest extends UnitTestCase {
$entity_type->id()->willReturn('black_entity');
$entity_type->getSingularLabel()->willReturn('black entity');
$entity_type->getPluralLabel()->willReturn('black entities');
+ $entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(FALSE);
$entity_type->getPermissionGranularity()->willReturn('bundle');
@@ -161,6 +164,7 @@ class UncacheableEntityPermissionProviderTest extends UnitTestCase {
$entity_type->id()->willReturn('pink_entity');
$entity_type->getSingularLabel()->willReturn('pink entity');
$entity_type->getPluralLabel()->willReturn('pink entities');
+ $entity_type->hasLinkTemplate('collection')->willReturn(TRUE);
$entity_type->entityClassImplements(EntityOwnerInterface::class)->willReturn(TRUE);
$entity_type->entityClassImplements(EntityPublishedInterface::class)->willReturn(TRUE);
$entity_type->getPermissionGranularity()->willReturn('bundle');
diff --git a/sites/all/modules/contrib/dev/token/README.md b/sites/all/modules/contrib/dev/token/README.md
old mode 100644
new mode 100755
index c37d33508..c2f8d04c8
--- a/sites/all/modules/contrib/dev/token/README.md
+++ b/sites/all/modules/contrib/dev/token/README.md
@@ -1,3 +1,13 @@
+CONTENTS OF THIS FILE
+---------------------
+
+ * Introduction
+ * Recommended modules
+ * Installation
+ * Configuration
+ * Troubleshooting
+ * Maintainers
+
INTRODUCTION
------------
@@ -9,20 +19,28 @@ INTRODUCTION
* To submit bug reports and feature suggestions, or to track changes:
https://drupal.org/project/issues/token
+RECOMMENDED MODULES
+-------------------
+
+ * No extra module is required.
INSTALLATION
------------
-Install as usual, see
- https://www.drupal.org/docs/8/extending-drupal-8/installing-contributed-modules-find-import-enable-configure-drupal-8 for further
-information.
+ * Install as usual, see
+ https://www.drupal.org/docs/8/extending-drupal-8/installing-contributed-modules-find-import-enable-configure-drupal-8 for further
+ information.
+CONFIGURATION
+-------------
+
+ * No configuration is needed.
TROUBLESHOOTING
---------------
-Token module doesn't provide any visible functions to the user on its own, it
-just provides token handling services for other modules.
+ * Token module doesn't provide any visible functions to the user on its own, it
+ just provides token handling services for other modules.
MAINTAINERS
@@ -31,3 +49,4 @@ MAINTAINERS
Current maintainers:
* Dave Reid (https://drupal.org/user/53892)
+ * Sascha Grossenbacher (Berdir) (https://www.drupal.org/user/214652)
diff --git a/sites/all/modules/contrib/dev/token/js/token.js b/sites/all/modules/contrib/dev/token/js/token.js
index f9d6862c0..3a41d6259 100644
--- a/sites/all/modules/contrib/dev/token/js/token.js
+++ b/sites/all/modules/contrib/dev/token/js/token.js
@@ -35,6 +35,12 @@
else if (typeof(CKEDITOR) != 'undefined' && CKEDITOR.currentInstance) {
CKEDITOR.currentInstance.insertHtml(content);
}
+ // Direct CodeMirror support.
+ else if (typeof(CodeMirror) != 'undefined' && drupalSettings.tokenFocusedField && $(drupalSettings.tokenFocusedField).parents('.CodeMirror').length) {
+ var editor = $(drupalSettings.tokenFocusedField).parents('.CodeMirror')[0].CodeMirror;
+ editor.replaceSelection(content);
+ editor.focus();
+ }
// WYSIWYG support, should work in all editors if available.
else if (Drupal.wysiwyg && Drupal.wysiwyg.activeId) {
Drupal.wysiwyg.instances[Drupal.wysiwyg.activeId].insert(content)
diff --git a/sites/all/modules/contrib/dev/token/src/Controller/TokenAutocompleteController.php b/sites/all/modules/contrib/dev/token/src/Controller/TokenAutocompleteController.php
index a50da70b8..979f832a4 100644
--- a/sites/all/modules/contrib/dev/token/src/Controller/TokenAutocompleteController.php
+++ b/sites/all/modules/contrib/dev/token/src/Controller/TokenAutocompleteController.php
@@ -2,7 +2,6 @@
namespace Drupal\token\Controller;
-use Drupal\Component\Utility\Unicode;
use Drupal\Core\Controller\ControllerBase;
use Drupal\token\TreeBuilderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -48,9 +47,9 @@ class TokenAutocompleteController extends ControllerBase {
public function autocomplete($token_type, $filter, Request $request) {
$filter = substr($filter, strrpos($filter, '['));
- $matches = array();
+ $matches = [];
- if (!Unicode::strlen($filter)) {
+ if (!mb_strlen($filter)) {
$matches["[{$token_type}:"] = 0;
}
else {
diff --git a/sites/all/modules/contrib/dev/token/src/Controller/TokenCacheController.php b/sites/all/modules/contrib/dev/token/src/Controller/TokenCacheController.php
index 39dc5b0f3..7f758d335 100644
--- a/sites/all/modules/contrib/dev/token/src/Controller/TokenCacheController.php
+++ b/sites/all/modules/contrib/dev/token/src/Controller/TokenCacheController.php
@@ -7,14 +7,14 @@ use Drupal\Core\Controller\ControllerBase;
/**
* Clears cache for tokens.
*/
-class TokenCacheController extends ControllerBase {
+class TokenCacheController extends ControllerBase {
/**
* Clear caches and redirect back to the frontpage.
*/
public function flush() {
token_clear_cache();
- drupal_set_message(t('Token registry caches cleared.'));
+ $this->messenger()->addMessage($this->t('Token registry caches cleared.'));
return $this->redirect('');
}
diff --git a/sites/all/modules/contrib/dev/token/src/Routing/RouteSubscriber.php b/sites/all/modules/contrib/dev/token/src/Routing/RouteSubscriber.php
index ae6815a28..b856f43e6 100644
--- a/sites/all/modules/contrib/dev/token/src/Routing/RouteSubscriber.php
+++ b/sites/all/modules/contrib/dev/token/src/Routing/RouteSubscriber.php
@@ -71,4 +71,5 @@ class RouteSubscriber extends RouteSubscriberBase {
$events[RoutingEvents::ALTER] = array('onAlterRoutes', 100);
return $events;
}
+
}
diff --git a/sites/all/modules/contrib/dev/token/src/Tests/TokenBlockTest.php b/sites/all/modules/contrib/dev/token/src/Tests/TokenBlockTest.php
index 66e30255e..55de3b988 100644
--- a/sites/all/modules/contrib/dev/token/src/Tests/TokenBlockTest.php
+++ b/sites/all/modules/contrib/dev/token/src/Tests/TokenBlockTest.php
@@ -1,6 +1,7 @@
admin_user = $this->drupalCreateUser(array('access content', 'administer blocks'));
+ $this->admin_user = $this->drupalCreateUser(['access content', 'administer blocks']);
$this->drupalLogin($this->admin_user);
}
public function testBlockTitleTokens() {
$label = 'tokenblock';
- $bundle = BlockContentType::create(array(
+ $bundle = BlockContentType::create([
'id' => $label,
'label' => $label,
'revision' => FALSE
- ));
+ ]);
$bundle->save();
- $block_content = BlockContent::create(array(
+ $block_content = BlockContent::create([
'type' => $label,
'label' => '[current-page:title] block title',
'info' => 'Test token title block',
'body[value]' => 'This is the test token title block.',
- ));
+ ]);
$block_content->save();
- $block = $this->drupalPlaceBlock('block_content:' . $block_content->uuid(), array(
+ $block = $this->drupalPlaceBlock('block_content:' . $block_content->uuid(), [
'label' => '[user:name]',
- ));
- $this->drupalGet($block->urlInfo());
+ ]);
+ $this->drupalGet($block->toUrl());
// Ensure that the link to available tokens is present and correctly
// positioned.
$this->assertLink('Browse available tokens.');
$this->assertText('This field supports tokens. Browse available tokens.');
- $this->drupalPostForm(NULL, array(), t('Save block'));
+ $this->drupalPostForm(NULL, [], t('Save block'));
// Ensure token validation is working on the block.
$this->assertText('Title is using the following invalid tokens: [user:name].');
@@ -63,8 +64,8 @@ class TokenBlockTest extends TokenTestBase {
$block->save();
// Ensure that tokens are not double-escaped when output as a block title.
- $this->drupalCreateContentType(array('type' => 'page'));
- $node = $this->drupalCreateNode(array('title' => "Site's first node"));
+ $this->drupalCreateContentType(['type' => 'page']);
+ $node = $this->drupalCreateNode(['title' => "Site's first node"]);
$this->drupalGet('node/' . $node->id());
// The apostraphe should only be escaped once.
$this->assertRaw("Site's first node block title");
diff --git a/sites/all/modules/contrib/dev/token/src/Tests/TokenCurrentPageTest.php b/sites/all/modules/contrib/dev/token/src/Tests/TokenCurrentPageTest.php
index cd8ac3729..096c24bc4 100644
--- a/sites/all/modules/contrib/dev/token/src/Tests/TokenCurrentPageTest.php
+++ b/sites/all/modules/contrib/dev/token/src/Tests/TokenCurrentPageTest.php
@@ -16,19 +16,19 @@ class TokenCurrentPageTest extends TokenTestBase {
*
* @var array
*/
- public static $modules = array('node');
+ public static $modules = ['node'];
function testCurrentPageTokens() {
- $tokens = array(
+ $tokens = [
'[current-page:title]' => t('Log in'),
- '[current-page:url]' => Url::fromRoute('user.login', [], array('absolute' => TRUE))->toString(),
- '[current-page:url:absolute]' => Url::fromRoute('user.login', [], array('absolute' => TRUE))->toString(),
+ '[current-page:url]' => Url::fromRoute('user.login', [], ['absolute' => TRUE])->toString(),
+ '[current-page:url:absolute]' => Url::fromRoute('user.login', [], ['absolute' => TRUE])->toString(),
'[current-page:url:relative]' => Url::fromRoute('user.login')->toString(),
'[current-page:url:path]' => '/user/login',
'[current-page:url:args:value:0]' => 'user',
'[current-page:url:args:value:1]' => 'login',
'[current-page:url:args:value:2]' => NULL,
- '[current-page:url:unaliased]' => Url::fromRoute('user.login', [], array('absolute' => TRUE, 'alias' => TRUE))->toString(),
+ '[current-page:url:unaliased]' => Url::fromRoute('user.login', [], ['absolute' => TRUE, 'alias' => TRUE])->toString(),
'[current-page:page-number]' => 1,
'[current-page:query:foo]' => NULL,
'[current-page:query:bar]' => NULL,
@@ -36,20 +36,20 @@ class TokenCurrentPageTest extends TokenTestBase {
'[current-page:arg:0]' => 'user',
'[current-page:arg:1]' => 'login',
'[current-page:arg:2]' => NULL,
- );
+ ];
$this->assertPageTokens('user/login', $tokens);
- $this->drupalCreateContentType(array('type' => 'page'));
- $node = $this->drupalCreateNode(array('title' => 'Node title', 'path' => array('alias' => '/node-alias')));
- $tokens = array(
+ $this->drupalCreateContentType(['type' => 'page']);
+ $node = $this->drupalCreateNode(['title' => 'Node title', 'path' => ['alias' => '/node-alias']]);
+ $tokens = [
'[current-page:title]' => 'Node title',
- '[current-page:url]' => $node->url('canonical', array('absolute' => TRUE)),
- '[current-page:url:absolute]' => $node->url('canonical', array('absolute' => TRUE)),
- '[current-page:url:relative]' => $node->url(),
+ '[current-page:url]' => $node->toUrl('canonical', ['absolute' => TRUE])->toString(),
+ '[current-page:url:absolute]' => $node->toUrl('canonical', ['absolute' => TRUE])->toString(),
+ '[current-page:url:relative]' => $node->toUrl()->toString(),
'[current-page:url:alias]' => '/node-alias',
'[current-page:url:args:value:0]' => 'node-alias',
'[current-page:url:args:value:1]' => NULL,
- '[current-page:url:unaliased]' => $node->url('canonical', array('absolute' => TRUE, 'alias' => TRUE)),
+ '[current-page:url:unaliased]' => $node->toUrl('canonical', ['absolute' => TRUE, 'alias' => TRUE])->toString(),
'[current-page:url:unaliased:args:value:0]' => 'node',
'[current-page:url:unaliased:args:value:1]' => $node->id(),
'[current-page:url:unaliased:args:value:2]' => NULL,
@@ -60,7 +60,7 @@ class TokenCurrentPageTest extends TokenTestBase {
'[current-page:arg:0]' => 'node',
'[current-page:arg:1]' => 1,
'[current-page:arg:2]' => NULL,
- );
- $this->assertPageTokens("/node/{$node->id()}", $tokens, array(), array('url_options' => array('query' => array('foo' => 'bar'))));
+ ];
+ $this->assertPageTokens("/node/{$node->id()}", $tokens, [], ['url_options' => ['query' => ['foo' => 'bar']]]);
}
}
diff --git a/sites/all/modules/contrib/dev/token/src/Tests/TokenFieldUiTest.php b/sites/all/modules/contrib/dev/token/src/Tests/TokenFieldUiTest.php
index f7983e73b..f72295f21 100644
--- a/sites/all/modules/contrib/dev/token/src/Tests/TokenFieldUiTest.php
+++ b/sites/all/modules/contrib/dev/token/src/Tests/TokenFieldUiTest.php
@@ -2,6 +2,8 @@
namespace Drupal\token\Tests;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
use Drupal\node\Entity\NodeType;
use Drupal\node\Entity\Node;
use Drupal\file\Entity\File;
@@ -41,50 +43,50 @@ class TokenFieldUiTest extends TokenTestBase {
]);
$node_type->save();
- entity_create('field_storage_config', array(
+ FieldStorageConfig::create([
'field_name' => 'field_body',
'entity_type' => 'node',
'type' => 'text_with_summary',
- ))->save();
- entity_create('field_config', array(
+ ])->save();
+ FieldConfig::create([
'field_name' => 'field_body',
'label' => 'Body',
'entity_type' => 'node',
'bundle' => 'article',
- ))->save();
- entity_create('field_storage_config', array(
+ ])->save();
+ FieldStorageConfig::create([
'field_name' => 'field_image',
'entity_type' => 'node',
'type' => 'image',
- ))->save();
- entity_create('field_config', array(
+ ])->save();
+ FieldConfig::create([
'field_name' => 'field_image',
'label' => 'Image',
'entity_type' => 'node',
'bundle' => 'article',
- ))->save();
- entity_create('field_storage_config', array(
+ ])->save();
+ FieldStorageConfig::create([
'field_name' => 'field_image_2',
'entity_type' => 'node',
'type' => 'image',
- ))->save();
- entity_create('field_config', array(
+ ])->save();
+ FieldConfig::create([
'field_name' => 'field_image_2',
'label' => 'Image 2',
'entity_type' => 'node',
'bundle' => 'article',
- ))->save();
- entity_create('field_storage_config', array(
+ ])->save();
+ FieldStorageConfig::create([
'field_name' => 'multivalued_field_image',
'entity_type' => 'node',
'type' => 'image',
- ))->save();
- entity_create('field_config', array(
+ ])->save();
+ FieldConfig::create([
'field_name' => 'multivalued_field_image',
'label' => 'Multivalued field image',
'entity_type' => 'node',
'bundle' => 'article',
- ))->save();
+ ])->save();
entity_get_form_display('node', 'article', 'default')
->setComponent('field_body', [
diff --git a/sites/all/modules/contrib/dev/token/src/Tests/TokenMenuTest.php b/sites/all/modules/contrib/dev/token/src/Tests/TokenMenuTest.php
index 135de5533..1b2eda091 100644
--- a/sites/all/modules/contrib/dev/token/src/Tests/TokenMenuTest.php
+++ b/sites/all/modules/contrib/dev/token/src/Tests/TokenMenuTest.php
@@ -35,11 +35,11 @@ class TokenMenuTest extends TokenTestBase {
// Make sure we have a body field on the node type.
$this->drupalCreateContentType(['type' => 'page']);
// Add a menu.
- $menu = entity_create('menu', array(
+ $menu = Menu::create([
'id' => 'main-menu',
'label' => 'Main menu',
'description' => 'The Main menu is used on many sites to show the major sections of the site, often in a top navigation bar.',
- ));
+ ]);
$menu->save();
// Place the menu block.
@@ -47,25 +47,25 @@ class TokenMenuTest extends TokenTestBase {
// Add a root link.
/** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $root_link */
- $root_link = entity_create('menu_link_content', array(
+ $root_link = MenuLinkContent::create([
'link' => ['uri' => 'internal:/admin'],
'title' => 'Administration',
'menu_name' => 'main-menu',
- ));
+ ]);
$root_link->save();
// Add another link with the root link as the parent.
/** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $parent_link */
- $parent_link = entity_create('menu_link_content', array(
+ $parent_link = MenuLinkContent::create([
'link' => ['uri' => 'internal:/admin/config'],
'title' => 'Configuration',
'menu_name' => 'main-menu',
'parent' => $root_link->getPluginId(),
- ));
+ ]);
$parent_link->save();
// Test menu link tokens.
- $tokens = array(
+ $tokens = [
'id' => $parent_link->getPluginId(),
'title' => 'Configuration',
'menu' => 'Main menu',
@@ -73,13 +73,13 @@ class TokenMenuTest extends TokenTestBase {
'menu:machine-name' => $menu->id(),
'menu:description' => 'The Main menu is used on many sites to show the major sections of the site, often in a top navigation bar.',
'menu:menu-link-count' => '2',
- 'menu:edit-url' => Url::fromRoute('entity.menu.edit_form', ['menu' => 'main-menu'], array('absolute' => TRUE))->toString(),
- 'url' => Url::fromRoute('system.admin_config', [], array('absolute' => TRUE))->toString(),
- 'url:absolute' => Url::fromRoute('system.admin_config', [], array('absolute' => TRUE))->toString(),
- 'url:relative' => Url::fromRoute('system.admin_config', [], array('absolute' => FALSE))->toString(),
+ 'menu:edit-url' => Url::fromRoute('entity.menu.edit_form', ['menu' => 'main-menu'], ['absolute' => TRUE])->toString(),
+ 'url' => Url::fromRoute('system.admin_config', [], ['absolute' => TRUE])->toString(),
+ 'url:absolute' => Url::fromRoute('system.admin_config', [], ['absolute' => TRUE])->toString(),
+ 'url:relative' => Url::fromRoute('system.admin_config', [], ['absolute' => FALSE])->toString(),
'url:path' => '/admin/config',
'url:alias' => '/admin/config',
- 'edit-url' => Url::fromRoute('entity.menu_link_content.canonical', ['menu_link_content' => $parent_link->id()], array('absolute' => TRUE))->toString(),
+ 'edit-url' => Url::fromRoute('entity.menu_link_content.canonical', ['menu_link_content' => $parent_link->id()], ['absolute' => TRUE])->toString(),
'parent' => 'Administration',
'parent:id' => $root_link->getPluginId(),
'parent:title' => 'Administration',
@@ -92,32 +92,32 @@ class TokenMenuTest extends TokenTestBase {
'root:id' => $root_link->getPluginId(),
'root:parent' => NULL,
'root:root' => NULL,
- );
- $this->assertTokens('menu-link', array('menu-link' => $parent_link), $tokens);
+ ];
+ $this->assertTokens('menu-link', ['menu-link' => $parent_link], $tokens);
// Add a node.
$node = $this->drupalCreateNode();
// Allow main menu for this node type.
- //$this->config('menu.entity.node.' . $node->getType())->set('available_menus', array('main-menu'))->save();
+ //$this->config('menu.entity.node.' . $node->getType())->set('available_menus', ['main-menu'])->save();
// Add a node menu link.
/** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $node_link */
- $node_link = entity_create('menu_link_content', array(
- 'link' => ['uri' =>'entity:node/' . $node->id()],
+ $node_link = MenuLinkContent::create([
+ 'link' => ['uri' => 'entity:node/' . $node->id()],
'title' => 'Node link',
'parent' => $parent_link->getPluginId(),
'menu_name' => 'main-menu',
- ));
+ ]);
$node_link->save();
// Test [node:menu] tokens.
- $tokens = array(
+ $tokens = [
'menu-link' => 'Node link',
'menu-link:id' => $node_link->getPluginId(),
'menu-link:title' => 'Node link',
'menu-link:menu' => 'Main menu',
- 'menu-link:url' => $node->url('canonical', ['absolute' => TRUE]),
+ 'menu-link:url' => $node->toUrl('canonical', ['absolute' => TRUE])->toString(),
'menu-link:url:path' => '/node/' . $node->id(),
'menu-link:edit-url' => $node_link->url('edit-form', ['absolute' => TRUE]),
'menu-link:parent' => 'Configuration',
@@ -127,12 +127,12 @@ class TokenMenuTest extends TokenTestBase {
'menu-link:parents:keys' => $root_link->getPluginId() . ', ' . $parent_link->getPluginId(),
'menu-link:root' => 'Administration',
'menu-link:root:id' => $root_link->getPluginId(),
- );
- $this->assertTokens('node', array('node' => $node), $tokens);
+ ];
+ $this->assertTokens('node', ['node' => $node], $tokens);
// Reload the node which will not have $node->menu defined and re-test.
$loaded_node = Node::load($node->id());
- $this->assertTokens('node', array('node' => $loaded_node), $tokens);
+ $this->assertTokens('node', ['node' => $loaded_node], $tokens);
// Regression test for http://drupal.org/node/1317926 to ensure the
// original node object is not changed when calling menu_node_prepare().
@@ -148,11 +148,11 @@ class TokenMenuTest extends TokenTestBase {
'access administration pages',
]));
// Setup node type menu options.
- $edit = array(
+ $edit = [
'menu_options[main-menu]' => 1,
'menu_options[main]' => 1,
'menu_parent' => 'main-menu:',
- );
+ ];
$this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type'));
// Use a menu-link token in the body.
@@ -186,7 +186,7 @@ class TokenMenuTest extends TokenTestBase {
$select = reset($selects);
$options = $this->getAllOptions($select);
// Filter to items with title containing 'Test preview'.
- $options = array_filter($options, function(\SimpleXMLElement $item) {
+ $options = array_filter($options, function (\SimpleXMLElement $item) {
return strpos((string) $item[0], 'Test preview') !== FALSE;
});
$this->assertEqual(1, count($options));
@@ -195,14 +195,14 @@ class TokenMenuTest extends TokenTestBase {
'body[0][value]' => 'This is a [node:menu-link:parent:url:path] token to the menu link parent',
'menu[enabled]' => 1,
'menu[title]' => 'Child link',
- 'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(),
+ 'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(),
], t('Save'));
$node = $this->drupalGetNodeByTitle('Node menu title parent path test');
$this->assertEqual('This is a /admin/config token to the menu link parent', $node->body->value);
// Now edit the node and update the parent and title.
$this->drupalPostForm('node/' . $node->id() . '/edit', [
- 'menu[menu_parent]' => 'main-menu:' . $node_link->getPluginId(),
+ 'menu[menu_parent]' => 'main-menu:' . $node_link->getPluginId(),
'title[0][value]' => 'Node menu title edit parent path test',
'body[0][value]' => 'This is a [node:menu-link:parent:url:path] token to the menu link parent',
], t('Save'));
@@ -218,7 +218,7 @@ class TokenMenuTest extends TokenTestBase {
$select = reset($selects);
$options = $this->getAllOptions($select);
// Filter to items with title containing 'Test preview'.
- $options = array_filter($options, function(\SimpleXMLElement $item) {
+ $options = array_filter($options, function (\SimpleXMLElement $item) {
return strpos((string) $item[0], 'Child link') !== FALSE;
});
$this->assertEqual(1, count($options));
@@ -238,7 +238,7 @@ class TokenMenuTest extends TokenTestBase {
'body[0][value]' => 'This is a [node:menu-link:parent:url:path] token to the menu link parent',
'menu[enabled]' => 1,
'menu[title]' => 'Child link',
- 'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(),
+ 'menu[menu_parent]' => 'main-menu:' . $parent_link->getPluginId(),
], t('Save'));
$node = $this->drupalGetNodeByTitle('Node menu adding menu later test', TRUE);
$this->assertEqual('This is a /admin/config token to the menu link parent', $node->body->value);
@@ -264,14 +264,14 @@ class TokenMenuTest extends TokenTestBase {
$this->assertText('page ' . $node_title . ' has been created');
$node = $this->drupalGetNodeByTitle($node_title);
- $menu_ui_link1 = entity_create('menu_link_content', [
+ $menu_ui_link1 = MenuLinkContent::create([
'link' => ['uri' => 'entity:node/' . $node->id()],
'title' => 'menu link 1 provided by menu ui',
'menu_name' => 'main-menu',
]);
$menu_ui_link1->save();
- $menu_ui_link2 = entity_create('menu_link_content', [
+ $menu_ui_link2 = MenuLinkContent::create([
'link' => ['uri' => 'entity:node/' . $node->id()],
'title' => 'menu link 2 provided by menu ui',
'menu_name' => 'main-menu',
@@ -306,7 +306,7 @@ class TokenMenuTest extends TokenTestBase {
]);
$node_type->save();
- $permissions = array(
+ $permissions = [
'access administration pages',
'administer content translation',
'administer content types',
@@ -316,18 +316,18 @@ class TokenMenuTest extends TokenTestBase {
'edit any article content',
'translate any entity',
'administer menu',
- );
+ ];
$this->drupalLogin($this->drupalCreateUser($permissions));
// Enable translation for articles and menu links.
$this->drupalGet('admin/config/regional/content-language');
- $edit = array(
+ $edit = [
'entity_types[node]' => TRUE,
'entity_types[menu_link_content]' => TRUE,
'settings[node][article][translatable]' => TRUE,
'settings[node][article][fields][title]' => TRUE,
'settings[menu_link_content][menu_link_content][translatable]' => TRUE,
- );
+ ];
$this->drupalPostForm(NULL, $edit, t('Save configuration'));
$this->assertText('Settings successfully updated.');
@@ -411,10 +411,10 @@ class TokenMenuTest extends TokenTestBase {
// - parent
// - child-1
// - child-1-1
- Menu::create(array(
+ Menu::create([
'id' => 'menu_test',
'label' => 'Test menu',
- ))->save();
+ ])->save();
$base_options = [
'provider' => 'menu_test',
'menu_name' => 'menu_test',
diff --git a/sites/all/modules/contrib/dev/token/src/Tests/TokenTestBase.php b/sites/all/modules/contrib/dev/token/src/Tests/TokenTestBase.php
index 29c1ac3cd..814ba776f 100644
--- a/sites/all/modules/contrib/dev/token/src/Tests/TokenTestBase.php
+++ b/sites/all/modules/contrib/dev/token/src/Tests/TokenTestBase.php
@@ -16,6 +16,6 @@ abstract class TokenTestBase extends WebTestBase {
*
* @var array
*/
- public static $modules = array('path', 'token', 'token_module_test');
+ public static $modules = ['path', 'token', 'token_module_test'];
}
diff --git a/sites/all/modules/contrib/dev/token/src/Tests/TokenTestTrait.php b/sites/all/modules/contrib/dev/token/src/Tests/TokenTestTrait.php
index b37cae950..471527459 100644
--- a/sites/all/modules/contrib/dev/token/src/Tests/TokenTestTrait.php
+++ b/sites/all/modules/contrib/dev/token/src/Tests/TokenTestTrait.php
@@ -11,57 +11,57 @@ use Drupal\Core\Render\BubbleableMetadata;
*/
trait TokenTestTrait {
- function assertToken($type, array $data, $token, $expected, array $options = array()) {
- return $this->assertTokens($type, $data, array($token => $expected), $options);
+ function assertToken($type, array $data, $token, $expected, array $options = []) {
+ return $this->assertTokens($type, $data, [$token => $expected], $options);
}
- function assertTokens($type, array $data, array $tokens, array $options = array()) {
+ function assertTokens($type, array $data, array $tokens, array $options = []) {
$input = $this->mapTokenNames($type, array_keys($tokens));
$bubbleable_metadata = new BubbleableMetadata();
$replacements = \Drupal::token()->generate($type, $input, $data, $options, $bubbleable_metadata);
foreach ($tokens as $name => $expected) {
$token = $input[$name];
if (!isset($expected)) {
- $this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", array('@type' => $type, '@token' => $token)));
+ $this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", ['@type' => $type, '@token' => $token]));
}
elseif (!isset($replacements[$token])) {
- $this->fail(t("Token value for @token was not generated.", array('@type' => $type, '@token' => $token)));
+ $this->fail(t("Token value for @token was not generated.", ['@type' => $type, '@token' => $token]));
}
elseif (!empty($options['regex'])) {
- $this->assertTrue(preg_match('/^' . $expected . '$/', $replacements[$token]), t("Token value for @token was '@actual', matching regular expression pattern '@expected'.", array('@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected)));
+ $this->assertTrue(preg_match('/^' . $expected . '$/', $replacements[$token]), t("Token value for @token was '@actual', matching regular expression pattern '@expected'.", ['@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected]));
}
else {
- $this->assertEqual($replacements[$token], $expected, t("Token value for @token was '@actual', expected value '@expected'.", array('@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected)));
+ $this->assertEqual($replacements[$token], $expected, t("Token value for @token was '@actual', expected value '@expected'.", ['@type' => $type, '@token' => $token, '@actual' => $replacements[$token], '@expected' => $expected]));
}
}
return $replacements;
}
- function mapTokenNames($type, array $tokens = array()) {
- $return = array();
+ function mapTokenNames($type, array $tokens = []) {
+ $return = [];
foreach ($tokens as $token) {
$return[$token] = "[$type:$token]";
}
return $return;
}
- function assertNoTokens($type, array $data, array $tokens, array $options = array()) {
+ function assertNoTokens($type, array $data, array $tokens, array $options = []) {
$input = $this->mapTokenNames($type, $tokens);
$bubbleable_metadata = new BubbleableMetadata();
$replacements = \Drupal::token()->generate($type, $input, $data, $options, $bubbleable_metadata);
foreach ($tokens as $name) {
$token = $input[$name];
- $this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", array('@type' => $type, '@token' => $token)));
+ $this->assertTrue(!isset($replacements[$token]), t("Token value for @token was not generated.", ['@type' => $type, '@token' => $token]));
}
}
function saveAlias($source, $alias, $language = Language::LANGCODE_NOT_SPECIFIED) {
- $alias = array(
+ $alias = [
'source' => $source,
'alias' => $alias,
'language' => $language,
- );
+ ];
\Drupal::service('path.alias_storage')->save($alias['source'], $alias['alias']);
return $alias;
}
@@ -74,22 +74,22 @@ trait TokenTestTrait {
/**
* Make a page request and test for token generation.
*/
- function assertPageTokens($url, array $tokens, array $data = array(), array $options = array()) {
+ function assertPageTokens($url, array $tokens, array $data = [], array $options = []) {
if (empty($tokens)) {
return TRUE;
}
- $token_page_tokens = array(
+ $token_page_tokens = [
'tokens' => $tokens,
'data' => $data,
'options' => $options,
- );
+ ];
\Drupal::state()->set('token_page_tokens', $token_page_tokens);
- $options += array('url_options' => array());
+ $options += ['url_options' => []];
$this->drupalGet($url, $options['url_options']);
$this->refreshVariables();
- $result = \Drupal::state()->get('token_page_tokens', array());
+ $result = \Drupal::state()->get('token_page_tokens', []);
if (!isset($result['values']) || !is_array($result['values'])) {
return $this->fail('Failed to generate tokens.');
@@ -97,13 +97,13 @@ trait TokenTestTrait {
foreach ($tokens as $token => $expected) {
if (!isset($expected)) {
- $this->assertTrue(!isset($result['values'][$token]) || $result['values'][$token] === $token, t("Token value for @token was not generated.", array('@token' => $token)));
+ $this->assertTrue(!isset($result['values'][$token]) || $result['values'][$token] === $token, t("Token value for @token was not generated.", ['@token' => $token]));
}
elseif (!isset($result['values'][$token])) {
- $this->fail(t('Failed to generate token @token.', array('@token' => $token)));
+ $this->fail(t('Failed to generate token @token.', ['@token' => $token]));
}
else {
- $this->assertIdentical($result['values'][$token], (string) $expected, t("Token value for @token was '@actual', expected value '@expected'.", array('@token' => $token, '@actual' => $result['values'][$token], '@expected' => $expected)));
+ $this->assertIdentical($result['values'][$token], (string) $expected, t("Token value for @token was '@actual', expected value '@expected'.", ['@token' => $token, '@actual' => $result['values'][$token], '@expected' => $expected]));
}
}
}
diff --git a/sites/all/modules/contrib/dev/token/src/Tests/TokenURLTest.php b/sites/all/modules/contrib/dev/token/src/Tests/TokenURLTest.php
index 6241f3b69..0a3bed0fc 100644
--- a/sites/all/modules/contrib/dev/token/src/Tests/TokenURLTest.php
+++ b/sites/all/modules/contrib/dev/token/src/Tests/TokenURLTest.php
@@ -16,7 +16,7 @@ class TokenURLTest extends TokenTestBase {
*
* @var array
*/
- public static $modules = array('node');
+ public static $modules = ['node'];
/**
* {@inheritdoc}
@@ -27,25 +27,25 @@ class TokenURLTest extends TokenTestBase {
}
function testURLTokens() {
- $url = new Url('entity.node.canonical', array('node' => 1));
- $tokens = array(
+ $url = new Url('entity.node.canonical', ['node' => 1]);
+ $tokens = [
'absolute' => $url->setAbsolute()->toString(),
'relative' => $url->setAbsolute(FALSE)->toString(),
'path' => '/first-node',
- 'brief' => preg_replace(array('!^https?://!', '!/$!'), '', $url->setAbsolute()->toString()),
+ 'brief' => preg_replace(['!^https?://!', '!/$!'], '', $url->setAbsolute()->toString()),
'args:value:0' => 'first-node',
'args:value:1' => NULL,
'args:value:N' => NULL,
'unaliased' => $url->setAbsolute()->setOption('alias', TRUE)->toString(),
'unaliased:relative' => $url->setAbsolute(FALSE)->setOption('alias', TRUE)->toString(),
'unaliased:path' => '/node/1',
- 'unaliased:brief' => preg_replace(array('!^https?://!', '!/$!'), '', $url->setAbsolute()->setOption('alias', TRUE)->toString()),
+ 'unaliased:brief' => preg_replace(['!^https?://!', '!/$!'], '', $url->setAbsolute()->setOption('alias', TRUE)->toString()),
'unaliased:args:value:0' => 'node',
'unaliased:args:value:1' => '1',
'unaliased:args:value:2' => NULL,
// Deprecated tokens.
'alias' => '/first-node',
- );
- $this->assertTokens('url', array('url' => new Url('entity.node.canonical', array('node' => 1))), $tokens);
+ ];
+ $this->assertTokens('url', ['url' => new Url('entity.node.canonical', ['node' => 1])], $tokens);
}
}
diff --git a/sites/all/modules/contrib/dev/token/src/Tests/TokenUserTest.php b/sites/all/modules/contrib/dev/token/src/Tests/TokenUserTest.php
index 476b22a6b..cb3203470 100644
--- a/sites/all/modules/contrib/dev/token/src/Tests/TokenUserTest.php
+++ b/sites/all/modules/contrib/dev/token/src/Tests/TokenUserTest.php
@@ -2,6 +2,7 @@
namespace Drupal\token\Tests;
+use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\AnonymousUserSession;
use Drupal\field\Entity\FieldStorageConfig;
@@ -24,7 +25,7 @@ class TokenUserTest extends TokenTestBase {
*
* @var array
*/
- public static $modules = array('token_user_picture');
+ public static $modules = ['token_user_picture'];
/**
* {@inheritdoc}
@@ -32,10 +33,17 @@ class TokenUserTest extends TokenTestBase {
public function setUp() {
parent::setUp();
- $this->account = $this->drupalCreateUser(['administer users', 'administer account settings', 'access content']);
+ $this->account = $this->drupalCreateUser([
+ 'administer users',
+ 'administer account settings',
+ 'access content',
+ ]);
$this->drupalLogin($this->account);
}
+ /**
+ * Tests the user releated tokens.
+ */
public function testUserTokens() {
// Enable user pictures.
\Drupal::state()->set('user_pictures', 1);
@@ -49,7 +57,7 @@ class TokenUserTest extends TokenTestBase {
// Add a user picture to the account.
$image = current($this->drupalGetTestFiles('image'));
- $edit = array('files[user_picture_0]' => drupal_realpath($image->uri));
+ $edit = ['files[user_picture_0]' => \Drupal::service('file_system')->realpath($image->uri)];
$this->drupalPostForm('user/' . $this->account->id() . '/edit', $edit, t('Save'));
$storage = \Drupal::entityTypeManager()->getStorage('user');
@@ -65,14 +73,14 @@ class TokenUserTest extends TokenTestBase {
];
/** @var \Drupal\Core\Render\RendererInterface $renderer */
$renderer = \Drupal::service('renderer');
- $user_tokens = array(
+ $user_tokens = [
'picture' => $renderer->renderPlain($picture),
'picture:fid' => $this->account->user_picture->target_id,
'picture:size-raw' => 125,
'ip-address' => NULL,
'roles' => implode(', ', $this->account->getRoles()),
- );
- $this->assertTokens('user', array('user' => $this->account), $user_tokens);
+ ];
+ $this->assertTokens('user', ['user' => $this->account], $user_tokens);
// Remove the simpletest-created user role.
$roles = $this->account->getRoles();
@@ -84,29 +92,32 @@ class TokenUserTest extends TokenTestBase {
$storage->resetCache();
$this->account = $storage->load($this->account->id());
- $user_tokens = array(
+ $user_tokens = [
'picture' => NULL,
'picture:fid' => NULL,
'ip-address' => NULL,
'roles' => 'authenticated',
- 'roles:keys' => (string) DRUPAL_AUTHENTICATED_RID,
- );
- $this->assertTokens('user', array('user' => $this->account), $user_tokens);
+ 'roles:keys' => AccountInterface::AUTHENTICATED_ROLE,
+ ];
+ $this->assertTokens('user', ['user' => $this->account], $user_tokens);
// The ip address token should work for the current user token type.
- $tokens = array(
+ $tokens = [
'ip-address' => \Drupal::request()->getClientIp(),
- );
- $this->assertTokens('current-user', array(), $tokens);
+ ];
+ $this->assertTokens('current-user', [], $tokens);
$anonymous = new AnonymousUserSession();
- $tokens = array(
+ $tokens = [
'roles' => 'anonymous',
- 'roles:keys' => (string) DRUPAL_ANONYMOUS_RID,
- );
- $this->assertTokens('user', array('user' => $anonymous), $tokens);
+ 'roles:keys' => AccountInterface::ANONYMOUS_ROLE,
+ ];
+ $this->assertTokens('user', ['user' => $anonymous], $tokens);
}
+ /**
+ * Test user account settings.
+ */
public function testUserAccountSettings() {
$this->drupalGet('admin/config/people/accounts');
$this->assertText('The list of available tokens that can be used in e-mails is provided below.');
diff --git a/sites/all/modules/contrib/dev/token/src/Tests/Tree/TreeTest.php b/sites/all/modules/contrib/dev/token/src/Tests/Tree/TreeTest.php
index ed1dd3cad..7c7243476 100644
--- a/sites/all/modules/contrib/dev/token/src/Tests/Tree/TreeTest.php
+++ b/sites/all/modules/contrib/dev/token/src/Tests/Tree/TreeTest.php
@@ -137,7 +137,7 @@ class TreeTest extends TokenTestBase {
protected function getTokenTreeUrl($options = []) {
$this->drupalGet('token_module_test/browse');
$this->assertTitle('Available Tokens | Drupal');
- $links = $this->xpath('//a[contains(@href, :href)]/@href', array(':href' => 'token/tree'));
+ $links = $this->xpath('//a[contains(@href, :href)]/@href', [':href' => 'token/tree']);
$link = $this->getAbsoluteUrl((string) current($links));
if (!empty($options)) {
$options = Json::encode($options);
diff --git a/sites/all/modules/contrib/dev/token/src/Token.php b/sites/all/modules/contrib/dev/token/src/Token.php
index 360ae351c..b75af5ab2 100644
--- a/sites/all/modules/contrib/dev/token/src/Token.php
+++ b/sites/all/modules/contrib/dev/token/src/Token.php
@@ -65,9 +65,9 @@ class Token extends TokenBase implements TokenInterface {
}
$this->tokenInfo = $token_info;
- $this->cache->set($cache_id, $this->tokenInfo, CacheBackendInterface::CACHE_PERMANENT, array(
+ $this->cache->set($cache_id, $this->tokenInfo, CacheBackendInterface::CACHE_PERMANENT, [
static::TOKEN_INFO_CACHE_TAG,
- ));
+ ]);
}
}
@@ -136,7 +136,7 @@ class Token extends TokenBase implements TokenInterface {
*/
function getInvalidTokens($type, $tokens) {
$token_info = $this->getInfo();
- $invalid_tokens = array();
+ $invalid_tokens = [];
foreach ($tokens as $token => $full_token) {
if (isset($token_info['tokens'][$type][$token])) {
@@ -162,7 +162,7 @@ class Token extends TokenBase implements TokenInterface {
}
else {
// Recursively check the chained tokens.
- $sub_tokens = $this->findWithPrefix(array($token => $full_token), $parts[0]);
+ $sub_tokens = $this->findWithPrefix([$token => $full_token], $parts[0]);
$invalid_tokens = array_merge($invalid_tokens, $this->getInvalidTokens($sub_token_info['type'], $sub_tokens));
}
}
@@ -184,7 +184,7 @@ class Token extends TokenBase implements TokenInterface {
$valid_types = array_merge($valid_types, $this->getGlobalTokenTypes());
}
- $invalid_tokens = array();
+ $invalid_tokens = [];
$value_tokens = is_string($value) ? $this->scan($value) : $value;
foreach ($value_tokens as $type => $tokens) {
diff --git a/sites/all/modules/contrib/dev/token/src/TreeBuilder.php b/sites/all/modules/contrib/dev/token/src/TreeBuilder.php
index 80ebca235..8e58ba330 100644
--- a/sites/all/modules/contrib/dev/token/src/TreeBuilder.php
+++ b/sites/all/modules/contrib/dev/token/src/TreeBuilder.php
@@ -61,12 +61,12 @@ class TreeBuilder implements TreeBuilderInterface {
$token_types = array_merge($token_types, $this->tokenService->getGlobalTokenTypes());
}
- $element = array(
- /*'#cache' => array(
- 'cid' => 'tree-rendered:' . hash('sha256', serialize(array('token_types' => $token_types, 'global_types' => NULL) + $variables)),
- 'tags' => array(Token::TOKEN_INFO_CACHE_TAG),
- ),*/
- );
+ $element = [
+ /*'#cache' => [
+ 'cid' => 'tree-rendered:' . hash('sha256', serialize(['token_types' => $token_types, 'global_types' => NULL] + $variables)),
+ 'tags' => [Token::TOKEN_INFO_CACHE_TAG],
+ ],*/
+ ];
// @todo Find a way to use the render cache for this.
/*if ($cached_output = token_render_cache_get($element)) {
diff --git a/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/test_views/views.view.token_views_test.yml b/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/test_views/views.view.token_views_test.yml
new file mode 100644
index 000000000..eeb150b0d
--- /dev/null
+++ b/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/test_views/views.view.token_views_test.yml
@@ -0,0 +1,130 @@
+langcode: en
+status: true
+dependencies:
+ module:
+ - user
+id: token_views_test
+label: token_views_test
+module: views
+description: ''
+tag: ''
+base_table: users_field_data
+base_field: uid
+core: 8.x
+display:
+ default:
+ display_plugin: default
+ id: default
+ display_title: Master
+ position: 0
+ display_options:
+ access:
+ type: none
+ options: { }
+ cache:
+ type: tag
+ options: { }
+ query:
+ type: views_query
+ options:
+ disable_sql_rewrite: false
+ distinct: false
+ replica: false
+ query_comment: ''
+ query_tags: { }
+ exposed_form:
+ type: basic
+ options:
+ submit_button: Apply
+ reset_button: false
+ reset_button_label: Reset
+ exposed_sorts_label: 'Sort by'
+ expose_sort_order: true
+ sort_asc_label: Asc
+ sort_desc_label: Desc
+ pager:
+ type: some
+ options:
+ items_per_page: 5
+ offset: 0
+ style:
+ type: default
+ row:
+ type: fields
+ options:
+ default_field_elements: true
+ inline: { }
+ separator: ''
+ hide_empty: false
+ fields:
+ name:
+ id: name
+ table: users_field_data
+ field: name
+ entity_type: user
+ entity_field: name
+ label: ''
+ alter:
+ alter_text: false
+ make_link: false
+ absolute: false
+ trim: false
+ word_boundary: false
+ ellipsis: false
+ strip_tags: false
+ html: false
+ hide_empty: false
+ empty_zero: false
+ plugin_id: field
+ relationship: none
+ group_type: group
+ admin_label: ''
+ exclude: false
+ element_type: ''
+ element_class: ''
+ element_label_type: ''
+ element_label_class: ''
+ element_label_colon: true
+ element_wrapper_type: ''
+ element_wrapper_class: ''
+ element_default_classes: true
+ empty: ''
+ hide_alter_empty: true
+ click_sort_column: value
+ type: user_name
+ settings: { }
+ group_column: value
+ group_columns: { }
+ group_rows: true
+ delta_limit: 0
+ delta_offset: 0
+ delta_reversed: false
+ delta_first_last: false
+ multi_type: separator
+ separator: ', '
+ field_api_classes: false
+ filters: { }
+ sorts: { }
+ title: token_views_test
+ header: { }
+ footer: { }
+ empty: { }
+ relationships: { }
+ arguments: { }
+ display_extenders: { }
+ filter_groups:
+ operator: AND
+ groups: { }
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_content'
+ - 'languages:language_interface'
+ tags: { }
+ block_1:
+ display_plugin: block
+ id: block_1
+ display_title: Block
+ position: 1
+ display_options:
+ display_extenders: { }
diff --git a/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.info.yml b/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.info.yml
index 0735ad560..134c18ce5 100644
--- a/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.info.yml
+++ b/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.info.yml
@@ -5,8 +5,8 @@ package: Testing
# core: 8.x
hidden: TRUE
-# Information added by Drupal.org packaging script on 2017-12-20
-version: '8.x-1.1'
+# Information added by Drupal.org packaging script on 2018-09-08
+version: '8.x-1.4'
core: '8.x'
project: 'token'
-datestamp: 1513810387
+datestamp: 1536408485
diff --git a/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.module b/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.module
index c26332075..c022b6575 100644
--- a/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.module
+++ b/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.module
@@ -4,14 +4,15 @@
* @file
* Helper module for token tests.
*/
+
use Drupal\node\NodeInterface;
/**
* Implements hook_page_attachments().
*/
function token_module_test_page_attachments() {
- if ($debug = \Drupal::state()->get('token_page_tokens', array())) {
- $debug += array('tokens' => array(), 'data' => array(), 'options' => array());
+ if ($debug = \Drupal::state()->get('token_page_tokens', [])) {
+ $debug += ['tokens' => [], 'data' => [], 'options' => []];
foreach (array_keys($debug['tokens']) as $token) {
$debug['values'][$token] = \Drupal::token()->replace($token, $debug['data'], $debug['options']);
}
diff --git a/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.tokens.inc b/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.tokens.inc
index ba8da5344..3adf45781 100644
--- a/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.tokens.inc
+++ b/sites/all/modules/contrib/dev/token/tests/modules/token_module_test/token_module_test.tokens.inc
@@ -4,10 +4,10 @@
* Implements hook_token_info()
*/
function token_module_test_token_info() {
- $info['tokens']['node']['colons:in:name'] = array(
+ $info['tokens']['node']['colons:in:name'] = [
'name' => t('A test token with colons in the name'),
'description' => NULL,
- );
+ ];
return $info;
}
diff --git a/sites/all/modules/contrib/dev/token/tests/modules/token_user_picture/token_user_picture.info.yml b/sites/all/modules/contrib/dev/token/tests/modules/token_user_picture/token_user_picture.info.yml
index 55c7ef424..8c168d25a 100644
--- a/sites/all/modules/contrib/dev/token/tests/modules/token_user_picture/token_user_picture.info.yml
+++ b/sites/all/modules/contrib/dev/token/tests/modules/token_user_picture/token_user_picture.info.yml
@@ -7,8 +7,8 @@ hidden: TRUE
dependencies:
- image
-# Information added by Drupal.org packaging script on 2017-12-20
-version: '8.x-1.1'
+# Information added by Drupal.org packaging script on 2018-09-08
+version: '8.x-1.4'
core: '8.x'
project: 'token'
-datestamp: 1513810387
+datestamp: 1536408485
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Functional/UrlTest.php b/sites/all/modules/contrib/dev/token/tests/src/Functional/UrlTest.php
new file mode 100644
index 000000000..0ae2788d8
--- /dev/null
+++ b/sites/all/modules/contrib/dev/token/tests/src/Functional/UrlTest.php
@@ -0,0 +1,137 @@
+ 'article', 'name' => 'Article']);
+ $node_type->save();
+
+ $this->node1 = Node::create([
+ 'type' => 'article',
+ 'title' => 'Test Node 1',
+ ]);
+ $this->node1->save();
+
+ $this->node2 = Node::create([
+ 'type' => 'article',
+ 'title' => 'Test Node 2',
+ ]);
+ $this->node2->save();
+
+ }
+
+ /**
+ * Creates a block with token for title and tests cache contexts.
+ *
+ * @throws \Behat\Mink\Exception\ElementHtmlException
+ * @throws \Drupal\Core\Entity\EntityStorageException
+ */
+ public function testBlockUrlTokenReplacement() {
+
+ $node1_url = $this->node1->toUrl();
+ $node2_url = $this->node2->toUrl();
+
+ // Using a @dataprovider causes repeated database installations and takes a
+ // very long time.
+ $tests = [];
+ $tests[] = [
+ 'token' => 'prefix_[current-page:url:path]_suffix',
+ 'expected1' => 'prefix_/' . $node1_url->getInternalPath() . '_suffix',
+ 'expected2' => 'prefix_/' . $node2_url->getInternalPath() . '_suffix',
+ // A path can only be generated from a routed path.
+ 'expected3' => 'prefix_/_suffix',
+ ];
+ $tests[] = [
+ 'token' => 'prefix_[current-page:url]_suffix',
+ 'expected1' => 'prefix_' . $node1_url->setAbsolute()->toString() . '_suffix',
+ 'expected2' => 'prefix_' . $node2_url->setAbsolute()->toString() . '_suffix',
+ 'expected3' => 'prefix_' . $this->getAbsoluteUrl('does-not-exist') . '_suffix',
+ ];
+
+ // Place a standard block and use a token in the label.
+ $edit = [
+ 'id' => 'token_url_test_block',
+ 'label' => 'label',
+ 'label_display' => TRUE,
+ ];
+ $this->placeBlock('system_powered_by_block', $edit);
+ $block = Block::load('token_url_test_block');
+
+ $assert_session = $this->assertSession();
+
+ foreach ($tests as $test) {
+ // Set the block label.
+ $block->getPlugin()->setConfigurationValue('label', $test['token']);
+ $block->save();
+
+ // Go to the first node page and test that the token is correct.
+ $this->drupalGet($node1_url);
+ $assert_session->elementContains('css', '#block-token-url-test-block', $test['expected1']);
+
+ // Go to the second node page and check that the block title has changed.
+ $this->drupalGet($node2_url);
+ $assert_session->elementContains('css', '#block-token-url-test-block', $test['expected2']);
+
+ // Test the current page url on a 404 page.
+ $this->drupalGet('does-not-exist');
+ $assert_session->statusCodeEquals(404);
+ $assert_session->elementContains('css', '#block-token-url-test-block', $test['expected3']);
+ }
+
+
+ // Can't do this test in the for loop above, it's too different.
+ $block->getPlugin()->setConfigurationValue('label', 'prefix_[current-page:query:unicorns]_suffix');
+ $block->save();
+
+ // Test the parameter token.
+ $this->drupalGet($node1_url->setOption('query', ['unicorns' => 'fluffy']));
+ $this->assertCacheContext('url.query_args');
+ $assert_session->elementContains('css', '#block-token-url-test-block', 'prefix_fluffy_suffix');
+
+ // Change the parameter on the same page.
+ $this->drupalGet($node1_url->setOption('query', ['unicorns' => 'dead']));
+ $assert_session->elementContains('css', '#block-token-url-test-block', 'prefix_dead_suffix');
+ }
+
+}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/ArrayTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/ArrayTest.php
index a7f83ae4d..d484835b5 100644
--- a/sites/all/modules/contrib/dev/token/tests/src/Kernel/ArrayTest.php
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/ArrayTest.php
@@ -11,8 +11,8 @@ class ArrayTest extends KernelTestBase {
function testArrayTokens() {
// Test a simple array.
- $array = array(0 => 'a', 1 => 'b', 2 => 'c', 4 => 'd');
- $tokens = array(
+ $array = [0 => 'a', 1 => 'b', 2 => 'c', 4 => 'd'];
+ $tokens = [
'first' => 'a',
'last' => 'd',
'value:0' => 'a',
@@ -27,19 +27,19 @@ class ArrayTest extends KernelTestBase {
'join' => 'abcd',
'join:, ' => 'a, b, c, d',
'join: ' => 'a b c d',
- );
- $this->assertTokens('array', array('array' => $array), $tokens);
+ ];
+ $this->assertTokens('array', ['array' => $array], $tokens);
// Test a mixed simple and render array.
// 2 => c, 0 => a, 4 => d, 1 => b
- $array = array(
+ $array = [
'#property' => 'value',
0 => 'a',
- 1 => array('#markup' => 'b', '#weight' => 0.01),
- 2 => array('#markup' => 'c', '#weight' => -10),
- 4 => array('#markup' => 'd', '#weight' => 0),
- );
- $tokens = array(
+ 1 => ['#markup' => 'b', '#weight' => 0.01],
+ 2 => ['#markup' => 'c', '#weight' => -10],
+ 4 => ['#markup' => 'd', '#weight' => 0],
+ ];
+ $tokens = [
'first' => 'c',
'last' => 'b',
'value:0' => 'a',
@@ -54,7 +54,8 @@ class ArrayTest extends KernelTestBase {
'join' => 'cadb',
'join:, ' => 'c, a, d, b',
'join: ' => 'c a d b',
- );
- $this->assertTokens('array', array('array' => $array), $tokens);
+ ];
+ $this->assertTokens('array', ['array' => $array], $tokens);
}
+
}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/BookTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/BookTest.php
index 67a13eecd..215fdb54e 100644
--- a/sites/all/modules/contrib/dev/token/tests/src/Kernel/BookTest.php
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/BookTest.php
@@ -27,9 +27,9 @@ class BookTest extends KernelTestBase {
$this->installEntitySchema('user');
$this->installEntitySchema('node');
- $this->installSchema('book', array('book'));
- $this->installSchema('node', array('node_access'));
- $this->installConfig(array('node', 'book', 'field'));
+ $this->installSchema('book', ['book']);
+ $this->installSchema('node', ['node_access']);
+ $this->installConfig(['node', 'book', 'field']);
}
function testBookTokens() {
@@ -63,12 +63,12 @@ class BookTest extends KernelTestBase {
'book:root' => $book_title,
'book:root:nid' => $book->id(),
'book:root:title' => $book_title,
- 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(),
+ 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
'book:root:content-type' => 'Book page',
'book:parent' => null,
'book:parents' => null,
];
- $this->assertTokens('node', array('node' => $book), $tokens);
+ $this->assertTokens('node', ['node' => $book], $tokens);
$tokens = [
'nid' => $page1->id(),
@@ -77,15 +77,15 @@ class BookTest extends KernelTestBase {
'book:root' => $book_title,
'book:root:nid' => $book->id(),
'book:root:title' => $book_title,
- 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(),
+ 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
'book:root:content-type' => 'Book page',
'book:parent:nid' => $book->id(),
'book:parent:title' => $book_title,
- 'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(),
+ 'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
'book:parents:count' => 1,
'book:parents:join:/' => $book_title,
];
- $this->assertTokens('node', array('node' => $page1), $tokens);
+ $this->assertTokens('node', ['node' => $page1], $tokens);
$tokens = [
'nid' => $page2->id(),
@@ -94,14 +94,15 @@ class BookTest extends KernelTestBase {
'book:root' => $book_title,
'book:root:nid' => $book->id(),
'book:root:title' => $book_title,
- 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], array('absolute' => TRUE))->toString(),
+ 'book:root:url' => Url::fromRoute('entity.node.canonical', ['node' => $book->id()], ['absolute' => TRUE])->toString(),
'book:root:content-type' => 'Book page',
'book:parent:nid' => $page1->id(),
'book:parent:title' => $page1->getTitle(),
- 'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $page1->id()], array('absolute' => TRUE))->toString(),
+ 'book:parent:url' => Url::fromRoute('entity.node.canonical', ['node' => $page1->id()], ['absolute' => TRUE])->toString(),
'book:parents:count' => 2,
'book:parents:join:/' => $book_title . '/' . $page1->getTitle(),
];
- $this->assertTokens('node', array('node' => $page2), $tokens);
+ $this->assertTokens('node', ['node' => $page2], $tokens);
}
+
}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/CommentTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/CommentTest.php
index 890d18e25..63232c11f 100644
--- a/sites/all/modules/contrib/dev/token/tests/src/Kernel/CommentTest.php
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/CommentTest.php
@@ -64,14 +64,14 @@ class CommentTest extends KernelTestBase {
// Fix http://example.com/index.php/comment/1 fails 'url:path' test.
$parent_comment_path = $parent_comment->url();
- $tokens = array(
- 'url' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
- 'url:absolute' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
- 'url:relative' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->toString(),
+ $tokens = [
+ 'url' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
+ 'url:absolute' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
+ 'url:relative' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->toString(),
'url:path' => $parent_comment_path,
'parent:url:absolute' => NULL,
- );
- $this->assertTokens('comment', array('comment' => $parent_comment), $tokens);
+ ];
+ $this->assertTokens('comment', ['comment' => $parent_comment], $tokens);
$comment = Comment::create([
'entity_id' => $node->id(),
@@ -86,16 +86,16 @@ class CommentTest extends KernelTestBase {
$comment->save();
// Fix http://example.com/index.php/comment/1 fails 'url:path' test.
- $comment_path = Url::fromRoute('entity.comment.canonical', array('comment' => $comment->id()))->toString();
+ $comment_path = Url::fromRoute('entity.comment.canonical', ['comment' => $comment->id()])->toString();
- $tokens = array(
- 'url' => $comment->urlInfo('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(),
- 'url:absolute' => $comment->urlInfo('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(),
- 'url:relative' => $comment->urlInfo('canonical', ['fragment' => "comment-{$comment->id()}"])->toString(),
+ $tokens = [
+ 'url' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(),
+ 'url:absolute' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->setAbsolute()->toString(),
+ 'url:relative' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])->toString(),
'url:path' => $comment_path,
- 'parent:url:absolute' => $parent_comment->urlInfo('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
- );
- $this->assertTokens('comment', array('comment' => $comment), $tokens);
+ 'parent:url:absolute' => $parent_comment->toUrl('canonical', ['fragment' => "comment-{$parent_comment->id()}"])->setAbsolute()->toString(),
+ ];
+ $this->assertTokens('comment', ['comment' => $comment], $tokens);
}
}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/DateTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/DateTest.php
index c25bf030d..c120e1109 100644
--- a/sites/all/modules/contrib/dev/token/tests/src/Kernel/DateTest.php
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/DateTest.php
@@ -25,11 +25,12 @@ class DateTest extends KernelTestBase {
}
function testDateTokens() {
- $tokens = array(
+ $tokens = [
'token_module_test' => '1984',
'invalid_format' => NULL,
- );
+ ];
- $this->assertTokens('date', array('date' => 453859200), $tokens);
+ $this->assertTokens('date', ['date' => 453859200], $tokens);
}
+
}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/EntityTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/EntityTest.php
index 7ff471dfe..caf575bc6 100644
--- a/sites/all/modules/contrib/dev/token/tests/src/Kernel/EntityTest.php
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/EntityTest.php
@@ -2,8 +2,8 @@
namespace Drupal\Tests\token\Kernel;
-use Drupal\Component\Utility\Unicode;
use Drupal\node\Entity\Node;
+use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\taxonomy\VocabularyInterface;
@@ -55,20 +55,21 @@ class EntityTest extends KernelTestBase {
$this->assertIdentical($mapper->getTokenTypeForEntityType('invalid'), FALSE);
$this->assertIdentical($mapper->getTokenTypeForEntityType('invalid', TRUE), 'invalid');
- // Test that when we send the mis-matched entity type into token_replace()
- // that we still get the tokens replaced.
- $vocabulary = entity_load('taxonomy_vocabulary', 'tags');
+ // Test that when we send the mis-matched entity type into
+ // Drupal\Core\Utility\Token::replace() that we still get the tokens
+ // replaced.
+ $vocabulary = Vocabulary::load('tags');
$term = $this->addTerm($vocabulary);
- $this->assertIdentical(\Drupal::token()->replace('[vocabulary:name]', array('taxonomy_vocabulary' => $vocabulary)), $vocabulary->label());
- $this->assertIdentical(\Drupal::token()->replace('[term:name][term:vocabulary:name]', array('taxonomy_term' => $term)), $term->label() . $vocabulary->label());
+ $this->assertIdentical(\Drupal::token()->replace('[vocabulary:name]', ['taxonomy_vocabulary' => $vocabulary]), $vocabulary->label());
+ $this->assertIdentical(\Drupal::token()->replace('[term:name][term:vocabulary:name]', ['taxonomy_term' => $term]), $term->label() . $vocabulary->label());
}
- function addTerm(VocabularyInterface $vocabulary, array $term = array()) {
- $term += array(
- 'name' => Unicode::strtolower($this->randomMachineName(5)),
+ function addTerm(VocabularyInterface $vocabulary, array $term = []) {
+ $term += [
+ 'name' => mb_strtolower($this->randomMachineName(5)),
'vid' => $vocabulary->id(),
- );
- $term = entity_create('taxonomy_term', $term);
+ ];
+ $term = Term::create($term);
$term->save();
return $term;
}
@@ -80,25 +81,26 @@ class EntityTest extends KernelTestBase {
$node = Node::create(['type' => 'page', 'title' => 'Original title']);
$node->save();
- $tokens = array(
+ $tokens = [
'nid' => $node->id(),
'title' => 'Original title',
'original' => NULL,
'original:nid' => NULL,
- );
- $this->assertTokens('node', array('node' => $node), $tokens);
+ ];
+ $this->assertTokens('node', ['node' => $node], $tokens);
// Emulate the original entity property that would be available from
// node_save() and change the title for the node.
- $node->original = entity_load_unchanged('node', $node->id());
+ $node->original = \Drupal::entityTypeManager()->getStorage('node')->loadUnchanged($node->id());
$node->title = 'New title';
- $tokens = array(
+ $tokens = [
'nid' => $node->id(),
'title' => 'New title',
'original' => 'Original title',
'original:nid' => $node->id(),
- );
- $this->assertTokens('node', array('node' => $node), $tokens);
+ ];
+ $this->assertTokens('node', ['node' => $node], $tokens);
}
+
}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/FileTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/FileTest.php
index 3a6a7fd64..6cfa98875 100644
--- a/sites/all/modules/contrib/dev/token/tests/src/Kernel/FileTest.php
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/FileTest.php
@@ -2,6 +2,7 @@
namespace Drupal\Tests\token\Kernel;
+use Drupal\file\Entity\File;
/**
* Tests file tokens.
*
@@ -14,7 +15,7 @@ class FileTest extends KernelTestBase {
*
* @var array
*/
- public static $modules = array('file');
+ public static $modules = ['file'];
/**
* {@inheritdoc}
@@ -26,30 +27,31 @@ class FileTest extends KernelTestBase {
function testFileTokens() {
// Create a test file object.
- $file = entity_create('file', array(
+ $file = File::create([
'fid' => 1,
'filename' => 'test.png',
'filesize' => 100,
'uri' => 'public://images/test.png',
'filemime' => 'image/png',
- ));
+ ]);
- $tokens = array(
+ $tokens = [
'basename' => 'test.png',
'extension' => 'png',
'size-raw' => 100,
- );
- $this->assertTokens('file', array('file' => $file), $tokens);
+ ];
+ $this->assertTokens('file', ['file' => $file], $tokens);
// Test a file with no extension and a fake name.
$file->filename = 'Test PNG image';
$file->uri = 'public://images/test';
- $tokens = array(
+ $tokens = [
'basename' => 'test',
'extension' => '',
'size-raw' => 100,
- );
- $this->assertTokens('file', array('file' => $file), $tokens);
+ ];
+ $this->assertTokens('file', ['file' => $file], $tokens);
}
+
}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/NodeTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/NodeTest.php
index e44b9abd0..846961a4d 100644
--- a/sites/all/modules/contrib/dev/token/tests/src/Kernel/NodeTest.php
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/NodeTest.php
@@ -48,52 +48,53 @@ class NodeTest extends KernelTestBase {
'type' => 'page',
'title' => 'Source Title',
'revision_log' => $this->randomMachineName(),
- 'path' => array('alias' => '/content/source-node')
+ 'path' => ['alias' => '/content/source-node']
]);
$page->save();
- $tokens = array(
+ $tokens = [
'log' => $page->revision_log->value,
'url:path' => '/content/source-node',
- 'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], array('absolute' => TRUE))->toString(),
- 'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], array('absolute' => FALSE))->toString(),
+ 'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], ['absolute' => TRUE])->toString(),
+ 'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $page->id()], ['absolute' => FALSE])->toString(),
'url:unaliased:path' => "/node/{$page->id()}",
'content-type' => 'Basic page',
'content-type:name' => 'Basic page',
'content-type:machine-name' => 'page',
'content-type:description' => "Use basic pages for your static content, such as an 'About us' page.",
'content-type:node-count' => 1,
- 'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'page'], array('absolute' => TRUE))->toString(),
+ 'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'page'], ['absolute' => TRUE])->toString(),
'source:title' => 'Source Title',
// Deprecated tokens.
'type' => 'page',
'type-name' => 'Basic page',
'url:alias' => '/content/source-node',
- );
- $this->assertTokens('node', array('node' => $page), $tokens);
+ ];
+ $this->assertTokens('node', ['node' => $page], $tokens);
$article = Node::create([
'type' => 'article',
'title' => 'Source Title',
]);
$article->save();
- $tokens = array(
+ $tokens = [
'log' => '',
'url:path' => "/node/{$article->id()}",
- 'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], array('absolute' => TRUE))->toString(),
- 'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], array('absolute' => FALSE))->toString(),
+ 'url:absolute' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], ['absolute' => TRUE])->toString(),
+ 'url:relative' => Url::fromRoute('entity.node.canonical', ['node' => $article->id()], ['absolute' => FALSE])->toString(),
'url:unaliased:path' => "/node/{$article->id()}",
'content-type' => 'Article',
'content-type:name' => 'Article',
'content-type:machine-name' => 'article',
'content-type:description' => "Use articles for time-sensitive content like news, press releases or blog posts.",
'content-type:node-count' => 1,
- 'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'article'], array('absolute' => TRUE))->toString(),
+ 'content-type:edit-url' => Url::fromRoute('entity.node_type.edit_form', ['node_type' => 'article'], ['absolute' => TRUE])->toString(),
'source:title' => 'Source Title',
// Deprecated tokens.
'type' => 'article',
'type-name' => 'Article',
'url:alias' => "/node/{$article->id()}",
- );
- $this->assertTokens('node', array('node' => $article), $tokens);
+ ];
+ $this->assertTokens('node', ['node' => $article], $tokens);
}
+
}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/RandomTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/RandomTest.php
index a4b09303d..5162846ce 100644
--- a/sites/all/modules/contrib/dev/token/tests/src/Kernel/RandomTest.php
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/RandomTest.php
@@ -10,18 +10,19 @@ namespace Drupal\Tests\token\Kernel;
class RandomTest extends KernelTestBase {
function testRandomTokens() {
- $tokens = array(
+ $tokens = [
'number' => '[0-9]{1,}',
'hash:md5' => '[0-9a-f]{32}',
'hash:sha1' => '[0-9a-f]{40}',
'hash:sha256' => '[0-9a-f]{64}',
'hash:invalid-algo' => NULL,
- );
+ ];
- $first_set = $this->assertTokens('random', array(), $tokens, array('regex' => TRUE));
- $second_set = $this->assertTokens('random', array(), $tokens, array('regex' => TRUE));
+ $first_set = $this->assertTokens('random', [], $tokens, ['regex' => TRUE]);
+ $second_set = $this->assertTokens('random', [], $tokens, ['regex' => TRUE]);
foreach ($first_set as $token => $value) {
$this->assertNotIdentical($first_set[$token], $second_set[$token]);
}
}
+
}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/TaxonomyTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/TaxonomyTest.php
index 73274df08..abc99ea4d 100644
--- a/sites/all/modules/contrib/dev/token/tests/src/Kernel/TaxonomyTest.php
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/TaxonomyTest.php
@@ -2,7 +2,7 @@
namespace Drupal\Tests\token\Kernel;
-use Drupal\Component\Utility\Unicode;
+use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Core\Url;
@@ -13,6 +13,7 @@ use Drupal\Core\Url;
* @group token
*/
class TaxonomyTest extends KernelTestBase {
+
protected $vocab;
/**
@@ -20,7 +21,7 @@ class TaxonomyTest extends KernelTestBase {
*
* @var array
*/
- public static $modules = array('taxonomy', 'text', 'language');
+ public static $modules = ['taxonomy', 'text', 'language'];
/**
* {@inheritdoc}
@@ -43,31 +44,31 @@ class TaxonomyTest extends KernelTestBase {
* Test the additional taxonomy term tokens.
*/
function testTaxonomyTokens() {
- $root_term = $this->addTerm($this->vocab, array('name' => 'Root term', 'path' => array('alias' => '/root-term')));
- $tokens = array(
- 'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], array('absolute' => TRUE))->toString(),
- 'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], array('absolute' => TRUE))->toString(),
- 'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], array('absolute' => FALSE))->toString(),
+ $root_term = $this->addTerm($this->vocab, ['name' => 'Root term', 'path' => ['alias' => '/root-term']]);
+ $tokens = [
+ 'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(),
+ 'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(),
+ 'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $root_term->id()], ['absolute' => FALSE])->toString(),
'url:path' => '/root-term',
'url:unaliased:path' => "/taxonomy/term/{$root_term->id()}",
- 'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $root_term->id()], array('absolute' => TRUE))->toString(),
+ 'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $root_term->id()], ['absolute' => TRUE])->toString(),
'parents' => NULL,
'parents:count' => NULL,
'parents:keys' => NULL,
'root' => NULL,
// Deprecated tokens
'url:alias' => '/root-term',
- );
- $this->assertTokens('term', array('term' => $root_term), $tokens);
+ ];
+ $this->assertTokens('term', ['term' => $root_term], $tokens);
- $parent_term = $this->addTerm($this->vocab, array('name' => 'Parent term', 'parent' => $root_term->id()));
- $tokens = array(
- 'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], array('absolute' => TRUE))->toString(),
- 'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], array('absolute' => TRUE))->toString(),
- 'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], array('absolute' => FALSE))->toString(),
+ $parent_term = $this->addTerm($this->vocab, ['name' => 'Parent term', 'parent' => $root_term->id()]);
+ $tokens = [
+ 'url' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(),
+ 'url:absolute' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(),
+ 'url:relative' => Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $parent_term->id()], ['absolute' => FALSE])->toString(),
'url:path' => "/taxonomy/term/{$parent_term->id()}",
'url:unaliased:path' => "/taxonomy/term/{$parent_term->id()}",
- 'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $parent_term->id()], array('absolute' => TRUE))->toString(),
+ 'edit-url' => Url::fromRoute('entity.taxonomy_term.edit_form', ['taxonomy_term' => $parent_term->id()], ['absolute' => TRUE])->toString(),
'parents' => 'Root term',
'parents:count' => 1,
'parents:keys' => $root_term->id(),
@@ -75,16 +76,16 @@ class TaxonomyTest extends KernelTestBase {
'root:tid' => $root_term->id(),
// Deprecated tokens
'url:alias' => "/taxonomy/term/{$parent_term->id()}",
- );
- $this->assertTokens('term', array('term' => $parent_term), $tokens);
+ ];
+ $this->assertTokens('term', ['term' => $parent_term], $tokens);
- $term = $this->addTerm($this->vocab, array('name' => 'Test term', 'parent' => $parent_term->id()));
- $tokens = array(
+ $term = $this->addTerm($this->vocab, ['name' => 'Test term', 'parent' => $parent_term->id()]);
+ $tokens = [
'parents' => 'Root term, Parent term',
'parents:count' => 2,
- 'parents:keys' => implode(', ', array($root_term->id(), $parent_term->id())),
- );
- $this->assertTokens('term', array('term' => $term), $tokens);
+ 'parents:keys' => implode(', ', [$root_term->id(), $parent_term->id()]),
+ ];
+ $this->assertTokens('term', ['term' => $term], $tokens);
}
/**
@@ -92,28 +93,28 @@ class TaxonomyTest extends KernelTestBase {
*/
function testVocabularyTokens() {
$vocabulary = $this->vocab;
- $tokens = array(
+ $tokens = [
'machine-name' => 'tags',
- 'edit-url' => Url::fromRoute('entity.taxonomy_vocabulary.edit_form', ['taxonomy_vocabulary' => $vocabulary->id()], array('absolute' => TRUE))->toString(),
- );
- $this->assertTokens('vocabulary', array('vocabulary' => $vocabulary), $tokens);
+ 'edit-url' => Url::fromRoute('entity.taxonomy_vocabulary.edit_form', ['taxonomy_vocabulary' => $vocabulary->id()], ['absolute' => TRUE])->toString(),
+ ];
+ $this->assertTokens('vocabulary', ['vocabulary' => $vocabulary], $tokens);
}
- function addVocabulary(array $vocabulary = array()) {
- $vocabulary += array(
- 'name' => Unicode::strtolower($this->randomMachineName(5)),
- 'nodes' => array('article' => 'article'),
- );
- $vocabulary = entity_create('taxonomy_vocabulary', $vocabulary)->save();
+ function addVocabulary(array $vocabulary = []) {
+ $vocabulary += [
+ 'name' => mb_strtolower($this->randomMachineName(5)),
+ 'nodes' => ['article' => 'article'],
+ ];
+ $vocabulary = Vocabulary::create($vocabulary)->save();
return $vocabulary;
}
- function addTerm($vocabulary, array $term = array()) {
- $term += array(
- 'name' => Unicode::strtolower($this->randomMachineName(5)),
+ function addTerm($vocabulary, array $term = []) {
+ $term += [
+ 'name' => mb_strtolower($this->randomMachineName(5)),
'vid' => $vocabulary->id(),
- );
- $term = entity_create('taxonomy_term', $term);
+ ];
+ $term = Term::create($term);
$term->save();
return $term;
}
@@ -146,6 +147,8 @@ class TaxonomyTest extends KernelTestBase {
])->save();
// Expect the parent term to be in the specified language.
- $this->assertTokens('term', array('term' => $child_term), ['parents' => 'german-parent-term'], ['langcode' => 'de']);
+ $this->assertTokens('term', ['term' => $child_term], ['parents' => 'german-parent-term'], ['langcode' => 'de']);
+ $this->assertTokens('term', ['term' => $child_term], ['root' => 'german-parent-term'], ['langcode' => 'de']);
}
+
}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/UnitTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/UnitTest.php
index c91f19433..c031e6bfb 100644
--- a/sites/all/modules/contrib/dev/token/tests/src/Kernel/UnitTest.php
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/UnitTest.php
@@ -33,9 +33,9 @@ class UnitTest extends KernelTestBase {
* Test invalid tokens.
*/
public function testGetInvalidTokens() {
- $tests = array();
- $tests[] = array(
- 'valid tokens' => array(
+ $tests = [];
+ $tests[] = [
+ 'valid tokens' => [
'[node:title]',
'[node:created:short]',
'[node:created:custom:invalid]',
@@ -46,8 +46,8 @@ class UnitTest extends KernelTestBase {
'[current-date:short]',
'[current-user:uid]',
'[current-user:ip-address]',
- ),
- 'invalid tokens' => array(
+ ],
+ 'invalid tokens' => [
'[node:title:invalid]',
'[node:created:invalid]',
'[node:created:short:invalid]',
@@ -62,11 +62,11 @@ class UnitTest extends KernelTestBase {
'[node:type]',
'[node:type-name]',
'[date:short]',
- ),
- 'types' => array('node'),
- );
- $tests[] = array(
- 'valid tokens' => array(
+ ],
+ 'types' => ['node'],
+ ];
+ $tests[] = [
+ 'valid tokens' => [
'[node:title]',
'[node:created:short]',
'[node:created:custom:invalid]',
@@ -77,8 +77,8 @@ class UnitTest extends KernelTestBase {
'[user:uid]',
'[current-date:short]',
'[current-user:uid]',
- ),
- 'invalid tokens' => array(
+ ],
+ 'invalid tokens' => [
'[node:title:invalid]',
'[node:created:invalid]',
'[node:created:short:invalid]',
@@ -91,9 +91,9 @@ class UnitTest extends KernelTestBase {
'[node:tnid]',
'[node:type]',
'[node:type-name]',
- ),
- 'types' => array('all'),
- );
+ ],
+ 'types' => ['all'],
+ ];
foreach ($tests as $test) {
$tokens = array_merge($test['valid tokens'], $test['invalid tokens']);
@@ -116,4 +116,5 @@ class UnitTest extends KernelTestBase {
$this->assertNull($this->tokenService->getTokenInfo('user_role', 'url'));
$this->assertNull($this->tokenService->getTypeInfo('user_role'));
}
+
}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/UrlTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/UrlTest.php
new file mode 100644
index 000000000..1464095d0
--- /dev/null
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/UrlTest.php
@@ -0,0 +1,88 @@
+token = $this->container->get('token');
+ $this->requestStack = $this->container->get('request_stack');
+ $this->currentRouteMatch = $this->container->get('current_route_match');
+ }
+
+ /**
+ * Test the url token replacements for current requests.
+ *
+ * The method ::expectedCurrentRequestUrlResults() is not declared
+ * as a regular data provider, because it might use services from
+ * the global Drupal container, which is not initialized yet during
+ * the invocation of data providers.
+ */
+ public function testCurrentRequestUrls() {
+ foreach ($this->expectedCurrentRequestUrlResults() as $data_set) {
+ list ($request, $text, $data, $options, $expected_output) = $data_set;
+ // Set the request as the current one.
+ $this->requestStack->pop();
+ $this->requestStack->push($request);
+ $this->currentRouteMatch->resetRouteMatch();
+
+ $this->assertEquals($expected_output, $this->token->replace($text, $data, $options));
+ }
+ }
+
+ /**
+ * Provides a list of results to expect for ::testRequestUrls().
+ *
+ * Each data set of this array holds the following order:
+ * - The request object to test for.
+ * - The input text as string.
+ * - The token data as array.
+ * - Further options for the token replacement as array.
+ * - The output to expect after token replacement.
+ *
+ * @return array
+ * The list of results to expect.
+ */
+ public function expectedCurrentRequestUrlResults() {
+ return [
+ [Request::createFromGlobals(), '[current-page:url]', [], [], Url::createFromRequest(Request::createFromGlobals())->setAbsolute()->toString()],
+ [Request::create('/should-not-exist'), '[current-page:url:path]', [], [], '/'],
+ [Request::create('/https://drupal.org/'), '[current-page:url:absolute]', [], [], '[current-page:url:absolute]'],
+ [Request::create('/https://drupal.org/'), '[current-page:url:absolute]', [], ['clear' => TRUE], ''],
+ ];
+ }
+
+}
diff --git a/sites/all/modules/contrib/dev/token/tests/src/Kernel/ViewsTest.php b/sites/all/modules/contrib/dev/token/tests/src/Kernel/ViewsTest.php
new file mode 100644
index 000000000..884e4fcb4
--- /dev/null
+++ b/sites/all/modules/contrib/dev/token/tests/src/Kernel/ViewsTest.php
@@ -0,0 +1,50 @@
+installEntitySchema('user');
+ ViewTestData::createTestViews(get_class($this), ['token_module_test']);
+ }
+
+ /**
+ * Tests path token replacements generated from a view without a path.
+ */
+ public function testTokenReplacementNoPath() {
+ $token_handler = \Drupal::token();
+ $view = Views::getView('token_views_test');
+ $view->setDisplay('block_1');
+ $view->execute();
+
+ $this->assertSame('', $token_handler->replace('[view:url]', ['view' => $view]), 'Token [view:url] is empty for views without path.');
+ }
+
+}
diff --git a/sites/all/modules/contrib/dev/token/token.info.yml b/sites/all/modules/contrib/dev/token/token.info.yml
index 97125553a..8d93be36f 100644
--- a/sites/all/modules/contrib/dev/token/token.info.yml
+++ b/sites/all/modules/contrib/dev/token/token.info.yml
@@ -2,9 +2,11 @@ type: module
name: Token
description: Provides a user interface for the Token API and some missing core tokens.
# core: 8.x
+dependencies:
+ - drupal:system (>= 8.5)
-# Information added by Drupal.org packaging script on 2017-12-20
-version: '8.x-1.1'
+# Information added by Drupal.org packaging script on 2018-09-08
+version: '8.x-1.4'
core: '8.x'
project: 'token'
-datestamp: 1513810387
+datestamp: 1536408485
diff --git a/sites/all/modules/contrib/dev/token/token.install b/sites/all/modules/contrib/dev/token/token.install
index 664b1af5c..39af20004 100644
--- a/sites/all/modules/contrib/dev/token/token.install
+++ b/sites/all/modules/contrib/dev/token/token.install
@@ -9,7 +9,7 @@
* Implements hook_requirements().
*/
function token_requirements($phase = 'runtime') {
- $requirements = array();
+ $requirements = [];
if ($phase == 'runtime') {
// Check for various token definition problems.
@@ -24,11 +24,11 @@ function token_requirements($phase = 'runtime') {
'#items' => $problems,
];
- $requirements['token-' . $problem_key] = array(
+ $requirements['token-' . $problem_key] = [
'title' => $problem['label'],
'value' => \Drupal::service('renderer')->renderPlain($build),
'severity' => $problem['severity'],
- );
+ ];
}
}
}
@@ -51,12 +51,12 @@ function token_install() {
$storage = \Drupal::entityTypeManager()->getStorage('entity_view_mode');
// Add a token view mode if it does not already exist.
if (!$storage->load("$entity_type.token")) {
- $storage->create(array(
+ $storage->create([
'targetEntityType' => $entity_type,
'id' => "$entity_type.token",
'status' => TRUE,
'label' => t('Token'),
- ))->save();
+ ])->save();
}
}
}
@@ -65,7 +65,7 @@ function token_install() {
* Build a list of Drupal 6 tokens and their Drupal 7 token names.
*/
function _token_upgrade_token_list() {
- $tokens = array(
+ $tokens = [
// Global tokens
'user-name' => 'current-user:name',
'user-id' => 'current-user:id',
@@ -142,7 +142,7 @@ function _token_upgrade_token_list() {
//'date-in-tz' => '',
'account-url' => 'user:url',
'account-edit' => 'user:edit-url',
- );
+ ];
// Account for date tokens which need to be expanded.
$tokens += _token_upgrade_token_date_list('site-', 'site:date');
@@ -160,8 +160,8 @@ function _token_upgrade_token_list() {
* Build a list of Drupal 6 date tokens and their Drupal 7 token names.
*/
function _token_upgrade_token_date_list($old_token, $new_token) {
- $tokens = array();
- $formats = array(
+ $tokens = [];
+ $formats = [
'yyyy' => 'Y',
'yy' => 'y',
'month' => 'F',
@@ -174,7 +174,7 @@ function _token_upgrade_token_date_list($old_token, $new_token) {
'ddd' => 'D',
'dd' => 'd',
'd' => 'j',
- );
+ ];
foreach ($formats as $token_format => $date_format) {
$tokens[$old_token . $token_format] = "$new_token:custom:$date_format";
}
@@ -198,7 +198,7 @@ function _token_upgrade_token_date_list($old_token, $new_token) {
*
* @see _token_upgrade_token_list()
*/
-function token_update_token_text($text, $updates = array(), $leading = '[', $trailing = ']') {
+function token_update_token_text($text, $updates = [], $leading = '[', $trailing = ']') {
$updates += _token_upgrade_token_list();
$regex = '/' . preg_quote($leading, '/') . '([^\s]*)' . preg_quote($trailing, '/') . '/';
preg_match_all($regex, $text, $matches);
@@ -220,7 +220,7 @@ function token_update_token_text($text, $updates = array(), $leading = '[', $tra
*/
function token_get_token_problems() {
// @todo Improve the duplicate checking to report which modules are the offenders.
- //$token_info = array();
+ //$token_info = [];
//foreach (module_implements('token_info') as $module) {
// $module_token_info = module_invoke($module, 'token_info');
// if (in_array($module, _token_core_supported_modules())) {
@@ -230,7 +230,7 @@ function token_get_token_problems() {
// if (is_array($module_token_info['types'])) {
// foreach (array_keys($module_token_info['types']) as $type) {
// if (is_array($module_token_info['types'][$type])) {
- // $module_token_info['types'][$type] += array('module' => $module);
+ // $module_token_info['types'][$type] += ['module' => $module];
// }
// }
// }
@@ -246,28 +246,28 @@ function token_get_token_problems() {
//}
$token_info = \Drupal::token()->getInfo();
- $token_problems = array(
- 'not-array' => array(
+ $token_problems = [
+ 'not-array' => [
'label' => t('Tokens or token types not defined as arrays'),
'severity' => REQUIREMENT_ERROR,
- ),
- 'missing-info' => array(
+ ],
+ 'missing-info' => [
'label' => t('Tokens or token types missing name property'),
'severity' => REQUIREMENT_WARNING,
- ),
- 'type-no-tokens' => array(
+ ],
+ 'type-no-tokens' => [
'label' => t('Token types do not have any tokens defined'),
'severity' => REQUIREMENT_INFO,
- ),
- 'tokens-no-type' => array(
+ ],
+ 'tokens-no-type' => [
'label' => t('Token types are not defined but have tokens'),
'severity' => REQUIREMENT_INFO,
- ),
- 'duplicate' => array(
+ ],
+ 'duplicate' => [
'label' => t('Token or token types are defined by multiple modules'),
'severity' => REQUIREMENT_ERROR,
- ),
- );
+ ],
+ ];
// Check token types for problems.
foreach ($token_info['types'] as $type => $type_info) {
@@ -313,4 +313,4 @@ function token_get_token_problems() {
}
return $token_problems;
-}
\ No newline at end of file
+}
diff --git a/sites/all/modules/contrib/dev/token/token.module b/sites/all/modules/contrib/dev/token/token.module
index 6aa254874..0d4f2cea1 100644
--- a/sites/all/modules/contrib/dev/token/token.module
+++ b/sites/all/modules/contrib/dev/token/token.module
@@ -6,7 +6,6 @@
*/
use Drupal\Component\Render\PlainTextOutput;
-use Drupal\Component\Utility\Unicode;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Menu\MenuLinkInterface;
@@ -47,7 +46,7 @@ function token_help($route_name, RouteMatchInterface $route_match) {
* Return an array of the core modules supported by token.module.
*/
function _token_core_supported_modules() {
- return array('book', 'field', 'menu_ui');
+ return ['book', 'field', 'menu_ui'];
}
/**
@@ -97,9 +96,9 @@ function token_form_block_form_alter(&$form, FormStateInterface $form_state) {
'#token_types' => [],
];
$rendered_token_tree = \Drupal::service('renderer')->render($token_tree);
- $form['settings']['label']['#description'] =
- t('This field supports tokens. @browse_tokens_link', ['@browse_tokens_link' => $rendered_token_tree])
- ;
+ $form['settings']['label']['#description'] = t('This field supports tokens. @browse_tokens_link', [
+ '@browse_tokens_link' => $rendered_token_tree,
+ ]);
$form['settings']['label']['#element_validate'][] = 'token_element_validate';
$form['settings']['label'] += ['#token_types' => []];
}
@@ -108,7 +107,7 @@ function token_form_block_form_alter(&$form, FormStateInterface $form_state) {
* Implements hook_field_info_alter().
*/
function token_field_info_alter(&$info) {
- $defaults = array(
+ $defaults = [
'taxonomy_term_reference' => 'taxonomy_term_reference_plain',
'number_integer' => 'number_unformatted',
'number_decimal' => 'number_unformatted',
@@ -122,10 +121,10 @@ function token_field_info_alter(&$info) {
'list_float' => 'list_default',
'list_string' => 'list_default',
'list_boolean' => 'list_default',
- );
+ ];
foreach ($defaults as $field_type => $default_token_formatter) {
if (isset($info[$field_type])) {
- $info[$field_type] += array('default_token_formatter' => $default_token_formatter);
+ $info[$field_type] += ['default_token_formatter' => $default_token_formatter];
}
}
}
@@ -228,7 +227,7 @@ function token_module_implements_alter(&$implementations, $hook) {
// other modules.
if (isset($implementations['token'])) {
unset($implementations['token']);
- $implementations = array_merge(array('token' => 'tokens'), $implementations);
+ $implementations = array_merge(['token' => 'tokens'], $implementations);
}
}
}
@@ -258,21 +257,21 @@ function _token_module($type, $name) {
*
* For example:
* @code
- * $form['my_node_text_element'] = array(
+ * $form['my_node_text_element'] = [
* '#type' => 'textfield',
* '#title' => t('Some text to token-ize that has a node context.'),
* '#default_value' => 'The title of this node is [node:title].',
- * '#element_validate' => array('token_element_validate'),
- * '#token_types' => array('node'),
+ * '#element_validate' => ['token_element_validate'],
+ * '#token_types' => ['node'],
* '#min_tokens' => 1,
* '#max_tokens' => 10,
- * );
+ * ];
* @endcode
*/
function token_element_validate($element, FormStateInterface $form_state) {
$value = isset($element['#value']) ? $element['#value'] : $element['#default_value'];
- if (!Unicode::strlen($value)) {
+ if (!mb_strlen($value)) {
// Empty value needs no further validation since the element should depend
// on using the '#required' FAPI property.
return $element;
@@ -283,13 +282,13 @@ function token_element_validate($element, FormStateInterface $form_state) {
// Validate if an element must have a minimum number of tokens.
if (isset($element['#min_tokens']) && count($tokens) < $element['#min_tokens']) {
- $error = \Drupal::translation()->formatPlural($element['#min_tokens'], '%name must contain at least one token.', '%name must contain at least @count tokens.', array('%name' => $title));
+ $error = \Drupal::translation()->formatPlural($element['#min_tokens'], '%name must contain at least one token.', '%name must contain at least @count tokens.', ['%name' => $title]);
$form_state->setError($element, $error);
}
// Validate if an element must have a maximum number of tokens.
if (isset($element['#max_tokens']) && count($tokens) > $element['#max_tokens']) {
- $error = \Drupal::translation()->formatPlural($element['#max_tokens'], '%name must contain at most one token.', '%name must contain at most @count tokens.', array('%name' => $title));
+ $error = \Drupal::translation()->formatPlural($element['#max_tokens'], '%name must contain at most one token.', '%name must contain at most @count tokens.', ['%name' => $title]);
$form_state->setError($element, $error);
}
@@ -297,7 +296,7 @@ function token_element_validate($element, FormStateInterface $form_state) {
if (isset($element['#token_types'])) {
$invalid_tokens = \Drupal::token()->getInvalidTokensByContext($tokens, $element['#token_types']);
if ($invalid_tokens) {
- $form_state->setError($element, t('%name is using the following invalid tokens: @invalid-tokens.', array('%name' => $title, '@invalid-tokens' => implode(', ', $invalid_tokens))));
+ $form_state->setError($element, t('%name is using the following invalid tokens: @invalid-tokens.', ['%name' => $title, '@invalid-tokens' => implode(', ', $invalid_tokens)]));
}
}
@@ -320,19 +319,19 @@ function token_form_field_config_edit_form_alter(&$form, FormStateInterface $for
// Date support needs to be implicitly added, as while technically it's not
// a global token, it is a not only used but is the default value.
// https://www.drupal.org/node/2642160
- $form['settings']['file_directory'] += array('#token_types' => array('date'));
+ $form['settings']['file_directory'] += ['#token_types' => ['date']];
$form['settings']['file_directory']['#description'] .= ' ' . t('This field supports tokens.');
}
// Note that the description is tokenized via token_field_widget_form_alter().
$form['description']['#element_validate'][] = 'token_element_validate';
- $form['description'] += array('#token_types' => array());
+ $form['description'] += ['#token_types' => []];
- $form['token_tree'] = array(
+ $form['token_tree'] = [
'#theme' => 'token_tree_link',
- '#token_types' => array(),
+ '#token_types' => [],
'#weight' => $form['description']['#weight'] + 0.5,
- );
+ ];
}
/**
@@ -384,6 +383,7 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s
case 'email_cancel_confirm':
// Do nothing, but allow execution to continue.
break;
+
case 'email_activated':
case 'email_blocked':
case 'email_canceled':
@@ -391,6 +391,7 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s
// sub-element, so switch to that element instead.
$element = &$form[$key]['settings'];
break;
+
default:
continue 2;
}
@@ -402,24 +403,24 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s
elseif ($element[$sub_key]['#type'] == 'textfield' && substr($sub_key, -8) === '_subject') {
// Add validation to subject textfields.
$element[$sub_key]['#element_validate'][] = 'token_element_validate';
- $element[$sub_key] += array('#token_types' => array('user'));
+ $element[$sub_key] += ['#token_types' => ['user']];
}
elseif ($element[$sub_key]['#type'] == 'textarea' && substr($sub_key, -5) === '_body') {
// Add validation to body textareas.
$element[$sub_key]['#element_validate'][] = 'token_element_validate';
- $element[$sub_key] += array('#token_types' => array('user'));
+ $element[$sub_key] += ['#token_types' => ['user']];
}
}
}
// Add the token tree UI.
- $form['email']['token_tree'] = array(
+ $form['email']['token_tree'] = [
'#theme' => 'token_tree_link',
- '#token_types' => array('user'),
+ '#token_types' => ['user'],
'#show_restricted' => TRUE,
'#show_nested' => FALSE,
'#weight' => 90,
- );
+ ];
}
/**
@@ -431,10 +432,10 @@ function token_form_user_admin_settings_alter(&$form, FormStateInterface $form_s
* The cleaned token name.
*/
function token_clean_token_name($name) {
- static $names = array();
+ static $names = [];
if (!isset($names[$name])) {
- $cleaned_name = strtr($name, array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => ''));
+ $cleaned_name = strtr($name, [' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => '']);
$cleaned_name = preg_replace('/[^\w\-]/i', '', $cleaned_name);
$cleaned_name = trim($cleaned_name, '-');
$names[$name] = $cleaned_name;
@@ -446,8 +447,8 @@ function token_clean_token_name($name) {
/**
* Do not use this function yet. Its API has not been finalized.
*/
-function token_render_array(array $array, array $options = array()) {
- $rendered = array();
+function token_render_array(array $array, array $options = []) {
+ $rendered = [];
/** @var \Drupal\Core\Render\RendererInterface $renderer */
$renderer = \Drupal::service('renderer');
@@ -463,7 +464,7 @@ function token_render_array(array $array, array $options = array()) {
/**
* Do not use this function yet. Its API has not been finalized.
*/
-function token_render_array_value($value, array $options = array()) {
+function token_render_array_value($value, array $options = []) {
/** @var \Drupal\Core\Render\RendererInterface $renderer */
$renderer = \Drupal::service('renderer');
@@ -497,7 +498,7 @@ function token_render_cache_get($elements) {
*/
function token_render_cache_set(&$markup, $elements) {
// This should only run of drupal_render_cache_set() did not.
- if (in_array(\Drupal::request()->server->get('REQUEST_METHOD'), array('GET', 'HEAD'))) {
+ if (in_array(\Drupal::request()->server->get('REQUEST_METHOD'), ['GET', 'HEAD'])) {
return FALSE;
}
@@ -519,10 +520,10 @@ function token_render_cache_set(&$markup, $elements) {
* List of menu link parent titles.
*/
function token_menu_link_load_all_parents($plugin_id, $langcode) {
- $cache = &drupal_static(__FUNCTION__, array());
+ $cache = &drupal_static(__FUNCTION__, []);
if (!isset($cache[$plugin_id][$langcode])) {
- $cache[$plugin_id][$langcode] = array();
+ $cache[$plugin_id][$langcode] = [];
/** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */
$menu_link_manager = \Drupal::service('plugin.manager.menu.link');
$parent_ids = $menu_link_manager->getParentIds($plugin_id);
@@ -530,7 +531,7 @@ function token_menu_link_load_all_parents($plugin_id, $langcode) {
unset($parent_ids[$plugin_id]);
foreach ($parent_ids as $parent_id) {
$parent = $menu_link_manager->createInstance($parent_id);
- $cache[$plugin_id][$langcode] = array($parent_id => token_menu_link_translated_title($parent, $langcode)) + $cache[$plugin_id][$langcode];
+ $cache[$plugin_id][$langcode] = [$parent_id => token_menu_link_translated_title($parent, $langcode)] + $cache[$plugin_id][$langcode];
}
}
@@ -577,14 +578,14 @@ function token_menu_link_translated_title(MenuLinkInterface $menu_link, $langcod
* The term parents collection.
*/
function token_taxonomy_term_load_all_parents($tid, $langcode) {
- $cache = &drupal_static(__FUNCTION__, array());
+ $cache = &drupal_static(__FUNCTION__, []);
if (!is_numeric($tid)) {
- return array();
+ return [];
}
if (!isset($cache[$langcode][$tid])) {
- $cache[$langcode][$tid] = array();
+ $cache[$langcode][$tid] = [];
/** @var \Drupal\taxonomy\TermStorageInterface $term_storage */
$term_storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
$parents = $term_storage->loadAllParents($tid);
@@ -605,7 +606,7 @@ function token_element_children(&$elements, $sort = FALSE) {
$sort = isset($elements['#sorted']) ? !$elements['#sorted'] : $sort;
// Filter out properties from the element, leaving only children.
- $children = array();
+ $children = [];
$sortable = FALSE;
foreach ($elements as $key => $value) {
if ($key === '' || $key[0] !== '#') {
@@ -643,15 +644,15 @@ function token_element_children(&$elements, $sort = FALSE) {
* List of node titles of the book parents.
*/
function token_book_load_all_parents(array $book) {
- $cache = &drupal_static(__FUNCTION__, array());
+ $cache = &drupal_static(__FUNCTION__, []);
if (empty($book['nid'])) {
- return array();
+ return [];
}
$nid = $book['nid'];
if (!isset($cache[$nid])) {
- $cache[$nid] = array();
+ $cache[$nid] = [];
$i = 1;
while ($book["p$i"] != $nid) {
$cache[$nid][] = Node::load($book["p$i"])->getTitle();
@@ -666,7 +667,7 @@ function token_book_load_all_parents(array $book) {
* Implements hook_entity_base_field_info().
*/
function token_entity_base_field_info(EntityTypeInterface $entity_type) {
- // We add a psuedo entity-reference field to track the menu entry created
+ // We add a pseudo entity-reference field to track the menu entry created
// from the node add/edit form so that tokens generated at that time that
// reference the menu link can access the yet to be saved menu link.
// @todo Revisit when https://www.drupal.org/node/2315773 is resolved.
@@ -677,14 +678,14 @@ function token_entity_base_field_info(EntityTypeInterface $entity_type) {
->setRevisionable(TRUE)
->setSetting('target_type', 'menu_link_content')
->setTranslatable(TRUE)
- ->setDisplayOptions('view', array(
+ ->setDisplayOptions('view', [
'label' => 'hidden',
'region' => 'hidden',
- ))
+ ])
->setComputed(TRUE)
- ->setDisplayOptions('form', array(
+ ->setDisplayOptions('form', [
'region' => 'hidden',
- ));
+ ]);
return $fields;
}
@@ -744,19 +745,19 @@ function token_node_menu_link_submit($entity_type, NodeInterface $node, &$form,
else {
if ($node->isNew()) {
// Create a new menu_link_content entity.
- $entity = MenuLinkContent::create(array(
+ $entity = MenuLinkContent::create([
// Lets just reference the UUID for now, the link is not important for
// token generation.
'link' => ['uri' => 'internal:/node/' . $node->uuid()],
'langcode' => $node->language()->getId(),
- ));
+ ]);
}
else {
// Create a new menu_link_content entity.
- $entity = MenuLinkContent::create(array(
+ $entity = MenuLinkContent::create([
'link' => ['uri' => 'entity:node/' . $node->id()],
'langcode' => $node->language()->getId(),
- ));
+ ]);
}
}
$entity->title->value = trim($values['title']);
@@ -779,7 +780,7 @@ function token_node_menu_link_submit($entity_type, NodeInterface $node, &$form,
function token_node_insert(NodeInterface $node) {
if ($node->hasField('menu_link') && $menu_link = $node->menu_link->entity) {
// Update the menu-link to point to the now saved node.
- $menu_link->link = 'entity:node/' . $node->id();
+ $menu_link->link = 'entity:node/' . $node->id();
$menu_link->save();
}
}
diff --git a/sites/all/modules/contrib/dev/token/token.pages.inc b/sites/all/modules/contrib/dev/token/token.pages.inc
index 4b92df1f1..0e417343d 100644
--- a/sites/all/modules/contrib/dev/token/token.pages.inc
+++ b/sites/all/modules/contrib/dev/token/token.pages.inc
@@ -53,7 +53,7 @@ function template_preprocess_token_tree_link(&$variables) {
'draggable' => TRUE,
'autoResize' => FALSE,
]),
- ];
+ ];
$variables['link'] = Link::createFromRoute($variables['text'], 'token.tree', [], $variables['options'])->toRenderable();
$variables['url'] = new Url('token.tree', [], $variables['options']);
diff --git a/sites/all/modules/contrib/dev/token/token.tokens.inc b/sites/all/modules/contrib/dev/token/token.tokens.inc
index 950f0ed06..7ee429107 100644
--- a/sites/all/modules/contrib/dev/token/token.tokens.inc
+++ b/sites/all/modules/contrib/dev/token/token.tokens.inc
@@ -4,19 +4,20 @@
* @file
* Token callbacks for the token module.
*/
+
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Entity\TypedData\EntityDataDefinitionInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\Element;
use Drupal\Component\Utility\Crypt;
-use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\Html;
use Drupal\Core\TypedData\DataReferenceDefinitionInterface;
use Drupal\Core\Url;
use Drupal\field\FieldStorageConfigInterface;
use Drupal\menu_link_content\MenuLinkContentInterface;
use Drupal\node\Entity\Node;
+use Drupal\node\Entity\NodeType;
use Drupal\node\NodeInterface;
use Drupal\system\Entity\Menu;
use Drupal\user\UserInterface;
@@ -33,11 +34,11 @@ function token_token_info_alter(&$info) {
// Force 'date' type tokens to require input and add a 'current-date' type.
// @todo Remove when http://drupal.org/node/943028 is fixed.
$info['types']['date']['needs-data'] = 'date';
- $info['types']['current-date'] = array(
+ $info['types']['current-date'] = [
'name' => t('Current date'),
'description' => t('Tokens related to the current date and time.'),
'type' => 'date',
- );
+ ];
// Add a 'dynamic' key to any tokens that have chained but dynamic tokens.
$info['tokens']['date']['custom']['dynamic'] = TRUE;
@@ -87,22 +88,22 @@ function token_token_info_alter(&$info) {
// Add [entity:url] tokens if they do not already exist.
// @todo Support entity:label
if (!isset($info['tokens'][$token_type]['url'])) {
- $info['tokens'][$token_type]['url'] = array(
+ $info['tokens'][$token_type]['url'] = [
'name' => t('URL'),
- 'description' => t('The URL of the @entity.', array('@entity' => Unicode::strtolower($entity_info->getLabel()))),
+ 'description' => t('The URL of the @entity.', ['@entity' => mb_strtolower($entity_info->getLabel())]),
'module' => 'token',
'type' => 'url',
- );
+ ];
}
// Add [entity:original] tokens if they do not already exist.
if (!isset($info['tokens'][$token_type]['original'])) {
- $info['tokens'][$token_type]['original'] = array(
- 'name' => t('Original @entity', array('@entity' => Unicode::strtolower($entity_info->getLabel()))),
- 'description' => t('The original @entity data if the @entity is being updated or saved.', array('@entity' => Unicode::strtolower($entity_info->getLabel()))),
+ $info['tokens'][$token_type]['original'] = [
+ 'name' => t('Original @entity', ['@entity' => mb_strtolower($entity_info->getLabel())]),
+ 'description' => t('The original @entity data if the @entity is being updated or saved.', ['@entity' => mb_strtolower($entity_info->getLabel())]),
'module' => 'token',
'type' => $token_type,
- );
+ ];
}
}
@@ -112,11 +113,11 @@ function token_token_info_alter(&$info) {
foreach ($date_format_types as $date_format_type => $date_format_type_info) {
/* @var \Drupal\system\Entity\DateFormat $date_format_type_info */
if (!isset($info['tokens']['date'][$date_format_type])) {
- $info['tokens']['date'][$date_format_type] = array(
+ $info['tokens']['date'][$date_format_type] = [
'name' => Html::escape($date_format_type_info->label()),
- 'description' => t("A date in '@type' format. (%date)", array('@type' => $date_format_type, '%date' => \Drupal::service('date.formatter')->format(REQUEST_TIME, $date_format_type))),
+ 'description' => t("A date in '@type' format. (%date)", ['@type' => $date_format_type, '%date' => \Drupal::service('date.formatter')->format(\Drupal::time()->getRequestTime(), $date_format_type)]),
'module' => 'token',
- );
+ ];
}
}
}
@@ -126,264 +127,264 @@ function token_token_info_alter(&$info) {
*/
function token_token_info() {
// Node tokens.
- $info['tokens']['node']['source'] = array(
+ $info['tokens']['node']['source'] = [
'name' => t('Translation source node'),
'description' => t("The source node for this current node's translation set."),
'type' => 'node',
- );
- $info['tokens']['node']['log'] = array(
+ ];
+ $info['tokens']['node']['log'] = [
'name' => t('Revision log message'),
'description' => t('The explanation of the most recent changes made to the node.'),
- );
- $info['tokens']['node']['content-type'] = array(
+ ];
+ $info['tokens']['node']['content-type'] = [
'name' => t('Content type'),
'description' => t('The content type of the node.'),
'type' => 'content-type',
- );
+ ];
// Content type tokens.
- $info['types']['content-type'] = array(
+ $info['types']['content-type'] = [
'name' => t('Content types'),
'description' => t('Tokens related to content types.'),
'needs-data' => 'node_type',
- );
- $info['tokens']['content-type']['name'] = array(
+ ];
+ $info['tokens']['content-type']['name'] = [
'name' => t('Name'),
'description' => t('The name of the content type.'),
- );
- $info['tokens']['content-type']['machine-name'] = array(
+ ];
+ $info['tokens']['content-type']['machine-name'] = [
'name' => t('Machine-readable name'),
'description' => t('The unique machine-readable name of the content type.'),
- );
- $info['tokens']['content-type']['description'] = array(
+ ];
+ $info['tokens']['content-type']['description'] = [
'name' => t('Description'),
'description' => t('The optional description of the content type.'),
- );
- $info['tokens']['content-type']['node-count'] = array(
+ ];
+ $info['tokens']['content-type']['node-count'] = [
'name' => t('Node count'),
'description' => t('The number of nodes belonging to the content type.'),
- );
- $info['tokens']['content-type']['edit-url'] = array(
+ ];
+ $info['tokens']['content-type']['edit-url'] = [
'name' => t('Edit URL'),
'description' => t("The URL of the content type's edit page."),
// 'type' => 'url',
- );
+ ];
// Taxonomy term and vocabulary tokens.
if (\Drupal::moduleHandler()->moduleExists('taxonomy')) {
- $info['tokens']['term']['edit-url'] = array(
+ $info['tokens']['term']['edit-url'] = [
'name' => t('Edit URL'),
'description' => t("The URL of the taxonomy term's edit page."),
// 'type' => 'url',
- );
- $info['tokens']['term']['parents'] = array(
+ ];
+ $info['tokens']['term']['parents'] = [
'name' => t('Parents'),
'description' => t("An array of all the term's parents, starting with the root."),
'type' => 'array',
- );
- $info['tokens']['term']['root'] = array(
+ ];
+ $info['tokens']['term']['root'] = [
'name' => t('Root term'),
'description' => t("The root term of the taxonomy term."),
'type' => 'term',
- );
+ ];
- $info['tokens']['vocabulary']['machine-name'] = array(
+ $info['tokens']['vocabulary']['machine-name'] = [
'name' => t('Machine-readable name'),
'description' => t('The unique machine-readable name of the vocabulary.'),
- );
- $info['tokens']['vocabulary']['edit-url'] = array(
+ ];
+ $info['tokens']['vocabulary']['edit-url'] = [
'name' => t('Edit URL'),
'description' => t("The URL of the vocabulary's edit page."),
// 'type' => 'url',
- );
+ ];
}
// File tokens.
- $info['tokens']['file']['basename'] = array(
+ $info['tokens']['file']['basename'] = [
'name' => t('Base name'),
'description' => t('The base name of the file.'),
- );
- $info['tokens']['file']['extension'] = array(
+ ];
+ $info['tokens']['file']['extension'] = [
'name' => t('Extension'),
'description' => t('The extension of the file.'),
- );
- $info['tokens']['file']['size-raw'] = array(
+ ];
+ $info['tokens']['file']['size-raw'] = [
'name' => t('File byte size'),
'description' => t('The size of the file, in bytes.'),
- );
+ ];
// User tokens.
// Add information on the restricted user tokens.
- $info['tokens']['user']['cancel-url'] = array(
+ $info['tokens']['user']['cancel-url'] = [
'name' => t('Account cancellation URL'),
'description' => t('The URL of the confirm delete page for the user account.'),
'restricted' => TRUE,
// 'type' => 'url',
- );
- $info['tokens']['user']['one-time-login-url'] = array(
+ ];
+ $info['tokens']['user']['one-time-login-url'] = [
'name' => t('One-time login URL'),
'description' => t('The URL of the one-time login page for the user account.'),
'restricted' => TRUE,
// 'type' => 'url',
- );
- $info['tokens']['user']['roles'] = array(
+ ];
+ $info['tokens']['user']['roles'] = [
'name' => t('Roles'),
'description' => t('The user roles associated with the user account.'),
'type' => 'array',
- );
+ ];
// Current user tokens.
- $info['tokens']['current-user']['ip-address'] = array(
+ $info['tokens']['current-user']['ip-address'] = [
'name' => t('IP address'),
- 'description' => 'The IP address of the current user.',
- );
+ 'description' => t('The IP address of the current user.'),
+ ];
// Menu link tokens (work regardless if menu module is enabled or not).
- $info['types']['menu-link'] = array(
+ $info['types']['menu-link'] = [
'name' => t('Menu links'),
'description' => t('Tokens related to menu links.'),
'needs-data' => 'menu-link',
- );
- $info['tokens']['menu-link']['mlid'] = array(
+ ];
+ $info['tokens']['menu-link']['mlid'] = [
'name' => t('Link ID'),
'description' => t('The unique ID of the menu link.'),
- );
- $info['tokens']['menu-link']['title'] = array(
+ ];
+ $info['tokens']['menu-link']['title'] = [
'name' => t('Title'),
'description' => t('The title of the menu link.'),
- );
- $info['tokens']['menu-link']['url'] = array(
+ ];
+ $info['tokens']['menu-link']['url'] = [
'name' => t('URL'),
'description' => t('The URL of the menu link.'),
'type' => 'url',
- );
- $info['tokens']['menu-link']['parent'] = array(
+ ];
+ $info['tokens']['menu-link']['parent'] = [
'name' => t('Parent'),
'description' => t("The menu link's parent."),
'type' => 'menu-link',
- );
- $info['tokens']['menu-link']['parents'] = array(
+ ];
+ $info['tokens']['menu-link']['parents'] = [
'name' => t('Parents'),
'description' => t("An array of all the menu link's parents, starting with the root."),
'type' => 'array',
- );
- $info['tokens']['menu-link']['root'] = array(
+ ];
+ $info['tokens']['menu-link']['root'] = [
'name' => t('Root'),
'description' => t("The menu link's root."),
'type' => 'menu-link',
- );
+ ];
// Current page tokens.
- $info['types']['current-page'] = array(
+ $info['types']['current-page'] = [
'name' => t('Current page'),
'description' => t('Tokens related to the current page request.'),
- );
- $info['tokens']['current-page']['title'] = array(
+ ];
+ $info['tokens']['current-page']['title'] = [
'name' => t('Title'),
'description' => t('The title of the current page.'),
- );
- $info['tokens']['current-page']['url'] = array(
+ ];
+ $info['tokens']['current-page']['url'] = [
'name' => t('URL'),
'description' => t('The URL of the current page.'),
'type' => 'url',
- );
- $info['tokens']['current-page']['page-number'] = array(
+ ];
+ $info['tokens']['current-page']['page-number'] = [
'name' => t('Page number'),
'description' => t('The page number of the current page when viewing paged lists.'),
- );
- $info['tokens']['current-page']['query'] = array(
+ ];
+ $info['tokens']['current-page']['query'] = [
'name' => t('Query string value'),
'description' => t('The value of a specific query string field of the current page.'),
'dynamic' => TRUE,
- );
+ ];
// URL tokens.
- $info['types']['url'] = array(
+ $info['types']['url'] = [
'name' => t('URL'),
'description' => t('Tokens related to URLs.'),
'needs-data' => 'path',
- );
- $info['tokens']['url']['path'] = array(
+ ];
+ $info['tokens']['url']['path'] = [
'name' => t('Path'),
'description' => t('The path component of the URL.'),
- );
- $info['tokens']['url']['relative'] = array(
+ ];
+ $info['tokens']['url']['relative'] = [
'name' => t('Relative URL'),
'description' => t('The relative URL.'),
- );
- $info['tokens']['url']['absolute'] = array(
+ ];
+ $info['tokens']['url']['absolute'] = [
'name' => t('Absolute URL'),
'description' => t('The absolute URL.'),
- );
- $info['tokens']['url']['brief'] = array(
+ ];
+ $info['tokens']['url']['brief'] = [
'name' => t('Brief URL'),
'description' => t('The URL without the protocol and trailing backslash.'),
- );
- $info['tokens']['url']['unaliased'] = array(
+ ];
+ $info['tokens']['url']['unaliased'] = [
'name' => t('Unaliased URL'),
'description' => t('The unaliased URL.'),
'type' => 'url',
- );
- $info['tokens']['url']['args'] = array(
+ ];
+ $info['tokens']['url']['args'] = [
'name' => t('Arguments'),
'description' => t("The specific argument of the current page (e.g. 'arg:1' on the page 'node/1' returns '1')."),
'type' => 'array',
- );
+ ];
// Array tokens.
- $info['types']['array'] = array(
+ $info['types']['array'] = [
'name' => t('Array'),
'description' => t('Tokens related to arrays of strings.'),
'needs-data' => 'array',
'nested' => TRUE,
- );
- $info['tokens']['array']['first'] = array(
+ ];
+ $info['tokens']['array']['first'] = [
'name' => t('First'),
'description' => t('The first element of the array.'),
- );
- $info['tokens']['array']['last'] = array(
+ ];
+ $info['tokens']['array']['last'] = [
'name' => t('Last'),
'description' => t('The last element of the array.'),
- );
- $info['tokens']['array']['count'] = array(
+ ];
+ $info['tokens']['array']['count'] = [
'name' => t('Count'),
'description' => t('The number of elements in the array.'),
- );
- $info['tokens']['array']['reversed'] = array(
+ ];
+ $info['tokens']['array']['reversed'] = [
'name' => t('Reversed'),
'description' => t('The array reversed.'),
'type' => 'array',
- );
- $info['tokens']['array']['keys'] = array(
+ ];
+ $info['tokens']['array']['keys'] = [
'name' => t('Keys'),
'description' => t('The array of keys of the array.'),
'type' => 'array',
- );
- $info['tokens']['array']['join'] = array(
+ ];
+ $info['tokens']['array']['join'] = [
'name' => t('Imploded'),
'description' => t('The values of the array joined together with a custom string in-between each value.'),
'dynamic' => TRUE,
- );
- $info['tokens']['array']['value'] = array(
+ ];
+ $info['tokens']['array']['value'] = [
'name' => t('Value'),
'description' => t('The specific value of the array.'),
'dynamic' => TRUE,
- );
+ ];
// Random tokens.
- $info['types']['random'] = array(
+ $info['types']['random'] = [
'name' => t('Random'),
'description' => t('Tokens related to random data.'),
- );
- $info['tokens']['random']['number'] = array(
+ ];
+ $info['tokens']['random']['number'] = [
'name' => t('Number'),
- 'description' => t('A random number from 0 to @max.', array('@max' => mt_getrandmax())),
- );
- $info['tokens']['random']['hash'] = array(
+ 'description' => t('A random number from 0 to @max.', ['@max' => mt_getrandmax()]),
+ ];
+ $info['tokens']['random']['hash'] = [
'name' => t('Hash'),
- 'description' => t('A random hash. The possible hashing algorithms are: @hash-algos.', array('@hash-algos' => implode(', ', hash_algos()))),
+ 'description' => t('A random hash. The possible hashing algorithms are: @hash-algos.', ['@hash-algos' => implode(', ', hash_algos())]),
'dynamic' => TRUE,
- );
+ ];
// Define image_with_image_style token type.
if (\Drupal::moduleHandler()->moduleExists('image')) {
@@ -427,10 +428,10 @@ function token_token_info() {
/**
* Implements hook_tokens().
*/
-function token_tokens($type, array $tokens, array $data = array(), array $options = array(), BubbleableMetadata $bubbleable_metadata) {
- $replacements = array();
+function token_tokens($type, array $tokens, array $data = [], array $options = [], BubbleableMetadata $bubbleable_metadata) {
+ $replacements = [];
$language_manager = \Drupal::languageManager();
- $url_options = array('absolute' => TRUE);
+ $url_options = ['absolute' => TRUE];
if (isset($options['langcode'])) {
$url_options['language'] = $language_manager->getLanguage($options['langcode']);
$langcode = $options['langcode'];
@@ -441,7 +442,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// Date tokens.
if ($type == 'date') {
- $date = !empty($data['date']) ? $data['date'] : REQUEST_TIME;
+ $date = !empty($data['date']) ? $data['date'] : \Drupal::time()->getRequestTime();
// @todo Remove when http://drupal.org/node/1173706 is fixed.
$date_format_types = \Drupal::entityTypeManager()->getStorage('date_format')->loadMultiple();
@@ -455,7 +456,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// Current date tokens.
// @todo Remove when http://drupal.org/node/943028 is fixed.
if ($type == 'current-date') {
- $replacements += \Drupal::token()->generate('date', $tokens, array('date' => REQUEST_TIME), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('date', $tokens, ['date' => \Drupal::time()->getRequestTime()], $options, $bubbleable_metadata);
}
// Comment tokens.
@@ -466,7 +467,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// Chained token relationships.
if (($url_tokens = \Drupal::token()->findWithPrefix($tokens, 'url'))) {
// Add fragment to url options.
- $replacements += \Drupal::token()->generate('url', $url_tokens, array('url' => $comment->urlInfo('canonical', ['fragment' => "comment-{$comment->id()}"])), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('url', $url_tokens, ['url' => $comment->toUrl('canonical', ['fragment' => "comment-{$comment->id()}"])], $options, $bubbleable_metadata);
}
}
@@ -480,6 +481,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
case 'log':
$replacements[$original] = (string) $node->revision_log->value;
break;
+
case 'content-type':
$type_name = \Drupal::entityTypeManager()->getStorage('node_type')->load($node->getType())->label();
$replacements[$original] = $type_name;
@@ -489,13 +491,13 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// Chained token relationships.
if (($parent_tokens = \Drupal::token()->findWithPrefix($tokens, 'source')) && $source_node = $node->getUntranslated()) {
- $replacements += \Drupal::token()->generate('node', $parent_tokens, array('node' => $source_node), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('node', $parent_tokens, ['node' => $source_node], $options, $bubbleable_metadata);
}
- if (($node_type_tokens = \Drupal::token()->findWithPrefix($tokens, 'content-type')) && $node_type = node_type_load($node->bundle())) {
- $replacements += \Drupal::token()->generate('content-type', $node_type_tokens, array('node_type' => $node_type), $options, $bubbleable_metadata);
+ if (($node_type_tokens = \Drupal::token()->findWithPrefix($tokens, 'content-type')) && $node_type = NodeType::load($node->bundle())) {
+ $replacements += \Drupal::token()->generate('content-type', $node_type_tokens, ['node_type' => $node_type], $options, $bubbleable_metadata);
}
if (($url_tokens = \Drupal::token()->findWithPrefix($tokens, 'url'))) {
- $replacements += \Drupal::token()->generate('url', $url_tokens, array('url' => $node->urlInfo()), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('url', $url_tokens, ['url' => $node->toUrl()], $options, $bubbleable_metadata);
}
}
@@ -509,12 +511,15 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
case 'name':
$replacements[$original] = $node_type->label();
break;
+
case 'machine-name':
$replacements[$original] = $node_type->id();
break;
+
case 'description':
$replacements[$original] = $node_type->getDescription();
break;
+
case 'node-count':
$count = \Drupal::entityQueryAggregate('node')
->aggregate('nid', 'COUNT')
@@ -522,8 +527,9 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
->execute();
$replacements[$original] = (int) $count;
break;
+
case 'edit-url':
- $replacements[$original] = $node_type->url('edit-form', $url_options);
+ $replacements[$original] = $node_type->toUrl('edit-form', $url_options)->toString();
break;
}
}
@@ -553,6 +559,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
$parents = $term_storage->loadAllParents($term->id());
$root_term = end($parents);
if ($root_term->id() != $term->id()) {
+ $root_term = \Drupal::service('entity.repository')->getTranslationFromContext($root_term, $langcode);
$replacements[$original] = $root_term->label();
}
break;
@@ -561,19 +568,19 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// Chained token relationships.
if (($url_tokens = \Drupal::token()->findWithPrefix($tokens, 'url'))) {
- $replacements += \Drupal::token()->generate('url', $url_tokens, array('url' => $term->urlInfo()), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('url', $url_tokens, ['url' => $term->toUrl()], $options, $bubbleable_metadata);
}
// [term:parents:*] chained tokens.
if ($parents_tokens = \Drupal::token()->findWithPrefix($tokens, 'parents')) {
if ($parents = token_taxonomy_term_load_all_parents($term->id(), $langcode)) {
- $replacements += \Drupal::token()->generate('array', $parents_tokens, array('array' => $parents), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('array', $parents_tokens, ['array' => $parents], $options, $bubbleable_metadata);
}
}
if ($root_tokens = \Drupal::token()->findWithPrefix($tokens, 'root')) {
$parents = $term_storage->loadAllParents($term->id());
$root_term = end($parents);
if ($root_term->tid != $term->id()) {
- $replacements += \Drupal::token()->generate('term', $root_tokens, array('term' => $root_term), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('term', $root_tokens, ['term' => $root_term], $options, $bubbleable_metadata);
}
}
}
@@ -587,6 +594,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
case 'machine-name':
$replacements[$original] = $vocabulary->id();
break;
+
case 'edit-url':
$replacements[$original] = Url::fromRoute('entity.taxonomy_vocabulary.edit_form', ['taxonomy_vocabulary' => $vocabulary->id()], $url_options)->toString();
break;
@@ -604,10 +612,12 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
$basename = pathinfo($file->uri->value, PATHINFO_BASENAME);
$replacements[$original] = $basename;
break;
+
case 'extension':
$extension = pathinfo($file->uri->value, PATHINFO_EXTENSION);
$replacements[$original] = $extension;
break;
+
case 'size-raw':
$replacements[$original] = (int) $file->filesize->value;
break;
@@ -644,15 +654,15 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// Chained token relationships.
if ($account instanceof UserInterface && $account->hasField('user_picture') && ($picture_tokens = \Drupal::token()->findWithPrefix($tokens, 'picture'))) {
- $replacements += \Drupal::token()->generate('file', $picture_tokens, array('file' => $account->user_picture->entity), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('file', $picture_tokens, ['file' => $account->user_picture->entity], $options, $bubbleable_metadata);
}
if ($url_tokens = \Drupal::token()->findWithPrefix($tokens, 'url')) {
- $replacements += \Drupal::token()->generate('url', $url_tokens, array('url' => $account->urlInfo()), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('url', $url_tokens, ['url' => $account->toUrl()], $options, $bubbleable_metadata);
}
if ($role_tokens = \Drupal::token()->findWithPrefix($tokens, 'roles')) {
$roles = $account->getRoles();
$roles_names = array_combine($roles, $roles);
- $replacements += \Drupal::token()->generate('array', $role_tokens, array('array' => $roles_names), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('array', $role_tokens, ['array' => $roles_names], $options, $bubbleable_metadata);
}
}
@@ -684,24 +694,28 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
case 'id':
$replacements[$original] = $link->getPluginId();
break;
+
case 'title':
$replacements[$original] = token_menu_link_translated_title($link, $langcode);
break;
+
case 'url':
$replacements[$original] = $link->getUrlObject()->setAbsolute()->toString();
break;
- case 'parent':
+ case 'parent':
/** @var \Drupal\Core\Menu\MenuLinkInterface $parent */
if ($link->getParent() && $parent = $menu_link_manager->createInstance($link->getParent())) {
$replacements[$original] = token_menu_link_translated_title($parent, $langcode);
}
break;
+
case 'parents':
if ($parents = token_menu_link_load_all_parents($link->getPluginId(), $langcode)) {
$replacements[$original] = token_render_array($parents, $options);
}
break;
+
case 'root';
if ($link->getParent() && $parent_ids = array_keys(token_menu_link_load_all_parents($link->getPluginId(), $langcode))) {
$root = $menu_link_manager->createInstance(array_shift($parent_ids));
@@ -714,41 +728,59 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// Chained token relationships.
/** @var \Drupal\Core\Menu\MenuLinkInterface $parent */
if ($link->getParent() && ($parent_tokens = \Drupal::token()->findWithPrefix($tokens, 'parent')) && $parent = $menu_link_manager->createInstance($link->getParent())) {
- $replacements += \Drupal::token()->generate('menu-link', $parent_tokens, array('menu-link' => $parent), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('menu-link', $parent_tokens, ['menu-link' => $parent], $options, $bubbleable_metadata);
}
// [menu-link:parents:*] chained tokens.
if ($parents_tokens = \Drupal::token()->findWithPrefix($tokens, 'parents')) {
if ($parents = token_menu_link_load_all_parents($link->getPluginId(), $langcode)) {
- $replacements += \Drupal::token()->generate('array', $parents_tokens, array('array' => $parents), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('array', $parents_tokens, ['array' => $parents], $options, $bubbleable_metadata);
}
}
if (($root_tokens = \Drupal::token()->findWithPrefix($tokens, 'root')) && $link->getParent() && $parent_ids = array_keys(token_menu_link_load_all_parents($link->getPluginId(), $langcode))) {
$root = $menu_link_manager->createInstance(array_shift($parent_ids));
- $replacements += \Drupal::token()->generate('menu-link', $root_tokens, array('menu-link' => $root), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('menu-link', $root_tokens, ['menu-link' => $root], $options, $bubbleable_metadata);
}
if ($url_tokens = \Drupal::token()->findWithPrefix($tokens, 'url')) {
- $replacements += \Drupal::token()->generate('url', $url_tokens, array('url' => $link->getUrlObject()), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('url', $url_tokens, ['url' => $link->getUrlObject()], $options, $bubbleable_metadata);
}
}
// Current page tokens.
if ($type == 'current-page') {
+ $request = \Drupal::request();
foreach ($tokens as $name => $original) {
switch ($name) {
case 'title':
- $request = \Drupal::request();
$route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT);
if ($route) {
$title = \Drupal::service('title_resolver')->getTitle($request, $route);
$replacements[$original] = token_render_array_value($title);
}
break;
+
case 'url':
- $replacements[$original] = Url::fromRoute('', [], $url_options)->toString();
+ $bubbleable_metadata->addCacheContexts(['url.path']);
+ try {
+ $url = Url::createFromRequest($request)->setOptions($url_options);
+ }
+ catch (\Exception $e) {
+ // Url::createFromRequest() can fail, e.g. on 404 pages.
+ // Fall back and try again with Url::fromUserInput().
+ try {
+ $url = Url::fromUserInput($request->getPathInfo(), $url_options);
+ }
+ catch (\Exception $e) {
+ // Instantiation would fail again on malformed urls.
+ }
+ }
+ if (isset($url)) {
+ $replacements[$original] = $url->toString();
+ }
break;
+
case 'page-number':
- if ($page = \Drupal::request()->query->get('page')) {
+ if ($page = $request->query->get('page')) {
// @see PagerDefault::execute()
$pager_page_array = explode(',', $page);
$page = $pager_page_array[0];
@@ -774,6 +806,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// [current-page:query] dynamic tokens.
if ($query_tokens = \Drupal::token()->findWithPrefix($tokens, 'query')) {
+ $bubbleable_metadata->addCacheContexts(['url.query_args']);
foreach ($query_tokens as $name => $original) {
if (\Drupal::request()->query->has($name)) {
$value = \Drupal::request()->query->get($name);
@@ -784,8 +817,23 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// Chained token relationships.
if ($url_tokens = \Drupal::token()->findWithPrefix($tokens, 'url')) {
- $url = Url::fromRoute('');
- $replacements += \Drupal::token()->generate('url', $url_tokens, array('url' => $url), $options, $bubbleable_metadata);
+ $url = NULL;
+ try {
+ $url = Url::createFromRequest($request)->setOptions($url_options);
+ }
+ catch (\Exception $e) {
+ // Url::createFromRequest() can fail, e.g. on 404 pages.
+ // Fall back and try again with Url::fromUserInput().
+ try {
+ $url = Url::fromUserInput($request->getPathInfo(), $url_options);
+ }
+ catch (\Exception $e) {
+ // Instantiation would fail again on malformed urls.
+ }
+ }
+ // Add cache contexts to ensure this token functions on a per-path basis
+ $bubbleable_metadata->addCacheContexts(['url.path']);
+ $replacements += \Drupal::token()->generate('url', $url_tokens, ['url' => $url], $options, $bubbleable_metadata);
}
}
@@ -807,42 +855,47 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
$value = !($url->getOption('alias')) ? \Drupal::service('path.alias_manager')->getAliasByPath($path, $langcode) : $path;
$replacements[$original] = $value;
break;
+
case 'alias':
// @deprecated
$alias = \Drupal::service('path.alias_manager')->getAliasByPath($path, $langcode);
$replacements[$original] = $alias;
break;
+
case 'absolute':
$replacements[$original] = $url->setAbsolute()->toString();
break;
+
case 'relative':
$replacements[$original] = $url->setAbsolute(FALSE)->toString();
break;
+
case 'brief':
- $replacements[$original] = preg_replace(array('!^https?://!', '!/$!'), '', $url->setAbsolute()->toString());
+ $replacements[$original] = preg_replace(['!^https?://!', '!/$!'], '', $url->setAbsolute()->toString());
break;
+
case 'unaliased':
$unaliased = clone $url;
$replacements[$original] = $unaliased->setAbsolute()->setOption('alias', TRUE)->toString();
break;
+
case 'args':
$value = !($url->getOption('alias')) ? \Drupal::service('path.alias_manager')->getAliasByPath($path, $langcode) : $path;
$replacements[$original] = token_render_array(explode('/', $value), $options);
break;
-
}
}
// [url:args:*] chained tokens.
if ($arg_tokens = \Drupal::token()->findWithPrefix($tokens, 'args')) {
$value = !($url->getOption('alias')) ? \Drupal::service('path.alias_manager')->getAliasByPath($path, $langcode) : $path;
- $replacements += \Drupal::token()->generate('array', $arg_tokens, array('array' => explode('/', ltrim($value, '/'))), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('array', $arg_tokens, ['array' => explode('/', ltrim($value, '/'))], $options, $bubbleable_metadata);
}
// [url:unaliased:*] chained tokens.
if ($unaliased_tokens = \Drupal::token()->findWithPrefix($tokens, 'unaliased')) {
$url->setOption('alias', TRUE);
- $replacements += \Drupal::token()->generate('url', $unaliased_tokens, array('url' => $url), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('url', $unaliased_tokens, ['url' => $url], $options, $bubbleable_metadata);
}
}
@@ -854,8 +907,8 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
foreach ($tokens as $name => $original) {
switch ($name) {
case 'url':
- if (_token_module($type, 'url') == 'token' && $url = $entity->url()) {
- $replacements[$original] = $url;
+ if (_token_module($type, 'url') === 'token' && !$entity->isNew() && $entity->hasLinkTemplate('canonical')) {
+ $replacements[$original] = $entity->toUrl('canonical')->toString();
}
break;
@@ -870,20 +923,20 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// [entity:url:*] chained tokens.
if (($url_tokens = \Drupal::token()->findWithPrefix($tokens, 'url')) && _token_module($type, 'url') == 'token') {
- $replacements += \Drupal::token()->generate('url', $url_tokens, array('url' => $entity->toUrl()), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('url', $url_tokens, ['url' => $entity->toUrl()], $options, $bubbleable_metadata);
}
// [entity:original:*] chained tokens.
if (($original_tokens = \Drupal::token()->findWithPrefix($tokens, 'original')) && _token_module($type, 'original') == 'token' && !empty($entity->original)) {
- $replacements += \Drupal::token()->generate($type, $original_tokens, array($type => $entity->original), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate($type, $original_tokens, [$type => $entity->original], $options, $bubbleable_metadata);
}
// Pass through to an generic 'entity' token type generation.
- $entity_data = array(
+ $entity_data = [
'entity_type' => $entity_type,
'entity' => $entity,
'token_type' => $type,
- );
+ ];
// @todo Investigate passing through more data like everything from entity_extract_ids().
$replacements += \Drupal::token()->generate('entity', $tokens, $entity_data, $options, $bubbleable_metadata);
}
@@ -905,23 +958,28 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
$value = is_array($value) ? $renderer->renderPlain($value) : (string) $value;
$replacements[$original] = $value;
break;
+
case 'last':
$value = $array[$keys[count($keys) - 1]];
$value = is_array($value) ? $renderer->renderPlain($value) : (string) $value;
- $replacements[$original] =$value;
+ $replacements[$original] = $value;
break;
+
case 'count':
$replacements[$original] = count($keys);
break;
+
case 'keys':
$replacements[$original] = token_render_array($keys, $options);
break;
+
case 'reversed':
$reversed = array_reverse($array, TRUE);
$replacements[$original] = token_render_array($reversed, $options);
break;
+
case 'join':
- $replacements[$original] = token_render_array($array, array('join' => '') + $options);
+ $replacements[$original] = token_render_array($array, ['join' => ''] + $options);
break;
}
}
@@ -938,18 +996,18 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// [array:join:*] dynamic tokens.
if ($join_tokens = \Drupal::token()->findWithPrefix($tokens, 'join')) {
foreach ($join_tokens as $join => $original) {
- $replacements[$original] = token_render_array($array, array('join' => $join) + $options);
+ $replacements[$original] = token_render_array($array, ['join' => $join] + $options);
}
}
// [array:keys:*] chained tokens.
if ($key_tokens = \Drupal::token()->findWithPrefix($tokens, 'keys')) {
- $replacements += \Drupal::token()->generate('array', $key_tokens, array('array' => $keys), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('array', $key_tokens, ['array' => $keys], $options, $bubbleable_metadata);
}
// [array:reversed:*] chained tokens.
if ($reversed_tokens = \Drupal::token()->findWithPrefix($tokens, 'reversed')) {
- $replacements += \Drupal::token()->generate('array', $reversed_tokens, array('array' => array_reverse($array, TRUE)), array('array sort' => FALSE) + $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('array', $reversed_tokens, ['array' => array_reverse($array, TRUE)], ['array sort' => FALSE] + $options, $bubbleable_metadata);
}
// @todo Handle if the array values are not strings and could be chained.
@@ -981,7 +1039,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
if (empty($data[$type]) && ($entity_type = \Drupal::service('token.entity_mapper')->getEntityTypeForTokenType($type)) && $entity_type != $type && !empty($data[$entity_type]) && empty($options['recursive'])) {
$data[$type] = $data[$entity_type];
$options['recursive'] = TRUE;
- $replacements += \Drupal::moduleHandler()->invokeAll('tokens', array($type, $tokens, $data, $options, $bubbleable_metadata));
+ $replacements += \Drupal::moduleHandler()->invokeAll('tokens', [$type, $tokens, $data, $options, $bubbleable_metadata]);
}
// If the token type specifics a 'needs-data' value, and the value is not
@@ -990,7 +1048,7 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
// Only check when tests are running.
$type_info = \Drupal::token()->getTypeInfo($type);
if (!empty($type_info['needs-data']) && !isset($data[$type_info['needs-data']])) {
- trigger_error(t('Attempting to perform token replacement for token type %type without required data', array('%type' => $type)), E_USER_WARNING);
+ trigger_error(t('Attempting to perform token replacement for token type %type without required data', ['%type' => $type]), E_USER_WARNING);
}
}
@@ -1001,50 +1059,50 @@ function token_tokens($type, array $tokens, array $data = array(), array $option
* Implements hook_token_info() on behalf of book.module.
*/
function book_token_info() {
- $info['types']['book'] = array(
+ $info['types']['book'] = [
'name' => t('Book'),
'description' => t('Tokens related to books.'),
'needs-data' => 'book',
- );
+ ];
- $info['tokens']['book']['title'] = array(
+ $info['tokens']['book']['title'] = [
'name' => t('Title'),
'description' => t('Title of the book.'),
- );
- $info['tokens']['book']['author'] = array(
+ ];
+ $info['tokens']['book']['author'] = [
'name' => t('Author'),
'description' => t('The author of the book.'),
'type' => 'user',
- );
- $info['tokens']['book']['root'] = array(
+ ];
+ $info['tokens']['book']['root'] = [
'name' => t('Root'),
'description' => t('Top level of the book.'),
'type' => 'node',
- );
- $info['tokens']['book']['parent'] = array(
+ ];
+ $info['tokens']['book']['parent'] = [
'name' => t('Parent'),
'description' => t('Parent of the current page.'),
'type' => 'node',
- );
- $info['tokens']['book']['parents'] = array(
+ ];
+ $info['tokens']['book']['parents'] = [
'name' => t('Parents'),
'description' => t("An array of all the node's parents, starting with the root."),
'type' => 'array',
- );
+ ];
- $info['tokens']['node']['book'] = array(
+ $info['tokens']['node']['book'] = [
'name' => t('Book'),
'description' => t('The book page associated with the node.'),
'type' => 'book',
- );
+ ];
return $info;
}
/**
* Implements hook_tokens() on behalf of book.module.
*/
-function book_tokens($type, $tokens, array $data = array(), array $options = array(), BubbleableMetadata $bubbleable_metadata) {
- $replacements = array();
+function book_tokens($type, $tokens, array $data = [], array $options = [], BubbleableMetadata $bubbleable_metadata) {
+ $replacements = [];
// Node tokens.
if ($type == 'node' && !empty($data['node'])) {
@@ -1053,12 +1111,12 @@ function book_tokens($type, $tokens, array $data = array(), array $options = arr
if (!empty($book['bid'])) {
if ($book_tokens = \Drupal::token()->findWithPrefix($tokens, 'book')) {
$child_node = Node::load($book['nid']);
- $replacements += \Drupal::token()->generate('book', $book_tokens, array('book' => $child_node), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('book', $book_tokens, ['book' => $child_node], $options, $bubbleable_metadata);
}
}
}
// Book tokens.
- else if ($type == 'book' && !empty($data['book'])) {
+ elseif ($type == 'book' && !empty($data['book'])) {
$book = $data['book']->book;
if (!empty($book['bid'])) {
@@ -1070,12 +1128,14 @@ function book_tokens($type, $tokens, array $data = array(), array $options = arr
case 'title':
$replacements[$original] = $book_node->getTitle();
break;
+
case 'parent':
if (!empty($book['pid'])) {
$parent_node = Node::load($book['pid']);
$replacements[$original] = $parent_node->getTitle();
}
break;
+
case 'parents':
if ($parents = token_book_load_all_parents($book)) {
$replacements[$original] = token_render_array($parents, $options);
@@ -1085,18 +1145,18 @@ function book_tokens($type, $tokens, array $data = array(), array $options = arr
}
if ($book_tokens = \Drupal::token()->findWithPrefix($tokens, 'author')) {
- $replacements += \Drupal::token()->generate('user', $book_tokens, array('user' => $book_node->getOwner()), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('user', $book_tokens, ['user' => $book_node->getOwner()], $options, $bubbleable_metadata);
}
if ($book_tokens = \Drupal::token()->findWithPrefix($tokens, 'root')) {
- $replacements += \Drupal::token()->generate('node', $book_tokens, array('node' => $book_node), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('node', $book_tokens, ['node' => $book_node], $options, $bubbleable_metadata);
}
if (!empty($book['pid']) && $book_tokens = \Drupal::token()->findWithPrefix($tokens, 'parent')) {
$parent_node = Node::load($book['pid']);
- $replacements += \Drupal::token()->generate('node', $book_tokens, array('node' => $parent_node), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('node', $book_tokens, ['node' => $parent_node], $options, $bubbleable_metadata);
}
if ($book_tokens = \Drupal::token()->findWithPrefix($tokens, 'parents')) {
$parents = token_book_load_all_parents($book);
- $replacements += \Drupal::token()->generate('array', $book_tokens, array('array' => $parents), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('array', $book_tokens, ['array' => $parents], $options, $bubbleable_metadata);
}
}
}
@@ -1109,46 +1169,46 @@ function book_tokens($type, $tokens, array $data = array(), array $options = arr
*/
function menu_ui_token_info() {
// Menu tokens.
- $info['types']['menu'] = array(
+ $info['types']['menu'] = [
'name' => t('Menus'),
'description' => t('Tokens related to menus.'),
'needs-data' => 'menu',
- );
- $info['tokens']['menu']['name'] = array(
+ ];
+ $info['tokens']['menu']['name'] = [
'name' => t('Name'),
'description' => t("The name of the menu."),
- );
- $info['tokens']['menu']['machine-name'] = array(
+ ];
+ $info['tokens']['menu']['machine-name'] = [
'name' => t('Machine-readable name'),
'description' => t("The unique machine-readable name of the menu."),
- );
- $info['tokens']['menu']['description'] = array(
+ ];
+ $info['tokens']['menu']['description'] = [
'name' => t('Description'),
'description' => t('The optional description of the menu.'),
- );
- $info['tokens']['menu']['menu-link-count'] = array(
+ ];
+ $info['tokens']['menu']['menu-link-count'] = [
'name' => t('Menu link count'),
'description' => t('The number of menu links belonging to the menu.'),
- );
- $info['tokens']['menu']['edit-url'] = array(
+ ];
+ $info['tokens']['menu']['edit-url'] = [
'name' => t('Edit URL'),
'description' => t("The URL of the menu's edit page."),
- );
+ ];
- $info['tokens']['menu-link']['menu'] = array(
+ $info['tokens']['menu-link']['menu'] = [
'name' => t('Menu'),
'description' => t('The menu of the menu link.'),
'type' => 'menu',
- );
- $info['tokens']['menu-link']['edit-url'] = array(
+ ];
+ $info['tokens']['menu-link']['edit-url'] = [
'name' => t('Edit URL'),
'description' => t("The URL of the menu link's edit page."),
- );
- $info['tokens']['node']['menu-link'] = array(
+ ];
+ $info['tokens']['node']['menu-link'] = [
'name' => t('Menu link'),
'description' => t("The menu link for this node."),
'type' => 'menu-link',
- );
+ ];
return $info;
}
@@ -1156,13 +1216,13 @@ function menu_ui_token_info() {
/**
* Implements hook_tokens() on behalf of menu_ui.module.
*/
-function menu_ui_tokens($type, $tokens, array $data = array(), array $options = array(), BubbleableMetadata $bubbleable_metadata) {
- $replacements = array();
+function menu_ui_tokens($type, $tokens, array $data = [], array $options = [], BubbleableMetadata $bubbleable_metadata) {
+ $replacements = [];
/** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */
$menu_link_manager = \Drupal::service('plugin.manager.menu.link');
- $url_options = array('absolute' => TRUE);
+ $url_options = ['absolute' => TRUE];
if (isset($options['langcode'])) {
$url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']);
$langcode = $options['langcode'];
@@ -1200,13 +1260,13 @@ function menu_ui_tokens($type, $tokens, array $data = array(), array $options =
if ($menu_tokens = \Drupal::token()->findWithPrefix($tokens, 'menu-link')) {
if ($node->getFieldDefinition('menu_link') && $menu_link = $node->menu_link->entity) {
/** @var \Drupal\menu_link_content\MenuLinkContentInterface $menu_link */
- $replacements += \Drupal::token()->generate('menu-link', $menu_tokens, array('menu-link' => $menu_link), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('menu-link', $menu_tokens, ['menu-link' => $menu_link], $options, $bubbleable_metadata);
}
else {
- $url = $node->urlInfo();
+ $url = $node->toUrl();
if ($links = $menu_link_manager->loadLinksByRoute($url->getRouteName(), $url->getRouteParameters())) {
$link = _token_menu_link_best_match($node, $links);
- $replacements += \Drupal::token()->generate('menu-link', $menu_tokens, array('menu-link' => $link), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('menu-link', $menu_tokens, ['menu-link' => $link], $options, $bubbleable_metadata);
}
}
}
@@ -1238,7 +1298,7 @@ function menu_ui_tokens($type, $tokens, array $data = array(), array $options =
// Chained token relationships.
if (($menu_tokens = \Drupal::token()->findWithPrefix($tokens, 'menu')) && $menu = Menu::load($link->getMenuName())) {
- $replacements += \Drupal::token()->generate('menu', $menu_tokens, array('menu' => $menu), $options, $bubbleable_metadata);
+ $replacements += \Drupal::token()->generate('menu', $menu_tokens, ['menu' => $menu], $options, $bubbleable_metadata);
}
}
@@ -1370,13 +1430,13 @@ function field_token_info_alter(&$info) {
$cardinality = $field->getCardinality();
$cardinality = ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED || $cardinality > 3) ? 3 : $cardinality;
$field_token_name = $token_type . '-' . $field_name;
- $info['tokens'][$token_type][$field_name] = array(
+ $info['tokens'][$token_type][$field_name] = [
'name' => Html::escape($label),
'description' => $description,
'module' => 'token',
// For multivalue fields the field token is a list type.
'type' => $cardinality > 1 ? "list<$field_token_name>" : $field_token_name,
- );
+ ];
// Field token type.
$info['types'][$field_token_name] = [
@@ -1387,12 +1447,12 @@ function field_token_info_alter(&$info) {
];
// Field list token type.
if ($cardinality > 1) {
- $info['types']["list<$field_token_name>"] = array(
- 'name' => t('List of @type values', array('@type' => Html::escape($label))),
- 'description' => t('Tokens for lists of @type values.', array('@type' => Html::escape($label))),
+ $info['types']["list<$field_token_name>"] = [
+ 'name' => t('List of @type values', ['@type' => Html::escape($label)]),
+ 'description' => t('Tokens for lists of @type values.', ['@type' => Html::escape($label)]),
'needs-data' => "list<$field_token_name>",
'nested' => TRUE,
- );
+ ];
}
// Show a different token for each field delta.
@@ -1443,7 +1503,7 @@ function field_token_info_alter(&$info) {
$info['tokens'][$field_token_name]['date']['name'] .= ' ' . t('format');
$info['tokens'][$field_token_name]['date']['type'] = 'date';
}
- if ($field->getType() == 'daterange') {
+ if ($field->getType() == 'daterange' || $field->getType() == 'date_recur') {
$info['tokens'][$field_token_name]['start_date'] = $info['tokens'][$field_token_name]['value'];
$info['tokens'][$field_token_name]['start_date']['name'] .= ' ' . t('format');
$info['tokens'][$field_token_name]['start_date']['type'] = 'date';
@@ -1488,8 +1548,8 @@ function _token_field_label($entity_type, $field_name) {
/**
* Implements hook_tokens() on behalf of field.module.
*/
-function field_tokens($type, $tokens, array $data = array(), array $options = array(), BubbleableMetadata $bubbleable_metadata) {
- $replacements = array();
+function field_tokens($type, $tokens, array $data = [], array $options = [], BubbleableMetadata $bubbleable_metadata) {
+ $replacements = [];
$langcode = isset($options['langcode']) ? $options['langcode'] : NULL;
// Entity tokens.
if ($type == 'entity' && !empty($data['entity_type']) && !empty($data['entity']) && !empty($data['token_type'])) {
@@ -1573,7 +1633,7 @@ function field_tokens($type, $tokens, array $data = array(), array $options = ar
}
// Handle [entity:field_name:value] and [entity:field_name:0:value]
// tokens.
- else if ($field_tokens = \Drupal::token()->findWithPrefix($tokens, $field_name)) {
+ elseif ($field_tokens = \Drupal::token()->findWithPrefix($tokens, $field_name)) {
$property_token_data = [
'field_property' => TRUE,
$data['entity_type'] . '-' . $field_name => $entity->$field_name,
@@ -1671,7 +1731,8 @@ function field_tokens($type, $tokens, array $data = array(), array $options = ar
case 'mimetype':
$replacements[$original] = $image->getMimeType();
break;
- case 'filesize' :
+
+ case 'filesize':
$replacements[$original] = $image->getFileSize();
break;
}
@@ -1679,11 +1740,11 @@ function field_tokens($type, $tokens, array $data = array(), array $options = ar
}
}
}
- elseif (in_array($field_item->getFieldDefinition()->getType(), ['datetime', 'daterange']) && in_array($property_name, ['date', 'start_date', 'end_date'])) {
- $timestamp = $field_item->$property_name->getTimestamp();
+ elseif (in_array($field_item->getFieldDefinition()->getType(), ['datetime', 'daterange', 'date_recur']) && in_array($property_name, ['date', 'start_date', 'end_date']) && !empty($field_item->$property_name)) {
+ $timestamp = $field_item->{$property_name}->getTimestamp();
// If the token is an exact match for the property or the delta and the
// property, use the timestamp as-is.
- if($property_name == $token || "$delta:$property_name" == $token) {
+ if ($property_name == $token || "$delta:$property_name" == $token) {
$replacements[$original] = $timestamp;
}
else {
@@ -1717,7 +1778,7 @@ function token_pre_render_field_token($elements) {
foreach ($deltas as $index => $delta) {
// Do not add a suffix to the last item.
if ($index < ($count - 1)) {
- $elements[$delta] += array('#suffix' => $join);
+ $elements[$delta] += ['#suffix' => $join];
}
}
}
diff --git a/sites/all/modules/contrib/search/search_api/CHANGELOG.txt b/sites/all/modules/contrib/search/search_api/CHANGELOG.txt
index 85c35b3ea..66f73cb2c 100644
--- a/sites/all/modules/contrib/search/search_api/CHANGELOG.txt
+++ b/sites/all/modules/contrib/search/search_api/CHANGELOG.txt
@@ -1,3 +1,62 @@
+Search API 1.9 (2018-07-19):
+----------------------------
+- #2956012 by drunken monkey, DuaelFr: Added uncustomized view modes as options
+ when rendering items.
+- #2980903 by drunken monkey, kristofferwiklund, borisson_: Fixed undefined
+ index notice in Views date filter.
+- #2982693 by jhedstrom, borisson_, drunken monkey: Adapted tests to latest
+ Core changes.
+- #2971033 by mErilainen, drunken monkey, borisson_: Added an option for prefix
+ matching to the database backend.
+- #2973034 by idebr, drunken monkey: Removed outdated @todo comment.
+- #2972510 by msankhala, drunken monkey: Replaced Unicode::* methods with mb_*
+ functions.
+- #2973047 by idebr, drunken monkey: Fixed misnamed test config files.
+- #2860167 by drunken monkey, borisson_, fenstrat: Added "orderby" to our
+ config schema definitions.
+- #2948820 by capysara, drunken monkey, borisson_: Added a link to the "need to
+ reindex" message on the Filters tab.
+- #2965803 by capysara, drunken monkey: Fixed left-over use of @url placeholder.
+- #2957650 by drunken monkey, borisson_: Fixed two minor problems.
+- #2939010 by nedjo, drunken monkey: Fixed deleted fields when index is created
+ during module install.
+- #2931730 by drunken monkey, borisson_, chanderbhushan: Adapted to changes in
+ drupal_set_message().
+- #2955607 by drunken monkey, borisson_: Removed our custom Query::__wakeup()
+ work-around.
+- #2940138 by drunken monkey, borisson_: Switched to new Core tempstore service.
+- #2936630 by drunken monkey, borisson_: Adapted override detection code to use
+ Config::hasOverrides().
+- #2961537 by drunken monkey: Increased Core dependency to Drupal 8.5.
+- #2959809 by drunken monkey, Rob230, mkalkbrenner, borisson_: Fixed small
+ coding mistake in the "URL field" processor.
+- #2960931 by drunken monkey, borisson_: Fixed viewing of multiple content
+ entity items.
+
+Search API 1.8 (2018-04-16):
+----------------------------
+- #2960854 by nedjo, drunken monkey: Fixed "Database search defaults" index.
+- #2930839 by drunken monkey: Update tests according to latest PHPUnit
+ compatibility changes
+- #2921022 by drunken monkey, marcvangend: Fixed automatic task execution with
+ Drush.
+- #2955887 by drunken monkey, borisson_: Added a way to re-execute a query.
+- #2925464 by drunken monkey, borisson_, .jch: Fixed problem with missing "NOT
+ NULL" attribute in database backend.
+- #2953266 by drunken monkey, borisson_: Added a helper method for
+ "selected"/"default" checks.
+- #2953267 by drunken monkey, borisson_: Fixed REST dependency of Views test
+ module.
+- #2945870 by Dropa, drunken monkey: Fixed timezone of indexed date strings.
+- #2948659 by drunken monkey, borisson_, bskibinski: Added support for HTML5
+ placeholder in Views exposed filters.
+- #2951055 by bradjones1, borisson_, drunken monkey: Fixed documentation for
+ IndexInterface::addField().
+- #2945560 by mkalkbrenner, drunken monkey, borisson_: Fixed handling of
+ existing highlighting data in Highlight processor.
+- #2946386 by drunken monkey, borisson_: Fixed typo in Query::getAbortMessage().
+- #2945675 by drunken monkey, borisson_: Unified use of self and static.
+
Search API 1.7 (2018-02-23):
----------------------------
- #2922525 by drunken monkey, borisson_: Changed "Index items immediately" to
diff --git a/sites/all/modules/contrib/search/search_api/config/schema/search_api.datasource.schema.yml b/sites/all/modules/contrib/search/search_api/config/schema/search_api.datasource.schema.yml
index 895f5b3b8..42590ed35 100644
--- a/sites/all/modules/contrib/search/search_api/config/schema/search_api.datasource.schema.yml
+++ b/sites/all/modules/contrib/search/search_api/config/schema/search_api.datasource.schema.yml
@@ -12,6 +12,7 @@
selected:
type: sequence
label: 'The selected bundles'
+ orderby: value
sequence:
type: string
label: 'A bundle machine name'
@@ -25,6 +26,7 @@
selected:
type: sequence
label: 'The selected languages'
+ orderby: value
sequence:
type: string
label: 'A language code'
diff --git a/sites/all/modules/contrib/search/search_api/config/schema/search_api.index.schema.yml b/sites/all/modules/contrib/search/search_api/config/schema/search_api.index.schema.yml
index 60e879afd..6797a8ebc 100644
--- a/sites/all/modules/contrib/search/search_api/config/schema/search_api.index.schema.yml
+++ b/sites/all/modules/contrib/search/search_api/config/schema/search_api.index.schema.yml
@@ -20,6 +20,7 @@ search_api.index.*:
field_settings:
type: sequence
label: 'Indexed fields'
+ orderby: key
sequence:
type: mapping
label: field
@@ -56,18 +57,21 @@ search_api.index.*:
datasource_settings:
type: sequence
label: 'Datasource settings'
+ orderby: key
sequence:
type: plugin.plugin_configuration.search_api_datasource.[%key]
label: 'The configuration for a single datasource'
processor_settings:
type: sequence
label: 'Processor settings'
+ orderby: key
sequence:
type: plugin.plugin_configuration.search_api_processor.[%key]
label: 'The configuration for a single processor'
tracker_settings:
type: sequence
label: 'Tracker settings'
+ orderby: key
sequence:
type: plugin.plugin_configuration.search_api_tracker.[%key]
label: 'The configuration for the tracker'
diff --git a/sites/all/modules/contrib/search/search_api/config/schema/search_api.processor.schema.yml b/sites/all/modules/contrib/search/search_api/config/schema/search_api.processor.schema.yml
index 1a0018c1a..0c98ad8a2 100644
--- a/sites/all/modules/contrib/search/search_api/config/schema/search_api.processor.schema.yml
+++ b/sites/all/modules/contrib/search/search_api/config/schema/search_api.processor.schema.yml
@@ -7,6 +7,7 @@ search_api.default_processor_configuration:
weights:
type: sequence
label: 'The processor''s weights for the different processing stages'
+ orderby: key
sequence:
type: integer
label: 'The processor''s weight for this stage'
@@ -21,6 +22,7 @@ search_api.fields_processor_configuration:
fields:
type: sequence
label: 'The selected fields'
+ orderby: value
sequence:
type: string
label: 'Selected field'
@@ -37,7 +39,8 @@ plugin.plugin_configuration.search_api_processor.hierarchy:
mapping:
fields:
type: sequence
- label: 'Fields for which to add the hierarchy'
+ label: 'Fields for which to add the hierarchy, mapped to their hierarchical nested property'
+ orderby: key
sequence:
type: string
label: 'Field ID'
@@ -61,6 +64,7 @@ plugin.plugin_configuration.search_api_processor.highlight:
exclude_fields:
type: sequence
label: 'Fields excluded from excerpt'
+ orderby: value
sequence:
type: string
label: 'An excluded field''s ID'
@@ -84,6 +88,7 @@ plugin.plugin_configuration.search_api_processor.html_filter:
tags:
type: sequence
label: 'Tag boosts'
+ orderby: key
sequence:
type: integer
label: Boost
@@ -106,6 +111,7 @@ plugin.plugin_configuration.search_api_processor.ignore_character:
character_sets:
type: sequence
label: 'Configuration of the character sets'
+ orderby: key
sequence:
type: ignore
label: 'Character set'
@@ -117,6 +123,7 @@ plugin.plugin_configuration.search_api_processor.stemmer:
exceptions:
type: sequence
label: 'Stemming exceptions'
+ orderby: key
sequence:
type: string
label: Exception
@@ -131,6 +138,7 @@ plugin.plugin_configuration.search_api_processor.role_filter:
roles:
type: sequence
label: 'The selected roles'
+ orderby: value
sequence:
type: string
label: 'The role name'
@@ -141,7 +149,8 @@ plugin.plugin_configuration.search_api_processor.stopwords:
mapping:
stopwords:
type: sequence
- label: 'entered stopwords'
+ label: 'Entered stopwords'
+ orderby: value
sequence:
type: string
label: Stopword
@@ -174,6 +183,7 @@ plugin.plugin_configuration.search_api_processor.type_boost:
boosts:
type: sequence
label: 'Boost settings'
+ orderby: key
sequence:
type: mapping
label: 'Datasource boost settings'
@@ -184,6 +194,7 @@ plugin.plugin_configuration.search_api_processor.type_boost:
bundle_boosts:
type: sequence
label: 'Bundle-specific boosts'
+ orderby: key
sequence:
type: float
label: 'The boost value for this bundle'
@@ -205,6 +216,7 @@ search_api.property_configuration.aggregated_field:
fields:
type: sequence
label: 'The properties to be aggregated'
+ orderby: value
sequence:
type: string
label: 'A property that should be part of the aggregation'
@@ -216,15 +228,18 @@ search_api.property_configuration.rendered_item:
roles:
type: sequence
label: 'The selected roles'
+ orderby: key
sequence:
type: string
label: 'The user roles which will be active when the entity is rendered'
view_mode:
type: sequence
label: 'The selected view modes for each datasource, by bundle'
+ orderby: key
sequence:
type: sequence
label: 'The selected view modes for the datasource, by bundle'
+ orderby: key
sequence:
type: string
label: 'The view mode used to render the entity for the specified bundle'
diff --git a/sites/all/modules/contrib/search/search_api/config/schema/search_api.views.schema.yml b/sites/all/modules/contrib/search/search_api/config/schema/search_api.views.schema.yml
index 2ae3943c5..80cb7c407 100644
--- a/sites/all/modules/contrib/search/search_api/config/schema/search_api.views.schema.yml
+++ b/sites/all/modules/contrib/search/search_api/config/schema/search_api.views.schema.yml
@@ -16,9 +16,11 @@ views.row.search_api:
view_modes:
type: sequence
label: View modes for each datasource
+ orderby: key
sequence:
type: sequence
label: A list of all the bundles and their configured view mode
+ orderby: key
sequence:
type: string
label: View mode for the specific bundle
@@ -70,6 +72,7 @@ views.argument.search_api_fulltext:
fields:
type: sequence
label: 'Fields'
+ orderby: value
sequence:
type: string
label: 'Field'
@@ -81,6 +84,7 @@ views.argument.search_api_more_like_this:
fields:
type: sequence
label: 'Fields'
+ orderby: value
sequence:
type: string
label: 'Field'
@@ -147,6 +151,7 @@ views.field.search_api_entity:
display_methods:
type: sequence
label: 'Display settings'
+ orderby: key
sequence:
type: mapping
label: 'Display settings for bundle'
@@ -216,9 +221,17 @@ views.filter.search_api_fulltext:
fields:
type: sequence
label: Fields to search on
+ orderby: value
sequence:
type: string
label: Field name
+ expose:
+ type: mapping
+ label: 'Exposed'
+ mapping:
+ placeholder:
+ type: label
+ label: 'Placeholder'
views.filter.search_api_language:
type: views.filter.language
@@ -269,6 +282,7 @@ views.filter_value.search_api_numeric:
views.filter_value.search_api_options:
type: sequence
+ orderby: value
sequence:
type: string
label: 'Value'
diff --git a/sites/all/modules/contrib/search/search_api/modules/search_api_db/config/schema/search_api_db.backend.schema.yml b/sites/all/modules/contrib/search/search_api/modules/search_api_db/config/schema/search_api_db.backend.schema.yml
index b64c0a19a..96157bda5 100644
--- a/sites/all/modules/contrib/search/search_api/modules/search_api_db/config/schema/search_api_db.backend.schema.yml
+++ b/sites/all/modules/contrib/search/search_api/modules/search_api_db/config/schema/search_api_db.backend.schema.yml
@@ -8,9 +8,9 @@ plugin.plugin_configuration.search_api_backend.search_api_db:
min_chars:
type: 'integer'
label: 'Minimum length of indexed words'
- partial_matches:
- type: 'boolean'
- label: 'Whether to also search on parts of a word'
+ matching:
+ type: 'string'
+ label: 'The matching mode – "words", "prefix" or "partial"'
autocomplete:
type: mapping
label: Autcomplete configuration
diff --git a/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db.info.yml b/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db.info.yml
index e290ca6d0..94ca69eba 100644
--- a/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db.info.yml
+++ b/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db.info.yml
@@ -6,8 +6,8 @@ package: Search
dependencies:
- search_api:search_api
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db.install b/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db.install
index 786d4c06b..40597e705 100644
--- a/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db.install
+++ b/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db.install
@@ -76,3 +76,34 @@ function search_api_db_update_8102() {
return t('Primary keys added to all denormalized index tables.');
}
+
+/**
+ * Converts the old "partial_matches" option to the new "matching" option.
+ */
+function search_api_db_update_8103() {
+ // @see https://www.drupal.org/project/search_api/issues/2971033
+
+ $config_factory = \Drupal::configFactory();
+ $count = 0;
+ foreach ($config_factory->listAll('search_api.server.') as $server_id) {
+ $server = $config_factory->getEditable($server_id);
+ if ($server->get('backend') !== 'search_api_db') {
+ continue;
+ }
+
+ ++$count;
+ $config = $server->get('backend_config') ?: [];
+ $config['matching'] = empty($config['partial_matches']) ? 'words' : 'partial';
+ unset($config['partial_matches']);
+ $server->set('backend_config', $config);
+ // Mark the resulting configuration as trusted data. This avoids issues
+ // with future schema changes.
+ $server->save(TRUE);
+ }
+
+ if ($count) {
+ return \Drupal::translation()
+ ->formatPlural($count, 'Updated 1 server.', 'Updated @count servers.');
+ }
+ return NULL;
+}
diff --git a/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/config/optional/search_api.index.default_index.yml b/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/config/optional/search_api.index.default_index.yml
index 05395b1e3..b8eebc911 100644
--- a/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/config/optional/search_api.index.default_index.yml
+++ b/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/config/optional/search_api.index.default_index.yml
@@ -3,12 +3,33 @@ name: 'Default content index'
description: 'Default content index created by the Database Search Defaults module'
read_only: false
field_settings:
- title:
- label: Title
- type: text
+ author:
+ label: 'Author name'
+ type: string
datasource_id: 'entity:node'
- property_path: title
- boost: 8
+ property_path: 'uid:entity:name'
+ changed:
+ label: Changed
+ type: date
+ datasource_id: 'entity:node'
+ property_path: changed
+ created:
+ label: 'Authored on'
+ type: date
+ datasource_id: 'entity:node'
+ property_path: created
+ field_tags:
+ label: Tags
+ type: integer
+ datasource_id: 'entity:node'
+ property_path: 'field_tags'
+ node_grants:
+ label: 'Node access information'
+ type: string
+ property_path: search_api_node_grants
+ indexed_locked: true
+ type_locked: true
+ hidden: true
rendered_item:
label: 'Rendered item'
type: text
@@ -20,57 +41,36 @@ field_settings:
'entity:node':
article: search_index
page: search_index
- created:
- label: 'Authored on'
- type: date
- datasource_id: 'entity:node'
- property_path: created
- changed:
- label: Changed
- type: date
- datasource_id: 'entity:node'
- property_path: changed
status:
label: 'Publishing status'
type: boolean
datasource_id: 'entity:node'
property_path: status
- index_locked: true
+ indexed_locked: true
type_locked: true
sticky:
label: 'Sticky at top of lists'
type: boolean
datasource_id: 'entity:node'
property_path: sticky
- field_tags:
- label: Tags
- type: integer
+ title:
+ label: Title
+ type: text
datasource_id: 'entity:node'
- property_path: 'field_tags'
- author:
- label: 'Author name'
- type: string
- datasource_id: 'entity:node'
- property_path: 'uid:entity:name'
- uid:
- label: 'Author ID'
- type: integer
- datasource_id: 'entity:node'
- property_path: uid
- index_locked: true
- type_locked: true
- node_grants:
- label: 'Node access information'
- type: string
- property_path: search_api_node_grants
- index_locked: true
- type_locked: true
- hidden: true
+ property_path: title
+ boost: 8
type:
label: 'Content type'
type: string
datasource_id: 'entity:node'
property_path: type
+ uid:
+ label: 'Author ID'
+ type: integer
+ datasource_id: 'entity:node'
+ property_path: uid
+ indexed_locked: true
+ type_locked: true
processor_settings:
add_url:
weights:
@@ -82,6 +82,9 @@ processor_settings:
weights:
preprocess_index: -6
preprocess_query: -4
+ entity_status:
+ weights:
+ preprocess_index: -10
html_filter:
weights:
preprocess_index: -3
@@ -103,9 +106,6 @@ processor_settings:
fields:
- rendered_item
- title
- entity_status:
- weights:
- preprocess_index: -10
rendered_item:
weights:
add_properties: 0
@@ -171,8 +171,8 @@ processor_settings:
- rendered_item
- title
options:
- index_directly: true
cron_limit: 50
+ index_directly: true
datasource_settings:
'entity:node': { }
tracker_settings:
diff --git a/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/config/optional/search_api.server.default_server.yml b/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/config/optional/search_api.server.default_server.yml
index 5566720d3..4451c2b0f 100644
--- a/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/config/optional/search_api.server.default_server.yml
+++ b/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/config/optional/search_api.server.default_server.yml
@@ -6,7 +6,7 @@ backend: search_api_db
backend_config:
database: 'default:default'
min_chars: 3
- partial_matches: false
+ matching: 'words'
autocomplete:
suggest_suffix: true
suggest_words: true
diff --git a/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/search_api_db_defaults.info.yml b/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/search_api_db_defaults.info.yml
index ca68b7720..2dba38b37 100644
--- a/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/search_api_db_defaults.info.yml
+++ b/sites/all/modules/contrib/search/search_api/modules/search_api_db/search_api_db_defaults/search_api_db_defaults.info.yml
@@ -13,8 +13,8 @@ dependencies:
- drupal:views
- search_api:search_api_db
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/modules/search_api_db/src/DatabaseCompatibility/GenericDatabase.php b/sites/all/modules/contrib/search/search_api/modules/search_api_db/src/DatabaseCompatibility/GenericDatabase.php
index c5de9250c..5db84b2f9 100644
--- a/sites/all/modules/contrib/search/search_api/modules/search_api_db/src/DatabaseCompatibility/GenericDatabase.php
+++ b/sites/all/modules/contrib/search/search_api/modules/search_api_db/src/DatabaseCompatibility/GenericDatabase.php
@@ -3,7 +3,6 @@
namespace Drupal\search_api_db\DatabaseCompatibility;
use Drupal\Component\Transliteration\TransliterationInterface;
-use Drupal\Component\Utility\Unicode;
use Drupal\Core\Database\Connection;
/**
@@ -66,7 +65,7 @@ class GenericDatabase implements DatabaseCompatibilityHandlerInterface {
if ($type == 'text') {
return $value;
}
- return Unicode::strtolower($this->transliterator->transliterate($value));
+ return mb_strtolower($this->transliterator->transliterate($value));
}
}
diff --git a/sites/all/modules/contrib/search/search_api/modules/search_api_db/src/Plugin/search_api/backend/Database.php b/sites/all/modules/contrib/search/search_api/modules/search_api_db/src/Plugin/search_api/backend/Database.php
index 88f22e76e..5bfb8cf59 100644
--- a/sites/all/modules/contrib/search/search_api/modules/search_api_db/src/Plugin/search_api/backend/Database.php
+++ b/sites/all/modules/contrib/search/search_api/modules/search_api_db/src/Plugin/search_api/backend/Database.php
@@ -399,7 +399,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
return [
'database' => NULL,
'min_chars' => 1,
- 'partial_matches' => FALSE,
+ 'matching' => 'words',
'autocomplete' => [
'suggest_suffix' => TRUE,
'suggest_words' => TRUE,
@@ -465,11 +465,15 @@ class Database extends BackendPluginBase implements PluginFormInterface {
'#default_value' => $this->configuration['min_chars'],
];
- $form['partial_matches'] = [
- '#type' => 'checkbox',
- '#title' => $this->t('Search on parts of a word'),
- '#description' => $this->t('Find keywords in parts of a word, too. (For example, find results with "database" when searching for "base"). Caution: This can make searches much slower on large sites!'),
- '#default_value' => $this->configuration['partial_matches'],
+ $form['matching'] = [
+ '#type' => 'radios',
+ '#title' => $this->t('Partial matching'),
+ '#default_value' => $this->configuration['matching'],
+ '#options' => [
+ 'words' => $this->t('Match whole words only'),
+ 'partial' => $this->t('Match on parts of a word'),
+ 'prefix' => $this->t('Match words starting with given keywords'),
+ ],
];
if ($this->getModuleHandler()->moduleExists('search_api_autocomplete')) {
@@ -511,10 +515,17 @@ class Database extends BackendPluginBase implements PluginFormInterface {
'info' => $this->configuration['min_chars'],
];
}
- $info[] = [
- 'label' => $this->t('Search on parts of a word'),
- 'info' => !empty($this->configuration['partial_matches']) ? $this->t('enabled') : $this->t('disabled'),
+
+ $labels = [
+ 'words' => $this->t('Match whole words only'),
+ 'partial' => $this->t('Match on parts of a word'),
+ 'prefix' => $this->t('Match words starting with given keywords'),
];
+ $info[] = [
+ 'label' => $this->t('Partial matching'),
+ 'info' => $labels[$this->configuration['matching']],
+ ];
+
if (!empty($this->configuration['autocomplete'])) {
$this->configuration['autocomplete'] += [
'suggest_suffix' => TRUE,
@@ -669,12 +680,12 @@ class Database extends BackendPluginBase implements PluginFormInterface {
// A DB prefix might further reduce the maximum length of the table name.
$max_bytes = 62;
if ($db_prefix = $this->database->tablePrefix()) {
- // Use strlen() instead of Unicode::strlen() since we want to measure
- // bytes, not characters.
+ // Use strlen() instead of mb_strlen() since we want to measure bytes, not
+ // characters.
$max_bytes -= strlen($db_prefix);
}
- $base = $table = Unicode::truncateBytes($prefix . Unicode::strtolower(preg_replace('/[^a-z0-9]/i', '_', $name)), $max_bytes);
+ $base = $table = Unicode::truncateBytes($prefix . mb_strtolower(preg_replace('/[^a-z0-9]/i', '_', $name)), $max_bytes);
$i = 0;
while ($this->database->schema()->tableExists($table)) {
$suffix = '_' . ++$i;
@@ -703,7 +714,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
protected function findFreeColumn($table, $column) {
$maxbytes = 62;
- $base = $name = Unicode::truncateBytes(Unicode::strtolower(preg_replace('/[^a-z0-9]/i', '_', $column)), $maxbytes);
+ $base = $name = Unicode::truncateBytes(mb_strtolower(preg_replace('/[^a-z0-9]/i', '_', $column)), $maxbytes);
// If the table does not exist yet, the initial name is not taken.
if ($this->database->schema()->tableExists($table)) {
$i = 0;
@@ -769,7 +780,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
$db_field += [
'description' => "The field's value for this item",
];
- if ($new_table) {
+ if ($new_table || $type === 'field') {
$db_field['not null'] = TRUE;
}
$this->database->schema()->addField($db['table'], $column, $db_field);
@@ -924,8 +935,13 @@ class Database extends BackendPluginBase implements PluginFormInterface {
elseif ($this->sqlType($old_type) != $this->sqlType($new_type)) {
// There is a change in SQL type. We don't have to clear the index,
// since types can be converted.
- $this->database->schema()->changeField($field['table'], 'value', 'value', $this->sqlType($new_type) + ['description' => "The field's value for this item"]);
- $this->database->schema()->changeField($denormalized_table, $field['column'], $field['column'], $this->sqlType($new_type) + ['description' => "The field's value for this item"]);
+ $sql_spec = $this->sqlType($new_type);
+ $sql_spec += [
+ 'description' => "The field's value for this item",
+ ];
+ $this->database->schema()->changeField($denormalized_table, $field['column'], $field['column'], $sql_spec);
+ $sql_spec['not null'] = TRUE;
+ $this->database->schema()->changeField($field['table'], 'value', 'value', $sql_spec);
$reindex = TRUE;
}
elseif ($old_type == 'date' || $new_type == 'date') {
@@ -955,7 +971,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
}
$this->database->update($text_table)
->expression('score', $expression, $args)
- ->condition('field_name', self::getTextFieldName($field_id))
+ ->condition('field_name', static::getTextFieldName($field_id))
->execute();
}
else {
@@ -1081,7 +1097,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
if ($this->getDataTypeHelper()->isTextType($field['type'])) {
// Remove data from the text table.
$this->database->delete($field['table'])
- ->condition('field_name', self::getTextFieldName($name))
+ ->condition('field_name', static::getTextFieldName($name))
->execute();
}
elseif ($this->database->schema()->tableExists($field['table'])) {
@@ -1263,7 +1279,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
// Store the first 30 characters of the string as the denormalized
// value.
- if (Unicode::strlen($denormalized_value) < 30) {
+ if (mb_strlen($denormalized_value) < 30) {
$denormalized_value .= $word . ' ';
}
@@ -1271,7 +1287,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
if (is_numeric($word)) {
$word = ltrim($word, '-0');
}
- elseif (Unicode::strlen($word) < $this->configuration['min_chars']) {
+ elseif (mb_strlen($word) < $this->configuration['min_chars']) {
continue;
}
@@ -1295,12 +1311,13 @@ class Database extends BackendPluginBase implements PluginFormInterface {
$unique_tokens[$word_base_form]['score'] += $score;
}
}
- $denormalized_values[$column] = Unicode::substr(trim($denormalized_value), 0, 30);
+ $denormalized_values[$column] = mb_substr(trim($denormalized_value), 0, 30);
if ($unique_tokens) {
- $field_name = self::getTextFieldName($field_id);
+ $field_name = static::getTextFieldName($field_id);
$boost = $field_info['boost'];
foreach ($unique_tokens as $token) {
- $score = round($token['score'] * $boost * self::SCORE_MULTIPLIER);
+ $score = $token['score'] * $boost * self::SCORE_MULTIPLIER;
+ $score = round($score);
// Take care that the score doesn't exceed the maximum value for
// the database column (2^32-1).
$score = min((int) $score, 4294967295);
@@ -1420,9 +1437,9 @@ class Database extends BackendPluginBase implements PluginFormInterface {
}
foreach (static::splitIntoWords($text) as $word) {
if ($word) {
- if (Unicode::strlen($word) > 50) {
+ if (mb_strlen($word) > 50) {
$this->getLogger()->warning('An overlong word (more than 50 characters) was encountered while indexing: %word. Since database search servers currently cannot index words of more than 50 characters, the word was truncated for indexing. If this should not be a single word, please make sure the "Tokenizer" processor is enabled and configured correctly for index %index.', ['%word' => $word, '%index' => $index->label()]);
- $word = Unicode::substr($word, 0, 50);
+ $word = mb_substr($word, 0, 50);
}
$tokens[] = new TextToken($word);
}
@@ -1434,12 +1451,12 @@ class Database extends BackendPluginBase implements PluginFormInterface {
// Check for over-long tokens.
$score = $token->getBoost();
$word = $token->getText();
- if (Unicode::strlen($word) > 50) {
+ if (mb_strlen($word) > 50) {
$new_tokens = [];
foreach (static::splitIntoWords($word) as $word) {
- if (Unicode::strlen($word) > 50) {
+ if (mb_strlen($word) > 50) {
$this->getLogger()->warning('An overlong word (more than 50 characters) was encountered while indexing: %word. Since database search servers currently cannot index words of more than 50 characters, the word was truncated for indexing. If this should not be a single word, please make sure the "Tokenizer" processor is enabled and configured correctly for index %index.', ['%word' => $word, '%index' => $index->label()]);
- $word = Unicode::substr($word, 0, 50);
+ $word = mb_substr($word, 0, 50);
}
$new_tokens[] = new TextToken($word, $score);
}
@@ -1459,13 +1476,14 @@ class Database extends BackendPluginBase implements PluginFormInterface {
if ($original_type == 'date') {
return date('c', $value);
}
- if (Unicode::strlen($value) > 255) {
- $value = Unicode::substr($value, 0, 255);
+ if (mb_strlen($value) > 255) {
+ $value = mb_substr($value, 0, 255);
$this->getLogger()->warning('An overlong value (more than 255 characters) was encountered while indexing: %value. Database search servers currently cannot index such values correctly – the value was therefore trimmed to the allowed length.', ['%value' => $value]);
}
return $value;
case 'integer':
+ case 'date':
case 'duration':
case 'decimal':
return 0 + $value;
@@ -1473,12 +1491,6 @@ class Database extends BackendPluginBase implements PluginFormInterface {
case 'boolean':
return $value ? 1 : 0;
- case 'date':
- if (is_numeric($value) || !$value) {
- return 0 + $value;
- }
- return strtotime($value);
-
default:
throw new SearchApiException("Unknown field type '$type'.");
}
@@ -1791,7 +1803,7 @@ class Database extends BackendPluginBase implements PluginFormInterface {
if (is_numeric($processed_keys)) {
return ltrim($processed_keys, '-0');
}
- elseif (Unicode::strlen($processed_keys) < $this->configuration['min_chars']) {
+ elseif (mb_strlen($processed_keys) < $this->configuration['min_chars']) {
$this->ignored[$keys] = 1;
return NULL;
}
@@ -1886,8 +1898,9 @@ class Database extends BackendPluginBase implements PluginFormInterface {
$db_query = NULL;
$mul_words = FALSE;
$neg_nested = $neg && $conj == 'AND';
- $match_parts = !empty($this->configuration['partial_matches']);
+ $match_parts = $this->configuration['matching'] !== 'words';
$keyword_hits = [];
+ $prefix_search = $this->configuration['matching'] === 'prefix';
foreach ($keys as $i => $key) {
if (!Element::child($i)) {
@@ -1944,7 +1957,9 @@ class Database extends BackendPluginBase implements PluginFormInterface {
}
foreach ($words as $i => $word) {
- $db_or->condition('t.word', '%' . $this->database->escapeLike($word) . '%', 'LIKE');
+ $like = $this->database->escapeLike($word);
+ $like = $prefix_search ? "$like%" : "%$like%";
+ $db_or->condition('t.word', $like, 'LIKE');
// Add an expression for each keyword that shows whether the indexed
// word matches that particular keyword. That way we don't return a
@@ -2547,8 +2562,8 @@ class Database extends BackendPluginBase implements PluginFormInterface {
// Make the input lowercase as the indexed data is (usually) also all
// lowercase.
- $incomplete_key = Unicode::strtolower($incomplete_key);
- $user_input = Unicode::strtolower($user_input);
+ $incomplete_key = mb_strtolower($incomplete_key);
+ $user_input = mb_strtolower($user_input);
// Decide which methods we want to use.
if ($incomplete_key && $settings['suggest_suffix']) {
@@ -2578,12 +2593,12 @@ class Database extends BackendPluginBase implements PluginFormInterface {
$query->keys($user_input);
}
// To avoid suggesting incomplete words, we have to temporarily disable
- // the "partial_matches" option. There should be no way we'll save the
- // server during the createDbQuery() call, so this should be safe.
+ // partial matching. There should be no way we'll save the server during
+ // the createDbQuery() call, so this should be safe.
$configuration = $this->configuration;
$db_query = NULL;
try {
- $this->configuration['partial_matches'] = FALSE;
+ $this->configuration['matching'] = 'words';
$db_query = $this->createDbQuery($query, $fields);
$this->configuration = $configuration;
diff --git a/sites/all/modules/contrib/search/search_api/modules/search_api_db/tests/search_api_db_test_autocomplete/search_api_db_test_autocomplete.info.yml b/sites/all/modules/contrib/search/search_api/modules/search_api_db/tests/search_api_db_test_autocomplete/search_api_db_test_autocomplete.info.yml
index d1793e789..8ca25ceda 100644
--- a/sites/all/modules/contrib/search/search_api/modules/search_api_db/tests/search_api_db_test_autocomplete/search_api_db_test_autocomplete.info.yml
+++ b/sites/all/modules/contrib/search/search_api/modules/search_api_db/tests/search_api_db_test_autocomplete/search_api_db_test_autocomplete.info.yml
@@ -8,8 +8,8 @@ dependencies:
# core: 8.x
hidden: true
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/modules/search_api_db/tests/src/Kernel/BackendTest.php b/sites/all/modules/contrib/search/search_api/modules/search_api_db/tests/src/Kernel/BackendTest.php
index d6ac55080..6d2a76602 100644
--- a/sites/all/modules/contrib/search/search_api/modules/search_api_db/tests/src/Kernel/BackendTest.php
+++ b/sites/all/modules/contrib/search/search_api/modules/search_api_db/tests/src/Kernel/BackendTest.php
@@ -4,6 +4,7 @@ namespace Drupal\Tests\search_api_db\Kernel;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Database\Database as CoreDatabase;
+use Drupal\search_api\Entity\Index;
use Drupal\search_api\Entity\Server;
use Drupal\search_api\IndexInterface;
use Drupal\search_api\Item\ItemInterface;
@@ -73,6 +74,8 @@ class BackendTest extends BackendTestBase {
$this->checkMultiValuedInfo();
$this->editServerPartial();
$this->searchSuccessPartial();
+ $this->editServerStartsWith();
+ $this->searchSuccessStartsWith();
$this->editServerMinChars();
$this->searchSuccessMinChars();
$this->checkUnknownOperator();
@@ -89,6 +92,7 @@ class BackendTest extends BackendTestBase {
$this->regressionTest2846932();
$this->regressionTest2926733();
$this->regressionTest2938646();
+ $this->regressionTest2925464();
}
/**
@@ -205,14 +209,11 @@ class BackendTest extends BackendTestBase {
/**
* Edits the server to enable partial matches.
- *
- * @param bool $enable
- * (optional) Whether partial matching should be enabled or disabled.
*/
- protected function editServerPartial($enable = TRUE) {
+ protected function editServerPartial() {
$server = $this->getServer();
$backend_config = $server->getBackendConfig();
- $backend_config['partial_matches'] = $enable;
+ $backend_config['matching'] = 'partial';
$server->setBackendConfig($backend_config);
$this->assertTrue((bool) $server->save(), 'The server was successfully edited.');
$this->resetEntityCache();
@@ -241,7 +242,7 @@ class BackendTest extends BackendTestBase {
$this->assertResults([], $results, 'Partial search for »foo nonexistent«');
$results = $this->buildSearch('bar nonexistent')->execute();
- $this->assertResults([], $results, 'Partial search for »foo nonexistent«');
+ $this->assertResults([], $results, 'Partial search for »bar nonexistent«');
$keys = [
'#conjunction' => 'AND',
@@ -269,6 +270,69 @@ class BackendTest extends BackendTestBase {
$this->assertResults([1, 2, 3, 4], $results, 'Partial search with multi-field fulltext filter');
}
+ /**
+ * Edits the server to enable prefix matching.
+ */
+ protected function editServerStartsWith() {
+ $server = $this->getServer();
+ $backend_config = $server->getBackendConfig();
+ $backend_config['matching'] = 'prefix';
+ $server->setBackendConfig($backend_config);
+ $this->assertTrue((bool) $server->save(), 'The server was successfully edited.');
+ $this->resetEntityCache();
+ }
+
+ /**
+ * Tests whether prefix matching works.
+ */
+ protected function searchSuccessStartsWith() {
+ $results = $this->buildSearch('foobaz')->range(0, 1)->execute();
+ $this->assertResults([1], $results, 'Prefix search for »foobaz«');
+
+ $results = $this->buildSearch('foo', [], [], FALSE)
+ ->sort('search_api_relevance', QueryInterface::SORT_DESC)
+ ->sort('id')
+ ->execute();
+ $this->assertResults([1, 2, 4, 3, 5], $results, 'Prefix search for »foo«');
+
+ $results = $this->buildSearch('foo tes')->execute();
+ $this->assertResults([1, 2, 3, 4], $results, 'Prefix search for »foo tes«');
+
+ $results = $this->buildSearch('oob est')->execute();
+ $this->assertResults([], $results, 'Prefix search for »oob est«');
+
+ $results = $this->buildSearch('foo nonexistent')->execute();
+ $this->assertResults([], $results, 'Prefix search for »foo nonexistent«');
+
+ $results = $this->buildSearch('bar nonexistent')->execute();
+ $this->assertResults([], $results, 'Prefix search for »bar nonexistent«');
+
+ $keys = [
+ '#conjunction' => 'AND',
+ 'foob',
+ [
+ '#conjunction' => 'OR',
+ 'tes',
+ 'nonexistent',
+ ],
+ ];
+ $results = $this->buildSearch($keys)->execute();
+ $this->assertResults([1, 2, 3], $results, 'Prefix search for complex keys');
+
+ $results = $this->buildSearch('foo', ['category,item_category'], [], FALSE)
+ ->sort('id', QueryInterface::SORT_DESC)
+ ->execute();
+ $this->assertResults([2, 1], $results, 'Prefix search for »foo« with additional filter');
+
+ $query = $this->buildSearch();
+ $conditions = $query->createConditionGroup('OR');
+ $conditions->addCondition('name', 'test');
+ $conditions->addCondition('body', 'test');
+ $query->addConditionGroup($conditions);
+ $results = $query->execute();
+ $this->assertResults([1, 2, 3, 4], $results, 'Prefix search with multi-field fulltext filter');
+ }
+
/**
* Edits the server to change the "Minimum word length" setting.
*/
@@ -276,7 +340,7 @@ class BackendTest extends BackendTestBase {
$server = $this->getServer();
$backend_config = $server->getBackendConfig();
$backend_config['min_chars'] = 4;
- $backend_config['partial_matches'] = FALSE;
+ $backend_config['matching'] = 'words';
$server->setBackendConfig($backend_config);
$success = (bool) $server->save();
$this->assertTrue($success, 'The server was successfully edited.');
@@ -556,6 +620,23 @@ class BackendTest extends BackendTestBase {
$this->assertEquals(2 * $old_score, $new_score);
}
+ /**
+ * Tests changing of field types.
+ *
+ * @see https://www.drupal.org/node/2925464
+ */
+ protected function regressionTest2925464() {
+ $index = $this->getIndex();
+
+ $index->getField('category')->setType('integer');
+ $index->save();
+
+ $index->getField('category')->setType('string');
+ $index->save();
+
+ $this->indexItems($index->id());
+ }
+
/**
* {@inheritdoc}
*/
@@ -750,4 +831,59 @@ class BackendTest extends BackendTestBase {
$this->assertEquals($class, get_class($dbms_comp2));
}
+ /**
+ * Tests whether indexing of dates works correctly.
+ */
+ public function testDateIndexing() {
+ // Load all existing entities.
+ $storage = \Drupal::entityTypeManager()
+ ->getStorage('entity_test_mulrev_changed');
+ $storage->delete($storage->loadMultiple());
+
+ $index = Index::load('database_search_index');
+ $index->getField('name')->setType('date');
+ $index->save();
+
+ // Simulate date field creation in one timezone and indexing in another.
+ date_default_timezone_set('America/Chicago');
+
+ // Test different input values, similar to @dataProvider (but with less
+ // overhead).
+ $t = 1400000000;
+ $f = 'Y-m-d H:i:s';
+ $test_values = [
+ 'null' => [NULL, NULL],
+ 'timestamp' => [$t, $t],
+ 'string timestamp' => ["$t", $t],
+ 'float timestamp' => [$t + 0.12, $t],
+ 'date string' => [gmdate($f, $t), $t],
+ 'date string with timezone' => [date($f . 'P', $t), $t],
+ ];
+
+ // Get storage information for quickly checking the indexed value.
+ $db_info = $this->getIndexDbInfo();
+ $table = $db_info['index_table'];
+ $column = $db_info['field_tables']['name']['column'];
+ $sql = "SELECT $column FROM {{$table}} WHERE item_id = :id";
+
+ $id = 0;
+ date_default_timezone_set('Asia/Seoul');
+ foreach ($test_values as $label => list($field_value, $expected)) {
+ $entity = $this->addTestEntity(++$id, [
+ 'name' => $field_value,
+ 'type' => 'item',
+ ]);
+ $item_id = $this->getItemIds([$id])[0];
+ $index->indexSpecificItems([$item_id => $entity->getTypedData()]);
+ $args[':id'] = $item_id;
+ $indexed_value = \Drupal::database()->query($sql, $args)->fetchField();
+ if ($expected === NULL) {
+ $this->assertSame($expected, $indexed_value, "Indexing of date field with $label value.");
+ }
+ else {
+ $this->assertEquals($expected, $indexed_value, "Indexing of date field with $label value.");
+ }
+ }
+ }
+
}
diff --git a/sites/all/modules/contrib/search/search_api/modules/search_api_views_taxonomy/search_api_views_taxonomy.info.yml b/sites/all/modules/contrib/search/search_api/modules/search_api_views_taxonomy/search_api_views_taxonomy.info.yml
index 813a86989..ec79a41cc 100644
--- a/sites/all/modules/contrib/search/search_api/modules/search_api_views_taxonomy/search_api_views_taxonomy.info.yml
+++ b/sites/all/modules/contrib/search/search_api/modules/search_api_views_taxonomy/search_api_views_taxonomy.info.yml
@@ -11,8 +11,8 @@ dependencies:
- drupal:taxonomy
- drupal:views
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/phpcs.xml b/sites/all/modules/contrib/search/search_api/phpcs.xml
index 6449d5959..5ff5509b0 100644
--- a/sites/all/modules/contrib/search/search_api/phpcs.xml
+++ b/sites/all/modules/contrib/search/search_api/phpcs.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/sites/all/modules/contrib/search/search_api/search_api.api.php b/sites/all/modules/contrib/search/search_api/search_api.api.php
index 7860c9d3e..5ec343328 100644
--- a/sites/all/modules/contrib/search/search_api/search_api.api.php
+++ b/sites/all/modules/contrib/search/search_api/search_api.api.php
@@ -241,7 +241,8 @@ function hook_search_api_index_items_alter(\Drupal\search_api\IndexInterface $in
'%index' => $index->label(),
'@ids' => implode(', ', array_keys($items)),
];
- drupal_set_message(t('Indexing items on index %index with the following IDs: @ids', $arguments));
+ $message = t('Indexing items on index %index with the following IDs: @ids', $arguments);
+ \Drupal::messenger()->addStatus($message);
}
/**
@@ -257,7 +258,8 @@ function hook_search_api_items_indexed(\Drupal\search_api\IndexInterface $index,
// Note that this is just an example, and would only work if there are only
// nodes indexed in that index (and even then the printed IDs would probably
// not be as expected).
- drupal_set_message(t('Nodes indexed: @ids.', implode(', ', $item_ids)));
+ $message = t('Nodes indexed: @ids.', implode(', ', $item_ids));
+ \Drupal::messenger()->addStatus($message);
}
}
diff --git a/sites/all/modules/contrib/search/search_api/search_api.info.yml b/sites/all/modules/contrib/search/search_api/search_api.info.yml
index f7693e5d1..018a25860 100644
--- a/sites/all/modules/contrib/search/search_api/search_api.info.yml
+++ b/sites/all/modules/contrib/search/search_api/search_api.info.yml
@@ -5,10 +5,10 @@ package: Search
# core: 8.x
configure: search_api.overview
dependencies:
- - system (>=8.4)
+ - system (>=8.5)
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/search_api.module b/sites/all/modules/contrib/search/search_api/search_api.module
index d2bd0e98f..8aea28d8c 100644
--- a/sites/all/modules/contrib/search/search_api/search_api.module
+++ b/sites/all/modules/contrib/search/search_api/search_api.module
@@ -572,7 +572,8 @@ function search_api_view_insert(ViewEntityInterface $view) {
}
if ($change) {
- drupal_set_message(\Drupal::translation()->translate('The selected caching mechanism does not work with views on Search API indexes. Please either use one of the Search API-specific caching options or "None". Caching was turned off for this view.'), 'warning');
+ $warning = t('The selected caching mechanism does not work with views on Search API indexes. Please either use one of the Search API-specific caching options or "None". Caching was turned off for this view.');
+ \Drupal::messenger()->addWarning($warning);
$view->set('display', $displays);
$view->save();
}
diff --git a/sites/all/modules/contrib/search/search_api/search_api.services.yml b/sites/all/modules/contrib/search/search_api/search_api.services.yml
index 92f58db5d..fc37edd1e 100644
--- a/sites/all/modules/contrib/search/search_api/search_api.services.yml
+++ b/sites/all/modules/contrib/search/search_api/search_api.services.yml
@@ -11,7 +11,7 @@ services:
paramconverter.search_api:
class: Drupal\search_api\ParamConverter\SearchApiConverter
- arguments: ['@entity.manager', '@user.shared_tempstore', '@current_user']
+ arguments: ['@entity.manager', '@tempstore.shared', '@current_user']
tags:
- { name: paramconverter, priority: 10 }
lazy: true
@@ -72,7 +72,7 @@ services:
class: Drupal\search_api\Utility\PostRequestIndexing
arguments: ['@entity_type.manager']
tags:
- - { name: event_subscriber }
+ - { name: needs_destruction }
search_api.query_helper:
class: Drupal\search_api\Utility\QueryHelper
@@ -86,7 +86,7 @@ services:
search_api.task_manager:
class: Drupal\search_api\Task\TaskManager
- arguments: ['@entity_type.manager', '@event_dispatcher', '@string_translation']
+ arguments: ['@entity_type.manager', '@event_dispatcher', '@string_translation', '@messenger']
search_api.vbo_view_data_provider:
class: Drupal\search_api\Contrib\ViewsBulkOperationsEventSubscriber
diff --git a/sites/all/modules/contrib/search/search_api/src/Backend/BackendPluginBase.php b/sites/all/modules/contrib/search/search_api/src/Backend/BackendPluginBase.php
index 86758f1ae..e234b2566 100644
--- a/sites/all/modules/contrib/search/search_api/src/Backend/BackendPluginBase.php
+++ b/sites/all/modules/contrib/search/search_api/src/Backend/BackendPluginBase.php
@@ -2,6 +2,7 @@
namespace Drupal\search_api\Backend;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\search_api\Entity\Server;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\LoggerTrait;
@@ -11,6 +12,7 @@ use Drupal\search_api\IndexInterface;
use Drupal\search_api\Plugin\ConfigurablePluginBase;
use Drupal\search_api\ServerInterface;
use Drupal\search_api\Utility\FieldsHelper;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a base class for backend plugins.
@@ -66,6 +68,13 @@ abstract class BackendPluginBase extends ConfigurablePluginBase implements Backe
*/
protected $fieldsHelper;
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface|null
+ */
+ protected $messenger;
+
/**
* {@inheritdoc}
*/
@@ -77,6 +86,19 @@ abstract class BackendPluginBase extends ConfigurablePluginBase implements Backe
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ /** @var static $plugin */
+ $plugin = parent::create($container, $configuration, $plugin_id, $plugin_definition);
+
+ $plugin->setFieldsHelper($container->get('search_api.fields_helper'));
+ $plugin->setMessenger($container->get('messenger'));
+
+ return $plugin;
+ }
+
/**
* Retrieves the fields helper.
*
@@ -100,6 +122,29 @@ abstract class BackendPluginBase extends ConfigurablePluginBase implements Backe
return $this;
}
+ /**
+ * Retrieves the messenger.
+ *
+ * @return \Drupal\Core\Messenger\MessengerInterface
+ * The messenger.
+ */
+ public function getMessenger() {
+ return $this->messenger ?: \Drupal::service('messenger');
+ }
+
+ /**
+ * Sets the messenger.
+ *
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The new messenger.
+ *
+ * @return $this
+ */
+ public function setMessenger(MessengerInterface $messenger) {
+ $this->messenger = $messenger;
+ return $this;
+ }
+
/**
* {@inheritdoc}
*/
@@ -172,7 +217,7 @@ abstract class BackendPluginBase extends ConfigurablePluginBase implements Backe
'%server' => $this->getServer()->label(),
];
$this->logException($e, '%type while deleting items from server %server: @message in %function (line %line of %file).', $vars);
- drupal_set_message($this->t('Deleting some of the items on the server failed. Check the logs for details. The server was still removed.'), 'error');
+ $this->getMessenger()->addError($this->t('Deleting some of the items on the server failed. Check the logs for details. The server was still removed.'));
}
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Backend/BackendSpecificInterface.php b/sites/all/modules/contrib/search/search_api/src/Backend/BackendSpecificInterface.php
index 93e300f94..393e4451d 100644
--- a/sites/all/modules/contrib/search/search_api/src/Backend/BackendSpecificInterface.php
+++ b/sites/all/modules/contrib/search/search_api/src/Backend/BackendSpecificInterface.php
@@ -127,7 +127,7 @@ interface BackendSpecificInterface {
* Notifies the server that an index attached to it has been changed.
*
* If any user action is necessary as a result of this, the method should
- * use drupal_set_message() to notify the user.
+ * set a message to notify the user.
*
* @param \Drupal\search_api\IndexInterface $index
* The updated index.
diff --git a/sites/all/modules/contrib/search/search_api/src/Contrib/RowsOfMultiValueFields.php b/sites/all/modules/contrib/search/search_api/src/Contrib/RowsOfMultiValueFields.php
index a3abcf364..5be2496ba 100644
--- a/sites/all/modules/contrib/search/search_api/src/Contrib/RowsOfMultiValueFields.php
+++ b/sites/all/modules/contrib/search/search_api/src/Contrib/RowsOfMultiValueFields.php
@@ -35,7 +35,7 @@ class RowsOfMultiValueFields extends RowsOfFields implements RenderCellInterface
protected static function arrayToString(array $array) {
$elements = [];
foreach ($array as $element) {
- $elements[] = is_array($element) ? '"' . self::arrayToString($element) . '"' : $element;
+ $elements[] = is_array($element) ? '"' . static::arrayToString($element) . '"' : $element;
}
return implode(',', $elements);
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Controller/IndexController.php b/sites/all/modules/contrib/search/search_api/src/Controller/IndexController.php
index 91cfb5228..26a72dd06 100644
--- a/sites/all/modules/contrib/search/search_api/src/Controller/IndexController.php
+++ b/sites/all/modules/contrib/search/search_api/src/Controller/IndexController.php
@@ -7,6 +7,7 @@ use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\RemoveCommand;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\EventSubscriber\AjaxResponseSubscriber;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\search_api\IndexInterface;
use Drupal\search_api\SearchApiException;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -25,6 +26,13 @@ class IndexController extends ControllerBase {
*/
protected $requestStack;
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface|null
+ */
+ protected $messenger;
+
/**
* {@inheritdoc}
*/
@@ -33,6 +41,7 @@ class IndexController extends ControllerBase {
$controller = parent::create($container);
$controller->setRequestStack($container->get('request_stack'));
+ $controller->setMessenger($container->get('messenger'));
return $controller;
}
@@ -70,6 +79,29 @@ class IndexController extends ControllerBase {
return $this;
}
+ /**
+ * Retrieves the messenger.
+ *
+ * @return \Drupal\Core\Messenger\MessengerInterface
+ * The messenger.
+ */
+ public function getMessenger() {
+ return $this->messenger ?: \Drupal::service('messenger');
+ }
+
+ /**
+ * Sets the messenger.
+ *
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The new messenger.
+ *
+ * @return $this
+ */
+ public function setMessenger(MessengerInterface $messenger) {
+ $this->messenger = $messenger;
+ return $this;
+ }
+
/**
* Displays information about a search index.
*
@@ -125,11 +157,11 @@ class IndexController extends ControllerBase {
// enabled if its server is not set or disabled.
if ($search_api_index->status()) {
// Notify the user about the status change.
- drupal_set_message($this->t('The search index %name has been enabled.', ['%name' => $search_api_index->label()]));
+ $this->getMessenger()->addStatus($this->t('The search index %name has been enabled.', ['%name' => $search_api_index->label()]));
}
else {
// Notify the user that the status change did not succeed.
- drupal_set_message($this->t('The search index %name could not be enabled. Check if its server is set and enabled.', ['%name' => $search_api_index->label()]));
+ $this->getMessenger()->addStatus($this->t('The search index %name could not be enabled. Check if its server is set and enabled.', ['%name' => $search_api_index->label()]));
}
// Redirect to the index's "View" page.
@@ -162,7 +194,7 @@ class IndexController extends ControllerBase {
}
catch (SearchApiException $e) {
$args['%field'] = $fields[$field_id]->getLabel();
- drupal_set_message($this->t('The field %field is locked and cannot be removed.', $args), 'error');
+ $this->getMessenger()->addError($this->t('The field %field is locked and cannot be removed.', $args));
}
}
else {
diff --git a/sites/all/modules/contrib/search/search_api/src/Controller/ServerController.php b/sites/all/modules/contrib/search/search_api/src/Controller/ServerController.php
index 8cc5ed22c..d17bcbf94 100644
--- a/sites/all/modules/contrib/search/search_api/src/Controller/ServerController.php
+++ b/sites/all/modules/contrib/search/search_api/src/Controller/ServerController.php
@@ -4,13 +4,57 @@ namespace Drupal\search_api\Controller;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\search_api\ServerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides block routines for search server-specific routes.
*/
class ServerController extends ControllerBase {
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface|null
+ */
+ protected $messenger;
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ /** @var static $controller */
+ $controller = parent::create($container);
+
+ $controller->setMessenger($container->get('messenger'));
+
+ return $controller;
+ }
+
+ /**
+ * Retrieves the messenger.
+ *
+ * @return \Drupal\Core\Messenger\MessengerInterface
+ * The messenger.
+ */
+ public function getMessenger() {
+ return $this->messenger ?: \Drupal::service('messenger');
+ }
+
+ /**
+ * Sets the messenger.
+ *
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The new messenger.
+ *
+ * @return $this
+ */
+ public function setMessenger(MessengerInterface $messenger) {
+ $this->messenger = $messenger;
+ return $this;
+ }
+
/**
* Displays information about a search server.
*
@@ -65,7 +109,7 @@ class ServerController extends ControllerBase {
$search_api_server->setStatus(TRUE)->save();
// Notify the user about the status change.
- drupal_set_message($this->t('The search server %name has been enabled.', ['%name' => $search_api_server->label()]));
+ $this->getMessenger()->addStatus($this->t('The search server %name has been enabled.', ['%name' => $search_api_server->label()]));
// Redirect to the server's "View" page.
$url = $search_api_server->toUrl('canonical');
diff --git a/sites/all/modules/contrib/search/search_api/src/Entity/Index.php b/sites/all/modules/contrib/search/search_api/src/Entity/Index.php
index e0eab54de..7765e0797 100644
--- a/sites/all/modules/contrib/search/search_api/src/Entity/Index.php
+++ b/sites/all/modules/contrib/search/search_api/src/Entity/Index.php
@@ -18,7 +18,7 @@ use Drupal\search_api\SearchApiException;
use Drupal\search_api\ServerInterface;
use Drupal\search_api\Tracker\TrackerInterface;
use Drupal\search_api\Utility\Utility;
-use Drupal\user\TempStoreException;
+use Drupal\Core\TempStore\TempStoreException;
use Drupal\views\Views;
/**
@@ -89,6 +89,7 @@ use Drupal\views\Views;
*/
class Index extends ConfigEntityBase implements IndexInterface {
+ use InstallingTrait;
use LoggerTrait;
/**
@@ -914,15 +915,19 @@ class Index extends ConfigEntityBase implements IndexInterface {
if ($this->hasValidTracker() && !$this->isReadOnly()) {
$tracker = $this->getTrackerInstance();
$next_set = $tracker->getRemainingItems($limit, $datasource_id);
+ if (!$next_set) {
+ return 0;
+ }
$items = $this->loadItemsMultiple($next_set);
- if ($items) {
- try {
- return count($this->indexSpecificItems($items));
- }
- catch (SearchApiException $e) {
- $variables['%index'] = $this->label();
- $this->logException($e, '%type while trying to index items on index %index: @message in %function (line %line of %file)', $variables);
- }
+ if (!$items) {
+ return 0;
+ }
+ try {
+ return count($this->indexSpecificItems($items));
+ }
+ catch (SearchApiException $e) {
+ $variables['%index'] = $this->label();
+ $this->logException($e, '%type while trying to index items on index %index: @message in %function (line %line of %file)', $variables);
}
}
return 0;
@@ -1197,9 +1202,10 @@ class Index extends ConfigEntityBase implements IndexInterface {
* {@inheritdoc}
*/
public function preSave(EntityStorageInterface $storage) {
- // If we are in the process of syncing, we shouldn't change any entity
+ // If we are in the process of syncing, or in the process of installing
+ // configuration from an extension, we shouldn't change any entity
// properties (or other configuration).
- if ($this->isSyncing()) {
+ if ($this->isSyncing() || $this->isInstallingFromExtension()) {
parent::preSave($storage);
return;
}
@@ -1559,8 +1565,8 @@ class Index extends ConfigEntityBase implements IndexInterface {
\Drupal::cache('discovery')->delete('views:wizard');
}
- /** @var \Drupal\user\SharedTempStore $temp_store */
- $temp_store = \Drupal::service('user.shared_tempstore')->get('search_api_index');
+ /** @var \Drupal\Core\TempStore\SharedTempStore $temp_store */
+ $temp_store = \Drupal::service('tempstore.shared')->get('search_api_index');
foreach ($entities as $entity) {
try {
$temp_store->delete($entity->id());
diff --git a/sites/all/modules/contrib/search/search_api/src/Entity/InstallingTrait.php b/sites/all/modules/contrib/search/search_api/src/Entity/InstallingTrait.php
new file mode 100644
index 000000000..ab3e94c17
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api/src/Entity/InstallingTrait.php
@@ -0,0 +1,38 @@
+isNew() && !empty($this->_core));
+ }
+
+ /**
+ * Determines whether the entity is new.
+ *
+ * Usually an entity is new if no ID exists for it yet. However, entities may
+ * be enforced to be new with existing IDs too.
+ *
+ * @return bool
+ * TRUE if the entity is new, or FALSE if the entity has already been saved.
+ *
+ * @see \Drupal\Core\Entity\EntityInterface::isNew()
+ */
+ abstract public function isNew();
+
+}
diff --git a/sites/all/modules/contrib/search/search_api/src/Entity/Server.php b/sites/all/modules/contrib/search/search_api/src/Entity/Server.php
index 4515e1741..74b7e5366 100644
--- a/sites/all/modules/contrib/search/search_api/src/Entity/Server.php
+++ b/sites/all/modules/contrib/search/search_api/src/Entity/Server.php
@@ -62,6 +62,7 @@ use Drupal\search_api\Utility\Utility;
*/
class Server extends ConfigEntityBase implements ServerInterface {
+ use InstallingTrait;
use LoggerTrait;
/**
@@ -500,6 +501,7 @@ class Server extends ConfigEntityBase implements ServerInterface {
// If the server is being disabled, also disable all its indexes.
if (!$this->isSyncing()
+ && !$this->isInstallingFromExtension()
&& !isset($overrides['status'])
&& !$this->status()
&& $this->original->status()) {
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/FieldConfigurationForm.php b/sites/all/modules/contrib/search/search_api/src/Form/FieldConfigurationForm.php
index 1e5555773..608bb7ba5 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/FieldConfigurationForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/FieldConfigurationForm.php
@@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\search_api\Processor\ConfigurablePropertyInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -44,11 +45,11 @@ class FieldConfigurationForm extends EntityForm {
protected $formIdAttribute;
/**
- * {@inheritdoc}
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
*/
- public function getFormId() {
- return 'search_api_field_config';
- }
+ protected $messenger;
/**
* Constructs a FieldConfigurationForm object.
@@ -61,12 +62,15 @@ class FieldConfigurationForm extends EntityForm {
* The date formatter.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
*/
- public function __construct(EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, DateFormatterInterface $date_formatter, RequestStack $request_stack) {
+ public function __construct(EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, DateFormatterInterface $date_formatter, RequestStack $request_stack, MessengerInterface $messenger) {
$this->entityTypeManager = $entity_type_manager;
$this->renderer = $renderer;
$this->dateFormatter = $date_formatter;
$this->requestStack = $request_stack;
+ $this->messenger = $messenger;
}
/**
@@ -77,8 +81,23 @@ class FieldConfigurationForm extends EntityForm {
$renderer = $container->get('renderer');
$date_formatter = $container->get('date.formatter');
$request_stack = $container->get('request_stack');
+ $messenger = $container->get('messenger');
- return new static($entity_type_manager, $renderer, $date_formatter, $request_stack);
+ return new static($entity_type_manager, $renderer, $date_formatter, $request_stack, $messenger);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBaseFormId() {
+ return NULL;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'search_api_field_config';
}
/**
@@ -179,7 +198,7 @@ class FieldConfigurationForm extends EntityForm {
$property = $field->getDataDefinition();
$property->submitConfigurationForm($field, $form, $form_state);
- drupal_set_message($this->t('The field configuration was successfully saved.'));
+ $this->messenger->addStatus($this->t('The field configuration was successfully saved.'));
if ($this->getRequest()->query->get('modal_redirect')) {
$url = $this->entity->toUrl('add-fields-ajax')
->setOption('query', [
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/IndexAddFieldsForm.php b/sites/all/modules/contrib/search/search_api/src/Form/IndexAddFieldsForm.php
index 8966d6d1f..aa06680e3 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/IndexAddFieldsForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/IndexAddFieldsForm.php
@@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\TypedData\EntityDataDefinitionInterface;
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
use Drupal\Core\TypedData\DataReferenceDefinitionInterface;
@@ -75,18 +76,11 @@ class IndexAddFieldsForm extends EntityForm {
protected $formIdAttribute;
/**
- * {@inheritdoc}
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
*/
- public function getFormId() {
- return 'search_api_index_add_fields';
- }
-
- /**
- * {@inheritdoc}
- */
- public function getBaseFormId() {
- return NULL;
- }
+ protected $messenger;
/**
* Constructs an IndexAddFieldsForm object.
@@ -101,15 +95,18 @@ class IndexAddFieldsForm extends EntityForm {
* The renderer to use.
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
* The date formatter.
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
* @param array $parameters
* The parameters for this page request.
*/
- public function __construct(EntityTypeManagerInterface $entity_type_manager, FieldsHelperInterface $fields_helper, DataTypeHelperInterface $data_type_helper, RendererInterface $renderer, DateFormatterInterface $date_formatter, array $parameters) {
+ public function __construct(EntityTypeManagerInterface $entity_type_manager, FieldsHelperInterface $fields_helper, DataTypeHelperInterface $data_type_helper, RendererInterface $renderer, DateFormatterInterface $date_formatter, MessengerInterface $messenger, array $parameters) {
$this->entityTypeManager = $entity_type_manager;
$this->fieldsHelper = $fields_helper;
$this->dataTypeHelper = $data_type_helper;
$this->renderer = $renderer;
$this->dateFormatter = $date_formatter;
+ $this->messenger = $messenger;
$this->parameters = $parameters;
}
@@ -123,9 +120,24 @@ class IndexAddFieldsForm extends EntityForm {
$renderer = $container->get('renderer');
$date_formatter = $container->get('date.formatter');
$request_stack = $container->get('request_stack');
+ $messenger = $container->get('messenger');
$parameters = $request_stack->getCurrentRequest()->query->all();
- return new static($entity_type_manager, $fields_helper, $data_type_helper, $renderer, $date_formatter, $parameters);
+ return new static($entity_type_manager, $fields_helper, $data_type_helper, $renderer, $date_formatter, $messenger, $parameters);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBaseFormId() {
+ return NULL;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'search_api_index_add_fields';
}
/**
@@ -480,7 +492,7 @@ class IndexAddFieldsForm extends EntityForm {
}
$args['%label'] = $field->getLabel();
- drupal_set_message($this->t('Field %label was added to the index.', $args));
+ $this->messenger->addStatus($this->t('Field %label was added to the index.', $args));
}
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/IndexBreakLockForm.php b/sites/all/modules/contrib/search/search_api/src/Form/IndexBreakLockForm.php
index 70892d454..66e942ee9 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/IndexBreakLockForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/IndexBreakLockForm.php
@@ -5,8 +5,9 @@ namespace Drupal\search_api\Form;
use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\RendererInterface;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -14,10 +15,17 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*/
class IndexBreakLockForm extends EntityConfirmFormBase {
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
/**
* The shared temporary storage for unsaved search indexes.
*
- * @var \Drupal\user\SharedTempStore
+ * @var \Drupal\Core\TempStore\SharedTempStore
*/
protected $tempStore;
@@ -38,28 +46,32 @@ class IndexBreakLockForm extends EntityConfirmFormBase {
/**
* Constructs an IndexBreakLockForm object.
*
- * @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory
* The factory for shared temporary storages.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The Entity manager.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer to use.
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
*/
- public function __construct(SharedTempStoreFactory $temp_store_factory, EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer) {
+ public function __construct(SharedTempStoreFactory $temp_store_factory, EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, MessengerInterface $messenger) {
$this->tempStore = $temp_store_factory->get('search_api_index');
$this->entityTypeManager = $entity_type_manager;
$this->renderer = $renderer;
+ $this->messenger = $messenger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
- $temp_store_factory = $container->get('user.shared_tempstore');
+ $temp_store_factory = $container->get('tempstore.shared');
$entity_type_manager = $container->get('entity_type.manager');
$renderer = $container->get('renderer');
+ $messenger = $container->get('messenger');
- return new static($temp_store_factory, $entity_type_manager, $renderer);
+ return new static($temp_store_factory, $entity_type_manager, $renderer, $messenger);
}
/**
@@ -120,7 +132,7 @@ class IndexBreakLockForm extends EntityConfirmFormBase {
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->tempStore->delete($this->entity->id());
$form_state->setRedirectUrl($this->entity->toUrl('fields'));
- drupal_set_message($this->t('The lock has been broken. You may now edit this search index.'));
+ $this->messenger->addStatus($this->t('The lock has been broken. You may now edit this search index.'));
}
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/IndexClearConfirmForm.php b/sites/all/modules/contrib/search/search_api/src/Form/IndexClearConfirmForm.php
index 528ba3497..5c497d190 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/IndexClearConfirmForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/IndexClearConfirmForm.php
@@ -7,12 +7,24 @@ use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\Core\Utility\Error;
use Drupal\search_api\SearchApiException;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a confirm form for clearing an index.
*/
class IndexClearConfirmForm extends EntityConfirmFormBase {
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ $form = parent::create($container);
+
+ $form->setMessenger($container->get('messenger'));
+
+ return $form;
+ }
+
/**
* {@inheritdoc}
*/
@@ -43,10 +55,11 @@ class IndexClearConfirmForm extends EntityConfirmFormBase {
try {
$index->clear();
- drupal_set_message($this->t('All items were successfully deleted from search index %name.', ['%name' => $index->label()]));
+ $this->messenger()
+ ->addStatus($this->t('All items were successfully deleted from search index %name.', ['%name' => $index->label()]));
}
catch (SearchApiException $e) {
- drupal_set_message($this->t('Failed to clear the search index %name.', ['%name' => $index->label()]), 'error');
+ $this->messenger->addError($this->t('Failed to clear the search index %name.', ['%name' => $index->label()]));
$message = '%type while trying to clear the index %name: @message in %function (line %line of %file)';
$variables = [
'%name' => $index->label(),
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/IndexDeleteConfirmForm.php b/sites/all/modules/contrib/search/search_api/src/Form/IndexDeleteConfirmForm.php
index 7709bdbb8..99fd8fa25 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/IndexDeleteConfirmForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/IndexDeleteConfirmForm.php
@@ -4,13 +4,41 @@ namespace Drupal\search_api\Form;
use Drupal\Core\Entity\EntityDeleteForm;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Url;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a confirm form for deleting an index.
*/
class IndexDeleteConfirmForm extends EntityDeleteForm {
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
+ /**
+ * Constructs an IndexDeleteConfirmForm object.
+ *
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
+ */
+ public function __construct(MessengerInterface $messenger) {
+ $this->messenger = $messenger;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ $messenger = $container->get('messenger');
+
+ return new static($messenger);
+ }
+
/**
* {@inheritdoc}
*/
@@ -37,7 +65,7 @@ class IndexDeleteConfirmForm extends EntityDeleteForm {
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->entity->delete();
- drupal_set_message($this->t('The search index %name has been removed.', ['%name' => $this->entity->label()]));
+ $this->messenger->addStatus($this->t('The search index %name has been removed.', ['%name' => $this->entity->label()]));
$form_state->setRedirect('search_api.overview');
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/IndexDisableConfirmForm.php b/sites/all/modules/contrib/search/search_api/src/Form/IndexDisableConfirmForm.php
index d9aa56dc4..ad00bde2c 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/IndexDisableConfirmForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/IndexDisableConfirmForm.php
@@ -4,13 +4,41 @@ namespace Drupal\search_api\Form;
use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Url;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a confirm form for disabling an index.
*/
class IndexDisableConfirmForm extends EntityConfirmFormBase {
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
+ /**
+ * Constructs an IndexDisableConfirmForm object.
+ *
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
+ */
+ public function __construct(MessengerInterface $messenger) {
+ $this->messenger = $messenger;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ $messenger = $container->get('messenger');
+
+ return new static($messenger);
+ }
+
/**
* {@inheritdoc}
*/
@@ -47,7 +75,7 @@ class IndexDisableConfirmForm extends EntityConfirmFormBase {
$entity = $this->entity;
$entity->setStatus(FALSE)->save();
- drupal_set_message($this->t('The search index %name has been disabled.', ['%name' => $this->entity->label()]));
+ $this->messenger->addStatus($this->t('The search index %name has been disabled.', ['%name' => $this->entity->label()]));
$form_state->setRedirect('search_api.overview');
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/IndexFieldsForm.php b/sites/all/modules/contrib/search/search_api/src/Form/IndexFieldsForm.php
index eba7a48be..cab71b055 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/IndexFieldsForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/IndexFieldsForm.php
@@ -8,6 +8,7 @@ use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Url;
use Drupal\search_api\DataType\DataTypePluginManager;
@@ -16,7 +17,7 @@ use Drupal\search_api\SearchApiException;
use Drupal\search_api\UnsavedConfigurationInterface;
use Drupal\search_api\Utility\DataTypeHelperInterface;
use Drupal\search_api\Utility\FieldsHelperInterface;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -36,7 +37,7 @@ class IndexFieldsForm extends EntityForm {
/**
* The shared temporary storage for unsaved search indexes.
*
- * @var \Drupal\user\SharedTempStore
+ * @var \Drupal\Core\TempStore\SharedTempStore
*/
protected $tempStore;
@@ -62,23 +63,16 @@ class IndexFieldsForm extends EntityForm {
protected $fieldsHelper;
/**
- * {@inheritdoc}
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
*/
- public function getFormId() {
- return 'search_api_index_fields';
- }
-
- /**
- * {@inheritdoc}
- */
- public function getBaseFormId() {
- return NULL;
- }
+ protected $messenger;
/**
* Constructs an IndexFieldsForm object.
*
- * @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory
* The factory for shared temporary storages.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
@@ -92,8 +86,10 @@ class IndexFieldsForm extends EntityForm {
* The data type helper.
* @param \Drupal\search_api\Utility\FieldsHelperInterface $fields_helper
* The fields helper.
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
*/
- public function __construct(SharedTempStoreFactory $temp_store_factory, EntityTypeManagerInterface $entity_type_manager, DataTypePluginManager $data_type_plugin_manager, RendererInterface $renderer, DateFormatterInterface $date_formatter, DataTypeHelperInterface $data_type_helper, FieldsHelperInterface $fields_helper) {
+ public function __construct(SharedTempStoreFactory $temp_store_factory, EntityTypeManagerInterface $entity_type_manager, DataTypePluginManager $data_type_plugin_manager, RendererInterface $renderer, DateFormatterInterface $date_formatter, DataTypeHelperInterface $data_type_helper, FieldsHelperInterface $fields_helper, MessengerInterface $messenger) {
$this->tempStore = $temp_store_factory->get('search_api_index');
$this->entityTypeManager = $entity_type_manager;
$this->dataTypePluginManager = $data_type_plugin_manager;
@@ -101,21 +97,37 @@ class IndexFieldsForm extends EntityForm {
$this->dateFormatter = $date_formatter;
$this->dataTypeHelper = $data_type_helper;
$this->fieldsHelper = $fields_helper;
+ $this->messenger = $messenger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
- $temp_store_factory = $container->get('user.shared_tempstore');
+ $temp_store_factory = $container->get('tempstore.shared');
$entity_type_manager = $container->get('entity_type.manager');
$data_type_plugin_manager = $container->get('plugin.manager.search_api.data_type');
$renderer = $container->get('renderer');
$date_formatter = $container->get('date.formatter');
$data_type_helper = $container->get('search_api.data_type_helper');
$fields_helper = $container->get('search_api.fields_helper');
+ $messenger = $container->get('messenger');
- return new static($temp_store_factory, $entity_type_manager, $data_type_plugin_manager, $renderer, $date_formatter, $data_type_helper, $fields_helper);
+ return new static($temp_store_factory, $entity_type_manager, $data_type_plugin_manager, $renderer, $date_formatter, $data_type_helper, $fields_helper, $messenger);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getBaseFormId() {
+ return NULL;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'search_api_index_fields';
}
/**
@@ -155,7 +167,7 @@ class IndexFieldsForm extends EntityForm {
],
];
- $form['description']['#markup'] = $this->t('
The data type of a field determines how it can be used for searching and filtering. The boost is used to give additional weight to certain fields, for example titles or tags.
For information about the data types available for indexing, see the data types table at the bottom of the page.
The data type of a field determines how it can be used for searching and filtering. The boost is used to give additional weight to certain fields, for example titles or tags.
For information about the data types available for indexing, see the data types table at the bottom of the page.
', [':url' => '#search-api-data-types-table']);
if ($fields = $index->getFieldsByDatasource(NULL)) {
$form['_general'] = $this->buildFieldsTable($fields);
@@ -216,7 +228,9 @@ class IndexFieldsForm extends EntityForm {
if ($fallback_types) {
foreach ($fields as $field) {
if (isset($fallback_types[$field->getType()])) {
- drupal_set_message($this->t("Some of the used data types aren't supported by the server's backend. See the data types table to find out which types are supported.", [':url' => '#search-api-data-types-table']), 'warning');
+ $args = [':url' => '#search-api-data-types-table'];
+ $warning = $this->t("Some of the used data types aren't supported by the server's backend. See the data types table to find out which types are supported.", $args);
+ $this->messenger->addWarning($warning);
break;
}
}
@@ -274,6 +288,7 @@ class IndexFieldsForm extends EntityForm {
],
];
+ uasort($fields, [$this->fieldsHelper, 'compareFieldLabels']);
foreach ($fields as $key => $field) {
$build['fields'][$key]['#access'] = !$field->isHidden();
@@ -444,7 +459,7 @@ class IndexFieldsForm extends EntityForm {
foreach ($field_values as $field_id => $new_settings) {
if (!isset($fields[$field_id])) {
$args['%field_id'] = $field_id;
- drupal_set_message($this->t('The field with ID %field_id does not exist anymore.', $args), 'warning');
+ $this->messenger->addWarning($this->t('The field with ID %field_id does not exist anymore.', $args));
continue;
}
$field = $fields[$field_id];
@@ -471,9 +486,9 @@ class IndexFieldsForm extends EntityForm {
$index->save();
}
- drupal_set_message($this->t('The changes were successfully saved.'));
+ $this->messenger->addStatus($this->t('The changes were successfully saved.'));
if ($this->entity->isReindexing()) {
- drupal_set_message($this->t('All content was scheduled for reindexing so the new settings can take effect.'));
+ $this->messenger->addStatus($this->t('All content was scheduled for reindexing so the new settings can take effect.'));
}
return SAVED_UPDATED;
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/IndexForm.php b/sites/all/modules/contrib/search/search_api/src/Form/IndexForm.php
index cb88aba2b..7e4e6f7c9 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/IndexForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/IndexForm.php
@@ -4,13 +4,14 @@ namespace Drupal\search_api\Form;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\EntityForm;
+use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Core\Form\SubformState;
use Drupal\Core\Utility\Error;
use Drupal\search_api\IndexInterface;
-use Drupal\search_api\SearchApiException;
use Drupal\search_api\Utility\PluginHelperInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -26,6 +27,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*/
class IndexForm extends EntityForm {
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
/**
* The entity type manager.
*
@@ -54,10 +62,13 @@ class IndexForm extends EntityForm {
* The entity type manager.
* @param \Drupal\search_api\Utility\PluginHelperInterface $plugin_helper
* The plugin helper.
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
*/
- public function __construct(EntityTypeManagerInterface $entity_type_manager, PluginHelperInterface $plugin_helper) {
+ public function __construct(EntityTypeManagerInterface $entity_type_manager, PluginHelperInterface $plugin_helper, MessengerInterface $messenger) {
$this->entityTypeManager = $entity_type_manager;
$this->pluginHelper = $plugin_helper;
+ $this->messenger = $messenger;
}
/**
@@ -66,7 +77,9 @@ class IndexForm extends EntityForm {
public static function create(ContainerInterface $container) {
$entity_type_manager = $container->get('entity_type.manager');
$plugin_helper = $container->get('search_api.plugin_helper');
- return new static($entity_type_manager, $plugin_helper);
+ $messenger = $container->get('messenger');
+
+ return new static($entity_type_manager, $plugin_helper, $messenger);
}
/**
@@ -358,7 +371,7 @@ class IndexForm extends EntityForm {
// If the user changed the datasources and there is at least one datasource
// config form, show a message telling the user to configure it.
if ($selected_datasources && $show_message) {
- drupal_set_message($this->t('Please configure the used datasources.'), 'warning');
+ $this->messenger->addWarning($this->t('Please configure the used datasources.'));
}
}
@@ -382,7 +395,7 @@ class IndexForm extends EntityForm {
// Only notify the user of a missing tracker plugin if we're editing an
// existing index.
elseif (!$index->isNew()) {
- drupal_set_message($this->t('The tracker plugin is missing or invalid.'), 'error');
+ $this->messenger->addError($this->t('The tracker plugin is missing or invalid.'));
}
}
else {
@@ -412,7 +425,7 @@ class IndexForm extends EntityForm {
// If the user changed the tracker and the new one has a config form, show
// a message telling the user to configure it.
if ($selected_tracker && $selected_tracker != $tracker->getPluginId()) {
- drupal_set_message($this->t('Please configure the used tracker.'), 'warning');
+ $this->messenger->addWarning($this->t('Please configure the used tracker.'));
}
}
}
@@ -598,7 +611,7 @@ class IndexForm extends EntityForm {
/** @var \Drupal\search_api\IndexInterface $index */
$index = $this->getEntity();
$index->save();
- drupal_set_message($this->t('The index was successfully saved.'));
+ $this->messenger->addStatus($this->t('The index was successfully saved.'));
$button = $form_state->getTriggeringElement();
if (!empty($button['#redirect_to_url'])) {
$form_state->setRedirectUrl($index->toUrl($button['#redirect_to_url']));
@@ -607,14 +620,14 @@ class IndexForm extends EntityForm {
$form_state->setRedirect('entity.search_api_index.canonical', ['search_api_index' => $index->id()]);
}
}
- catch (SearchApiException $e) {
+ catch (EntityStorageException $e) {
$form_state->setRebuild();
$message = '%type: @message in %function (line %line of %file).';
$variables = Error::decodeException($e);
$this->getLogger('search_api')->error($message, $variables);
- drupal_set_message($this->t('The index could not be saved.'), 'error');
+ $this->messenger->addError($this->t('The index could not be saved.'));
}
}
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/IndexProcessorsForm.php b/sites/all/modules/contrib/search/search_api/src/Form/IndexProcessorsForm.php
index d2fec7a80..c8bca3e3c 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/IndexProcessorsForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/IndexProcessorsForm.php
@@ -6,6 +6,7 @@ use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Core\Form\SubformState;
use Drupal\search_api\Processor\ProcessorInterface;
@@ -18,6 +19,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
*/
class IndexProcessorsForm extends EntityForm {
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
/**
* The index being configured.
*
@@ -55,11 +63,14 @@ class IndexProcessorsForm extends EntityForm {
* The processor plugin manager.
* @param \Psr\Log\LoggerInterface $logger
* The logger.
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
*/
- public function __construct(EntityTypeManagerInterface $entity_type_manager, ProcessorPluginManager $processor_plugin_manager, LoggerInterface $logger) {
+ public function __construct(EntityTypeManagerInterface $entity_type_manager, ProcessorPluginManager $processor_plugin_manager, LoggerInterface $logger, MessengerInterface $messenger) {
$this->entityTypeManager = $entity_type_manager;
$this->processorPluginManager = $processor_plugin_manager;
$this->logger = $logger;
+ $this->messenger = $messenger;
}
/**
@@ -69,8 +80,9 @@ class IndexProcessorsForm extends EntityForm {
$entity_type_manager = $container->get('entity_type.manager');
$processor_plugin_manager = $container->get('plugin.manager.search_api.processor');
$logger = $container->get('logger.channel.search_api');
+ $messenger = $container->get('messenger');
- return new static($entity_type_manager, $processor_plugin_manager, $logger);
+ return new static($entity_type_manager, $processor_plugin_manager, $logger, $messenger);
}
/**
@@ -322,13 +334,14 @@ class IndexProcessorsForm extends EntityForm {
public function save(array $form, FormStateInterface $form_state) {
if ($form_state->get('processors_changed')) {
$save_status = parent::save($form, $form_state);
- drupal_set_message($this->t('The indexing workflow was successfully edited.'));
+ $this->messenger->addStatus($this->t('The indexing workflow was successfully edited.'));
if ($this->entity->isReindexing()) {
- drupal_set_message($this->t('All content was scheduled for reindexing so the new settings can take effect.'));
+ $url = $this->entity->toUrl();
+ $this->messenger->addStatus($this->t('All content was scheduled for reindexing so the new settings can take effect.', [':url' => $url->toString()]));
}
}
else {
- drupal_set_message($this->t('No values were changed.'));
+ $this->messenger->addStatus($this->t('No values were changed.'));
$save_status = SAVED_UPDATED;
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/IndexRebuildTrackerConfirmForm.php b/sites/all/modules/contrib/search/search_api/src/Form/IndexRebuildTrackerConfirmForm.php
index 6a60ec0ab..5f652a126 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/IndexRebuildTrackerConfirmForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/IndexRebuildTrackerConfirmForm.php
@@ -5,12 +5,24 @@ namespace Drupal\search_api\Form;
use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a confirm form for clearing an index.
*/
class IndexRebuildTrackerConfirmForm extends EntityConfirmFormBase {
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ $form = parent::create($container);
+
+ $form->setMessenger($container->get('messenger'));
+
+ return $form;
+ }
+
/**
* {@inheritdoc}
*/
@@ -39,7 +51,8 @@ class IndexRebuildTrackerConfirmForm extends EntityConfirmFormBase {
/** @var \Drupal\search_api\IndexInterface $index */
$index = $this->getEntity();
$index->rebuildTracker();
- drupal_set_message($this->t('The tracking information for search index %name will be rebuilt.', ['%name' => $index->label()]));
+ $this->messenger()
+ ->addStatus($this->t('The tracking information for search index %name will be rebuilt.', ['%name' => $index->label()]));
$form_state->setRedirect('entity.search_api_index.canonical', ['search_api_index' => $index->id()]);
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/IndexReindexConfirmForm.php b/sites/all/modules/contrib/search/search_api/src/Form/IndexReindexConfirmForm.php
index d4003f71b..24b37dfd9 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/IndexReindexConfirmForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/IndexReindexConfirmForm.php
@@ -4,15 +4,43 @@ namespace Drupal\search_api\Form;
use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Url;
use Drupal\Core\Utility\Error;
use Drupal\search_api\SearchApiException;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a confirm form for reindexing an index.
*/
class IndexReindexConfirmForm extends EntityConfirmFormBase {
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
+ /**
+ * Constructs an IndexReindexConfirmForm object.
+ *
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
+ */
+ public function __construct(MessengerInterface $messenger) {
+ $this->messenger = $messenger;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ $messenger = $container->get('messenger');
+
+ return new static($messenger);
+ }
+
/**
* {@inheritdoc}
*/
@@ -43,10 +71,10 @@ class IndexReindexConfirmForm extends EntityConfirmFormBase {
try {
$index->reindex();
- drupal_set_message($this->t('The search index %name was successfully reindexed.', ['%name' => $index->label()]));
+ $this->messenger->addStatus($this->t('The search index %name was successfully reindexed.', ['%name' => $index->label()]));
}
catch (SearchApiException $e) {
- drupal_set_message($this->t('Failed to reindex items for the search index %name.', ['%name' => $index->label()]), 'error');
+ $this->messenger->addError($this->t('Failed to reindex items for the search index %name.', ['%name' => $index->label()]));
$message = '%type while trying to reindex items on index %name: @message in %function (line %line of %file)';
$variables = [
'%name' => $index->label(),
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/IndexStatusForm.php b/sites/all/modules/contrib/search/search_api/src/Form/IndexStatusForm.php
index f738cfe4d..d13e7f93d 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/IndexStatusForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/IndexStatusForm.php
@@ -2,19 +2,46 @@
namespace Drupal\search_api\Form;
-use Drupal\Component\Utility\Unicode;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\search_api\IndexBatchHelper;
use Drupal\search_api\SearchApiException;
use Drupal\search_api\IndexInterface;
use Drupal\search_api\Task\IndexTaskManagerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a form for indexing, clearing, etc., an index.
*/
class IndexStatusForm extends FormBase {
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
+ /**
+ * Constructs an IndexStatusForm object.
+ *
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
+ */
+ public function __construct(MessengerInterface $messenger) {
+ $this->messenger = $messenger;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ $messenger = $container->get('messenger');
+
+ return new static($messenger);
+ }
+
/**
* The index task manager.
*
@@ -184,12 +211,12 @@ class IndexStatusForm extends FormBase {
if ($form_state->getTriggeringElement()['#name'] === 'index_now') {
$values = $form_state->getValues();
// Get the translated "all" value and lowercase it for comparison.
- $all_value = Unicode::strtolower($values['all']);
+ $all_value = mb_strtolower($values['all']);
foreach (['limit', 'batch_size'] as $field) {
// Trim and lowercase the value so we correctly identify "all" values,
// even if not matching exactly.
- $value = Unicode::strtolower(trim($values[$field]));
+ $value = mb_strtolower(trim($values[$field]));
if ($value === $all_value) {
$value = -1;
@@ -221,7 +248,7 @@ class IndexStatusForm extends FormBase {
IndexBatchHelper::create($index, $values['batch_size'], $values['limit']);
}
catch (SearchApiException $e) {
- drupal_set_message($this->t('Failed to create a batch, please check the batch size and limit.'), 'warning');
+ $this->messenger->addWarning($this->t('Failed to create a batch, please check the batch size and limit.'));
}
break;
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/ServerClearConfirmForm.php b/sites/all/modules/contrib/search/search_api/src/Form/ServerClearConfirmForm.php
index 315bd2eb8..4e452ad99 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/ServerClearConfirmForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/ServerClearConfirmForm.php
@@ -4,15 +4,43 @@ namespace Drupal\search_api\Form;
use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Url;
use Drupal\Core\Utility\Error;
use Drupal\search_api\SearchApiException;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a confirm form for clearing a server.
*/
class ServerClearConfirmForm extends EntityConfirmFormBase {
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
+ /**
+ * Constructs a ServerClearConfirmForm object.
+ *
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
+ */
+ public function __construct(MessengerInterface $messenger) {
+ $this->messenger = $messenger;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ $messenger = $container->get('messenger');
+
+ return new static($messenger);
+ }
+
/**
* {@inheritdoc}
*/
@@ -43,10 +71,10 @@ class ServerClearConfirmForm extends EntityConfirmFormBase {
try {
$server->deleteAllItems();
- drupal_set_message($this->t('All indexed data was successfully deleted from the server.'));
+ $this->messenger->addStatus($this->t('All indexed data was successfully deleted from the server.'));
}
catch (SearchApiException $e) {
- drupal_set_message($this->t('Indexed data could not be cleared for some indexes. Check the logs for details.'), 'error');
+ $this->messenger->addError($this->t('Indexed data could not be cleared for some indexes. Check the logs for details.'));
}
$failed_reindexing = [];
@@ -74,7 +102,7 @@ class ServerClearConfirmForm extends EntityConfirmFormBase {
$args = [
'@indexes' => implode(', ', $failed_reindexing),
];
- drupal_set_message($this->t('Failed to mark the following indexes for reindexing: @indexes. Check the logs for details.', $args), 'warning');
+ $this->messenger->addWarning($this->t('Failed to mark the following indexes for reindexing: @indexes. Check the logs for details.', $args));
}
$form_state->setRedirect('entity.search_api_server.canonical', ['search_api_server' => $server->id()]);
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/ServerDeleteConfirmForm.php b/sites/all/modules/contrib/search/search_api/src/Form/ServerDeleteConfirmForm.php
index bdd8a8ae6..b861648bb 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/ServerDeleteConfirmForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/ServerDeleteConfirmForm.php
@@ -4,13 +4,41 @@ namespace Drupal\search_api\Form;
use Drupal\Core\Entity\EntityDeleteForm;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Url;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a confirm form for deleting a server.
*/
class ServerDeleteConfirmForm extends EntityDeleteForm {
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
+ /**
+ * Constructs a ServerDeleteConfirmForm object.
+ *
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
+ */
+ public function __construct(MessengerInterface $messenger) {
+ $this->messenger = $messenger;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ $messenger = $container->get('messenger');
+
+ return new static($messenger);
+ }
+
/**
* {@inheritdoc}
*/
@@ -44,7 +72,7 @@ class ServerDeleteConfirmForm extends EntityDeleteForm {
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->entity->delete();
- drupal_set_message($this->t('The search server %name has been deleted.', ['%name' => $this->entity->label()]));
+ $this->messenger->addStatus($this->t('The search server %name has been deleted.', ['%name' => $this->entity->label()]));
$form_state->setRedirect('search_api.overview');
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/ServerDisableConfirmForm.php b/sites/all/modules/contrib/search/search_api/src/Form/ServerDisableConfirmForm.php
index 03df68d3b..b2fb63b9e 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/ServerDisableConfirmForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/ServerDisableConfirmForm.php
@@ -4,13 +4,41 @@ namespace Drupal\search_api\Form;
use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Url;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a confirm form for disabling a server.
*/
class ServerDisableConfirmForm extends EntityConfirmFormBase {
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
+ /**
+ * Constructs a ServerDisableConfirmForm object.
+ *
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
+ */
+ public function __construct(MessengerInterface $messenger) {
+ $this->messenger = $messenger;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ $messenger = $container->get('messenger');
+
+ return new static($messenger);
+ }
+
/**
* {@inheritdoc}
*/
@@ -47,7 +75,7 @@ class ServerDisableConfirmForm extends EntityConfirmFormBase {
$server = $this->entity;
$server->setStatus(FALSE)->save();
- drupal_set_message($this->t('The search server %name has been disabled.', ['%name' => $this->entity->label()]));
+ $this->messenger->addStatus($this->t('The search server %name has been disabled.', ['%name' => $this->entity->label()]));
$form_state->setRedirect('search_api.overview');
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Form/ServerForm.php b/sites/all/modules/contrib/search/search_api/src/Form/ServerForm.php
index 0bbcc7d03..4e65fec9a 100644
--- a/sites/all/modules/contrib/search/search_api/src/Form/ServerForm.php
+++ b/sites/all/modules/contrib/search/search_api/src/Form/ServerForm.php
@@ -3,13 +3,14 @@
namespace Drupal\search_api\Form;
use Drupal\Core\Entity\EntityForm;
+use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Core\Form\SubformState;
use Drupal\Core\Url;
use Drupal\Core\Utility\Error;
use Drupal\search_api\Backend\BackendPluginManager;
-use Drupal\search_api\SearchApiException;
use Drupal\search_api\ServerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -25,21 +26,34 @@ class ServerForm extends EntityForm {
*/
protected $backendPluginManager;
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
/**
* Constructs a ServerForm object.
*
* @param \Drupal\search_api\Backend\BackendPluginManager $backend_plugin_manager
* The backend plugin manager.
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
*/
- public function __construct(BackendPluginManager $backend_plugin_manager) {
+ public function __construct(BackendPluginManager $backend_plugin_manager, MessengerInterface $messenger) {
$this->backendPluginManager = $backend_plugin_manager;
+ $this->messenger = $messenger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
- return new static($container->get('plugin.manager.search_api.backend'));
+ $backend_plugin_manager = $container->get('plugin.manager.search_api.backend');
+ $messenger = $container->get('messenger');
+
+ return new static($backend_plugin_manager, $messenger);
}
/**
@@ -154,7 +168,10 @@ class ServerForm extends EntityForm {
$form['backend'] += $descriptions;
}
else {
- drupal_set_message($this->t('There are no backend plugins available for the Search API. Please install a module that provides a backend plugin to proceed.', [':url' => Url::fromUri('https://www.drupal.org/node/1254698')->toString()]), 'error');
+ $url = 'https://www.drupal.org/node/1254698';
+ $args[':url'] = Url::fromUri($url)->toString();
+ $error = $this->t('There are no backend plugins available for the Search API. Please install a module that provides a backend plugin to proceed.', $args);
+ $this->messenger->addError($error);
$form = [];
}
}
@@ -176,7 +193,7 @@ class ServerForm extends EntityForm {
$form_state->set('backend', $backend->getPluginId());
if ($backend instanceof PluginFormInterface) {
if ($form_state->isRebuilding()) {
- drupal_set_message($this->t('Please configure the selected backend.'), 'warning');
+ $this->messenger->addWarning($this->t('Please configure the selected backend.'));
}
// Attach the backend plugin configuration form.
$backend_form_state = SubformState::createForSubform($form['backend_config'], $form, $form_state);
@@ -191,7 +208,7 @@ class ServerForm extends EntityForm {
// Only notify the user of a missing backend plugin if we're editing an
// existing server.
elseif (!$server->isNew()) {
- drupal_set_message($this->t('The backend plugin is missing or invalid.'), 'error');
+ $this->messenger->addError($this->t('The backend plugin is missing or invalid.'));
return;
}
$form['backend_config'] += [
@@ -282,17 +299,17 @@ class ServerForm extends EntityForm {
try {
$server = $this->getEntity();
$server->save();
- drupal_set_message($this->t('The server was successfully saved.'));
+ $this->messenger->addStatus($this->t('The server was successfully saved.'));
$form_state->setRedirect('entity.search_api_server.canonical', ['search_api_server' => $server->id()]);
}
- catch (SearchApiException $e) {
+ catch (EntityStorageException $e) {
$form_state->setRebuild();
$message = '%type: @message in %function (line %line of %file).';
$variables = Error::decodeException($e);
$this->getLogger('search_api')->error($message, $variables);
- drupal_set_message($this->t('The server could not be saved.'), 'error');
+ $this->messenger->addError($this->t('The server could not be saved.'));
}
}
}
diff --git a/sites/all/modules/contrib/search/search_api/src/IndexBatchHelper.php b/sites/all/modules/contrib/search/search_api/src/IndexBatchHelper.php
index 5ea5083d5..f531e2a88 100644
--- a/sites/all/modules/contrib/search/search_api/src/IndexBatchHelper.php
+++ b/sites/all/modules/contrib/search/search_api/src/IndexBatchHelper.php
@@ -187,23 +187,23 @@ class IndexBatchHelper {
// Build the indexed message.
$indexed_message = static::formatPlural($results['indexed'], 'Successfully indexed 1 item.', 'Successfully indexed @count items.');
// Notify user about indexed items.
- drupal_set_message($indexed_message);
+ \Drupal::messenger()->addStatus($indexed_message);
// Display the number of items not indexed.
if (!empty($results['not indexed'])) {
// Build the not indexed message.
$not_indexed_message = static::formatPlural($results['not indexed'], '1 item could not be indexed. Check the logs for details.', '@count items could not be indexed. Check the logs for details.');
// Notify user about not indexed items.
- drupal_set_message($not_indexed_message, 'warning');
+ \Drupal::messenger()->addWarning($not_indexed_message);
}
}
else {
// Notify user about failure to index items.
- drupal_set_message(static::t("Couldn't index items. Check the logs for details."), 'error');
+ \Drupal::messenger()->addError(static::t("Couldn't index items. Check the logs for details."));
}
}
else {
// Notify user about batch job failure.
- drupal_set_message(static::t('An error occurred while trying to index items. Check the logs for details.'), 'error');
+ \Drupal::messenger()->addError(static::t('An error occurred while trying to index items. Check the logs for details.'));
}
}
diff --git a/sites/all/modules/contrib/search/search_api/src/IndexInterface.php b/sites/all/modules/contrib/search/search_api/src/IndexInterface.php
index 277f76c1b..7eeb42476 100644
--- a/sites/all/modules/contrib/search/search_api/src/IndexInterface.php
+++ b/sites/all/modules/contrib/search/search_api/src/IndexInterface.php
@@ -399,18 +399,15 @@ interface IndexInterface extends ConfigEntityInterface {
/**
* Adds a field to this index.
*
- * If the field is already present (with the same datasource and property
- * path) its settings will be updated.
- *
* @param \Drupal\search_api\Item\FieldInterface $field
- * The field to add, or update.
+ * The field to add.
*
* @return $this
*
* @throws \Drupal\search_api\SearchApiException
- * Thrown if the field could not be added, either because a different field
- * with the same field ID would be overwritten, or because the field
- * identifier is one of the pseudo-fields that can be used in search
+ * Thrown if the field could not be added, either because a field with the
+ * same field ID already exists, or because the field identifier is one of
+ * the reserved field IDs of pseudo-fields that can be used in search
* queries.
*/
public function addField(FieldInterface $field);
diff --git a/sites/all/modules/contrib/search/search_api/src/ParamConverter/SearchApiConverter.php b/sites/all/modules/contrib/search/search_api/src/ParamConverter/SearchApiConverter.php
index a68da13c0..a3929bf09 100644
--- a/sites/all/modules/contrib/search/search_api/src/ParamConverter/SearchApiConverter.php
+++ b/sites/all/modules/contrib/search/search_api/src/ParamConverter/SearchApiConverter.php
@@ -8,7 +8,7 @@ use Drupal\Core\ParamConverter\EntityConverter;
use Drupal\Core\ParamConverter\ParamConverterInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\search_api\UnsavedIndexConfiguration;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
use Symfony\Component\Routing\Route;
/**
@@ -24,7 +24,7 @@ class SearchApiConverter extends EntityConverter implements ParamConverterInterf
/**
* The shared temporary storage factory.
*
- * @var \Drupal\user\SharedTempStoreFactory
+ * @var \Drupal\Core\TempStore\SharedTempStoreFactory
*/
protected $tempStoreFactory;
@@ -40,7 +40,7 @@ class SearchApiConverter extends EntityConverter implements ParamConverterInterf
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
- * @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory
* The factory for the temp store object.
* @param \Drupal\Core\Session\AccountInterface $user
* The current user.
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/DataType/Html.php b/sites/all/modules/contrib/search/search_api/src/Plugin/DataType/Html.php
index 1e7a7f28a..18326f70e 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/DataType/Html.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/DataType/Html.php
@@ -11,7 +11,7 @@ namespace Drupal\search_api\Plugin\DataType;
*
* @DataType(
* id = "search_api_html",
- * label = @Translation("Text (Search API)")
+ * label = @Translation("HTML text (Search API)")
* )
*/
class Html extends Text {}
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/data_type/DateDataType.php b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/data_type/DateDataType.php
index bcbdab2ac..40a9ff156 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/data_type/DateDataType.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/data_type/DateDataType.php
@@ -16,4 +16,19 @@ use Drupal\search_api\DataType\DataTypePluginBase;
*/
class DateDataType extends DataTypePluginBase {
+ /**
+ * {@inheritdoc}
+ */
+ public function getValue($value) {
+ if ((string) $value === '') {
+ return NULL;
+ }
+ if (is_numeric($value)) {
+ return (int) $value;
+ }
+ $timezone = new \DateTimezone('UTC');
+ $date = new \Datetime($value, $timezone);
+ return $date->getTimestamp();
+ }
+
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/datasource/ContentEntity.php b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/datasource/ContentEntity.php
index 2feda6c69..88116a71d 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/datasource/ContentEntity.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/datasource/ContentEntity.php
@@ -809,12 +809,8 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
* {@inheritdoc}
*/
public function getViewModes($bundle = NULL) {
- if (isset($bundle) && $this->hasBundles()) {
- return $this->getEntityDisplayRepository()->getViewModeOptionsByBundle($this->getEntityTypeId(), $bundle);
- }
- else {
- return $this->getEntityDisplayRepository()->getViewModeOptions($this->getEntityTypeId());
- }
+ return $this->getEntityDisplayRepository()
+ ->getViewModeOptions($this->getEntityTypeId());
}
/**
@@ -841,7 +837,8 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
*/
public function viewMultipleItems(array $items, $view_mode, $langcode = NULL) {
try {
- $view_builder = $this->getEntityTypeManager()->getViewBuilder($this->getEntityTypeId());
+ $view_builder = $this->getEntityTypeManager()
+ ->getViewBuilder($this->getEntityTypeId());
// Langcode passed, use that for viewing.
if (isset($langcode)) {
$entities = [];
@@ -858,8 +855,8 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
// Otherwise, separate the items by language, keeping the keys.
$items_by_language = [];
foreach ($items as $i => $item) {
- if ($item instanceof EntityInterface) {
- $items_by_language[$item->language()->getId()][$i] = $item;
+ if ($entity = $this->getEntity($item)) {
+ $items_by_language[$entity->language()->getId()][$i] = $entity;
}
}
// Then build the items for each language. We initialize $build beforehand
@@ -969,7 +966,7 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
$indexes = Index::loadMultiple();
foreach ($indexes as $index_id => $index) {
- // Filter our indexes that don't contain the datasource in question.
+ // Filter out indexes that don't contain the datasource in question.
if (!$index->isValidDatasource($datasource_id)) {
unset($indexes[$index_id]);
}
@@ -977,9 +974,7 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
// If the entity type supports bundles, we also have to filter out
// indexes that exclude the entity's bundle.
$config = $index->getDatasource($datasource_id)->getConfiguration();
- $default = !empty($config['bundles']['default']);
- $bundle_set = in_array($entity_bundle, $config['bundles']['selected']);
- if ($default == $bundle_set) {
+ if (!Utility::matches($entity_bundle, $config['bundles'])) {
unset($indexes[$index_id]);
}
}
@@ -1017,8 +1012,6 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
if (!isset($config['languages']['selected'])) {
return $item_ids;
}
- $default = !empty($config['languages']['default']);
- $selected = $config['languages']['selected'];
$always_valid = [
LanguageInterface::LANGCODE_NOT_SPECIFIED,
LanguageInterface::LANGCODE_NOT_APPLICABLE,
@@ -1031,7 +1024,7 @@ class ContentEntity extends DatasourcePluginBase implements EntityDatasourceInte
continue;
}
$langcode = substr($item_id, $pos + 1);
- if ($default != in_array($langcode, $selected)
+ if (Utility::matches($langcode, $config['languages'])
|| in_array($langcode, $always_valid)) {
$valid_ids[] = $item_id;
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/datasource/ContentEntityTaskManager.php b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/datasource/ContentEntityTaskManager.php
index 2faea4333..e6fde8128 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/datasource/ContentEntityTaskManager.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/datasource/ContentEntityTaskManager.php
@@ -55,8 +55,8 @@ class ContentEntityTaskManager implements EventSubscriberInterface {
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
- $events['search_api.task.' . static::INSERT_ITEMS_TASK_TYPE][] = ['processEvent'];
- $events['search_api.task.' . static::DELETE_ITEMS_TASK_TYPE][] = ['processEvent'];
+ $events['search_api.task.' . self::INSERT_ITEMS_TASK_TYPE][] = ['processEvent'];
+ $events['search_api.task.' . self::DELETE_ITEMS_TASK_TYPE][] = ['processEvent'];
return $events;
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/AddHierarchy.php b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/AddHierarchy.php
index abd3e2e93..8c165e304 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/AddHierarchy.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/AddHierarchy.php
@@ -120,7 +120,7 @@ class AddHierarchy extends ProcessorPluginBase implements PluginFormInterface {
$property_label = $property->getLabel();
$property = $this->getFieldsHelper()->getInnerProperty($property);
if ($property instanceof EntityDataDefinitionInterface) {
- $options = self::findHierarchicalProperties($property, $property_label);
+ $options = static::findHierarchicalProperties($property, $property_label);
if ($options) {
$field_options += [$field_id => []];
$field_options[$field_id] += $options;
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/AddURL.php b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/AddURL.php
index c39bb2ef1..5fd163bc6 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/AddURL.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/AddURL.php
@@ -49,8 +49,9 @@ class AddURL extends ProcessorPluginBase {
$url = $item->getDatasource()->getItemUrl($item->getOriginalObject());
if ($url) {
$url = $url->toString();
+ $fields = $item->getFields(FALSE);
$fields = $this->getFieldsHelper()
- ->filterForPropertyPath($item->getFields(), NULL, 'search_api_url');
+ ->filterForPropertyPath($fields, NULL, 'search_api_url');
foreach ($fields as $field) {
$field->addValue($url);
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/Highlight.php b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/Highlight.php
index 195b7d574..c94425b24 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/Highlight.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/Highlight.php
@@ -63,14 +63,14 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
public function __construct(array $configuration, $plugin_id, array $plugin_definition) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
- if (!isset(self::$boundary)) {
+ if (!isset(static::$boundary)) {
$cjk = '\x{1100}-\x{11FF}\x{3040}-\x{309F}\x{30A1}-\x{318E}' .
'\x{31A0}-\x{31B7}\x{31F0}-\x{31FF}\x{3400}-\x{4DBF}\x{4E00}-\x{9FCF}' .
'\x{A000}-\x{A48F}\x{A4D0}-\x{A4FD}\x{A960}-\x{A97F}\x{AC00}-\x{D7FF}' .
'\x{F900}-\x{FAFF}\x{FF21}-\x{FF3A}\x{FF41}-\x{FF5A}\x{FF66}-\x{FFDC}' .
'\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}';
- self::$boundary = '(?:(?<=[' . Unicode::PREG_CLASS_WORD_BOUNDARY . $cjk . '])|(?=[' . Unicode::PREG_CLASS_WORD_BOUNDARY . $cjk . ']))';
- self::$split = '/[' . Unicode::PREG_CLASS_WORD_BOUNDARY . ']+/iu';
+ static::$boundary = '(?:(?<=[' . Unicode::PREG_CLASS_WORD_BOUNDARY . $cjk . '])|(?=[' . Unicode::PREG_CLASS_WORD_BOUNDARY . $cjk . ']))';
+ static::$split = '/[' . Unicode::PREG_CLASS_WORD_BOUNDARY . ']+/iu';
}
}
@@ -257,9 +257,6 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
$highlighted_fields = $this->highlightFields($result_items, $keys);
foreach ($highlighted_fields as $item_id => $item_fields) {
$item = $result_items[$item_id];
- // Maybe the backend or some other processor has already set highlighted
- // field values.
- $item_fields += $item->getExtraData('highlighted_fields', []);
$item->setExtraData('highlighted_fields', $item_fields);
}
}
@@ -303,19 +300,28 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
* highlighted versions of the values for that field.
*/
protected function highlightFields(array $results, array $keys) {
- $item_fields = $this->getFulltextFields($results, NULL, $this->configuration['highlight'] == 'always');
$highlighted_fields = [];
+ foreach ($results as $item_id => $item) {
+ // Maybe the backend or some other processor has already set highlighted
+ // field values.
+ $highlighted_fields[$item_id] = $item->getExtraData('highlighted_fields', []);
+ }
+
+ $load = $this->configuration['highlight'] == 'always';
+ $item_fields = $this->getFulltextFields($results, NULL, $load);
foreach ($item_fields as $item_id => $fields) {
foreach ($fields as $field_id => $values) {
- $change = FALSE;
- foreach ($values as $i => $value) {
- $values[$i] = $this->highlightField($value, $keys);
- if ($values[$i] !== $value) {
- $change = TRUE;
+ if (empty($highlighted_fields[$item_id][$field_id])) {
+ $change = FALSE;
+ foreach ($values as $i => $value) {
+ $values[$i] = $this->highlightField($value, $keys);
+ if ($values[$i] !== $value) {
+ $change = TRUE;
+ }
+ }
+ if ($change) {
+ $highlighted_fields[$item_id][$field_id] = $values;
}
- }
- if ($change) {
- $highlighted_fields[$item_id][$field_id] = $values;
}
}
}
@@ -373,7 +379,7 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
return $this->flattenKeysArray($keys);
}
- $keywords_in = preg_split(self::$split, $keys);
+ $keywords_in = preg_split(static::$split, $keys);
// Assure there are no duplicates. (This is actually faster than
// array_unique() by a factor of 3 to 4.)
// Remove quotes from keywords.
@@ -474,7 +480,7 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
if (!$this->configuration['highlight_partial']) {
$found_position = FALSE;
- $regex = '/' . self::$boundary . preg_quote($key, '/') . self::$boundary . '/iu';
+ $regex = '/' . static::$boundary . preg_quote($key, '/') . static::$boundary . '/iu';
if (preg_match($regex, ' ' . $text . ' ', $matches, PREG_OFFSET_CAPTURE, $look_start[$key])) {
$found_position = $matches[0][1];
}
@@ -602,7 +608,7 @@ class Highlight extends ProcessorPluginBase implements PluginFormInterface {
$keys = implode('|', array_map('preg_quote', $keys, array_fill(0, count($keys), '/')));
// If "Highlight partial matches" is disabled, we only want to highlight
// matches that are complete words. Otherwise, we want all of them.
- $boundary = !$this->configuration['highlight_partial'] ? self::$boundary : '';
+ $boundary = !$this->configuration['highlight_partial'] ? static::$boundary : '';
$regex = '/' . $boundary . '(?:' . $keys . ')' . $boundary . '/iu';
$replace = $this->configuration['prefix'] . '\0' . $this->configuration['suffix'];
$text = preg_replace($regex, $replace, ' ' . $text . ' ');
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/IgnoreCase.php b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/IgnoreCase.php
index 013d3d086..9421fdf25 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/IgnoreCase.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/IgnoreCase.php
@@ -2,7 +2,6 @@
namespace Drupal\search_api\Plugin\search_api\processor;
-use Drupal\Component\Utility\Unicode;
use Drupal\search_api\Item\FieldInterface;
use Drupal\search_api\Plugin\search_api\data_type\value\TextValueInterface;
use Drupal\search_api\Processor\FieldsProcessorPluginBase;
@@ -42,7 +41,7 @@ class IgnoreCase extends FieldsProcessorPluginBase {
protected function process(&$value) {
// We don't touch integers, NULL values or the like.
if (is_string($value)) {
- $value = Unicode::strtolower($value);
+ $value = mb_strtolower($value);
}
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/Tokenizer.php b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/Tokenizer.php
index 394bfa74e..f64b2f982 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/Tokenizer.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/processor/Tokenizer.php
@@ -205,7 +205,7 @@ class Tokenizer extends FieldsProcessorPluginBase {
$value = [];
foreach ($arr as $token) {
- if (is_numeric($token) || Unicode::strlen($token) >= $this->configuration['minimum_word_size']) {
+ if (is_numeric($token) || mb_strlen($token) >= $this->configuration['minimum_word_size']) {
$value[] = Utility::createTextToken($token);
}
}
@@ -277,7 +277,7 @@ class Tokenizer extends FieldsProcessorPluginBase {
protected function expandCjk(array $matches) {
$min = $this->configuration['minimum_word_size'];
$str = $matches[0];
- $length = Unicode::strlen($str);
+ $length = mb_strlen($str);
// If the text is shorter than the minimum word size, don't tokenize it.
if ($length <= $min) {
return ' ' . $str . ' ';
@@ -287,7 +287,7 @@ class Tokenizer extends FieldsProcessorPluginBase {
$chars = [];
for ($i = 0; $i < $length; $i++) {
// Add the next character off the beginning of the string to the queue.
- $current = Unicode::substr($str, 0, 1);
+ $current = mb_substr($str, 0, 1);
$str = substr($str, strlen($current));
$chars[] = $current;
if ($i >= $min - 1) {
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/tracker/Basic.php b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/tracker/Basic.php
index f122fbf4e..bcfa99ad7 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/tracker/Basic.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/search_api/tracker/Basic.php
@@ -271,7 +271,7 @@ class Basic extends TrackerPluginBase implements PluginFormInterface {
// (Otherwise, an item that's regularly being updated might never get
// indexed.)
if ($this->configuration['indexing_order'] === 'fifo') {
- $update->condition('status', static::STATUS_INDEXED);
+ $update->condition('status', self::STATUS_INDEXED);
}
$update->execute();
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiDate.php b/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiDate.php
index 7fe9975cd..821983726 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiDate.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiDate.php
@@ -78,14 +78,9 @@ class SearchApiDate extends Date {
];
}
- // Store this because it will get overwritten by the grandparent, and the
- // parent doesn't always restore it correctly.
- $type = $this->value['type'];
$return = parent::acceptExposedInput($input);
if (!$return) {
- // If the parent returns FALSE, it doesn't restore the "type" key.
- $this->value['type'] = $type;
// Override for the "(not) empty" operators.
$operators = $this->operators();
if ($operators[$this->operator]['values'] == 0) {
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiFulltext.php b/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiFulltext.php
index d02be82f2..11891702f 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiFulltext.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiFulltext.php
@@ -2,7 +2,6 @@
namespace Drupal\search_api\Plugin\views\filter;
-use Drupal\Component\Utility\Unicode;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\search_api\Entity\Index;
@@ -123,11 +122,11 @@ class SearchApiFulltext extends FilterPluginBase {
public function defineOptions() {
$options = parent::defineOptions();
- $options['parse_mode'] = ['default' => 'terms'];
$options['operator']['default'] = 'and';
-
- $options['min_length']['default'] = '';
- $options['fields']['default'] = [];
+ $options['parse_mode'] = ['default' => 'terms'];
+ $options['min_length'] = ['default' => ''];
+ $options['fields'] = ['default' => []];
+ $options['expose']['contains']['placeholder'] = ['default' => ''];
return $options;
}
@@ -188,6 +187,21 @@ class SearchApiFulltext extends FilterPluginBase {
];
}
+ /**
+ * {@inheritdoc}
+ */
+ public function buildExposeForm(&$form, FormStateInterface $form_state) {
+ parent::buildExposeForm($form, $form_state);
+
+ $form['expose']['placeholder'] = [
+ '#type' => 'textfield',
+ '#default_value' => $this->options['expose']['placeholder'],
+ '#title' => $this->t('Placeholder'),
+ '#size' => 40,
+ '#description' => $this->t('Hint text that appears inside the field when empty.'),
+ ];
+ }
+
/**
* {@inheritdoc}
*/
@@ -200,6 +214,9 @@ class SearchApiFulltext extends FilterPluginBase {
'#size' => 30,
'#default_value' => $this->value,
];
+ if (!empty($this->options['expose']['placeholder'])) {
+ $form['value']['#attributes']['placeholder'] = $this->options['expose']['placeholder'];
+ }
}
/**
@@ -254,7 +271,7 @@ class SearchApiFulltext extends FilterPluginBase {
$words = preg_split('/\s+/', $input);
foreach ($words as $i => $word) {
- if (Unicode::strlen($word) < $this->options['min_length']) {
+ if (mb_strlen($word) < $this->options['min_length']) {
unset($words[$i]);
}
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiLanguage.php b/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiLanguage.php
index b342b2731..6fe5703a6 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiLanguage.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/views/filter/SearchApiLanguage.php
@@ -19,7 +19,7 @@ class SearchApiLanguage extends LanguageFilter {
* {@inheritdoc}
*/
public function query() {
- $substitutions = self::queryLanguageSubstitutions();
+ $substitutions = static::queryLanguageSubstitutions();
foreach ($this->value as $i => $value) {
if (isset($substitutions[$value])) {
$this->value[$i] = $substitutions[$value];
diff --git a/sites/all/modules/contrib/search/search_api/src/Plugin/views/query/SearchApiQuery.php b/sites/all/modules/contrib/search/search_api/src/Plugin/views/query/SearchApiQuery.php
index eaf087385..bd18cfd8e 100644
--- a/sites/all/modules/contrib/search/search_api/src/Plugin/views/query/SearchApiQuery.php
+++ b/sites/all/modules/contrib/search/search_api/src/Plugin/views/query/SearchApiQuery.php
@@ -9,6 +9,7 @@ use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Url;
use Drupal\search_api\Entity\Index;
use Drupal\search_api\LoggerTrait;
@@ -115,6 +116,13 @@ class SearchApiQuery extends QueryPluginBase {
*/
protected $moduleHandler;
+ /**
+ * The messenger.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface|null
+ */
+ protected $messenger;
+
/**
* {@inheritdoc}
*/
@@ -123,6 +131,7 @@ class SearchApiQuery extends QueryPluginBase {
$plugin = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$plugin->setModuleHandler($container->get('module_handler'));
+ $plugin->setMessenger($container->get('messenger'));
$plugin->setLogger($container->get('logger.channel.search_api'));
return $plugin;
@@ -208,6 +217,29 @@ class SearchApiQuery extends QueryPluginBase {
return $this;
}
+ /**
+ * Retrieves the messenger.
+ *
+ * @return \Drupal\Core\Messenger\MessengerInterface
+ * The messenger.
+ */
+ public function getMessenger() {
+ return $this->messenger ?: \Drupal::service('messenger');
+ }
+
+ /**
+ * Sets the messenger.
+ *
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The new messenger.
+ *
+ * @return $this
+ */
+ public function setMessenger(MessengerInterface $messenger) {
+ $this->messenger = $messenger;
+ return $this;
+ }
+
/**
* {@inheritdoc}
*/
@@ -427,7 +459,7 @@ class SearchApiQuery extends QueryPluginBase {
if ($this->shouldAbort()) {
if (error_displayable()) {
foreach ($this->errors as $msg) {
- drupal_set_message(Html::escape($msg), 'error');
+ $this->getMessenger()->addError(Html::escape($msg));
}
}
$view->result = [];
diff --git a/sites/all/modules/contrib/search/search_api/src/Processor/FieldsProcessorPluginBase.php b/sites/all/modules/contrib/search/search_api/src/Processor/FieldsProcessorPluginBase.php
index 02039eb98..eb857fabf 100644
--- a/sites/all/modules/contrib/search/search_api/src/Processor/FieldsProcessorPluginBase.php
+++ b/sites/all/modules/contrib/search/search_api/src/Processor/FieldsProcessorPluginBase.php
@@ -427,9 +427,9 @@ abstract class FieldsProcessorPluginBase extends ProcessorPluginBase implements
// value can't be in the index – but that's irrelevant for (NOT)
// BETWEEN conditions, as any value between the two bounds could still
// be included. We therefore never remove a (NOT) BETWEEN condition
- // and also ignore it when one of the two values got removed. (Note
- // that this check will also catch empty strings.) Processors who need
- // different behavior have to override this method.
+ // and also ignore it when one of the two values got removed.
+ // Processors who need different behavior have to override this
+ // method.
$between_operator = in_array($condition->getOperator(), ['BETWEEN', 'NOT BETWEEN']);
if ($between_operator && (!is_array($value) || count($value) < 2)) {
continue;
diff --git a/sites/all/modules/contrib/search/search_api/src/Query/Query.php b/sites/all/modules/contrib/search/search_api/src/Query/Query.php
index c07780f54..e415cc2c3 100644
--- a/sites/all/modules/contrib/search/search_api/src/Query/Query.php
+++ b/sites/all/modules/contrib/search/search_api/src/Query/Query.php
@@ -176,6 +176,13 @@ class Query implements QueryInterface {
*/
protected $queryHelper;
+ /**
+ * The original query before preprocessing.
+ *
+ * @var static|null
+ */
+ protected $originalQuery;
+
/**
* Constructs a Query object.
*
@@ -465,7 +472,7 @@ class Query implements QueryInterface {
* {@inheritdoc}
*/
public function getAbortMessage() {
- return is_bool($this->aborted) ? $this->aborted : NULL;
+ return !is_bool($this->aborted) ? $this->aborted : NULL;
}
/**
@@ -511,6 +518,9 @@ class Query implements QueryInterface {
if (!$this->wasAborted() && $this->languages !== []) {
return FALSE;
}
+ if (!$this->originalQuery) {
+ $this->originalQuery = clone $this;
+ }
$this->postExecute();
return TRUE;
}
@@ -521,9 +531,15 @@ class Query implements QueryInterface {
public function preExecute() {
// Make sure to only execute this once per query, and not for queries with
// the "none" processing level.
- if (!$this->preExecuteRan && $this->processingLevel != self::PROCESSING_NONE) {
+ if (!$this->preExecuteRan) {
+ $this->originalQuery = clone $this;
+ $this->originalQuery->executed = FALSE;
$this->preExecuteRan = TRUE;
+ if ($this->processingLevel == self::PROCESSING_NONE) {
+ return;
+ }
+
// Preprocess query.
$this->index->preprocessSearchQuery($this);
@@ -673,12 +689,22 @@ class Query implements QueryInterface {
return $this->tags;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function getOriginalQuery() {
+ return $this->originalQuery ?: clone $this;
+ }
+
/**
* {@inheritdoc}
*/
public function __clone() {
$this->results = $this->getResults()->getCloneForQuery($this);
$this->conditionGroup = clone $this->conditionGroup;
+ if ($this->originalQuery) {
+ $this->originalQuery = clone $this->originalQuery;
+ }
if ($this->parseMode) {
$this->parseMode = clone $this->parseMode;
}
@@ -707,19 +733,6 @@ class Query implements QueryInterface {
$this->indexId = NULL;
}
- // Sanitize the service IDs saved by the serialization trait to guard
- // against incomplete service containers. Doesn't need to happen when the
- // trait's __wakeup() method will return early anyways, though.
- // @todo Remove once #2909164 gets fixed in Core (and we depend on that Core
- // version).
- if (!isset($GLOBALS['__PHPUNIT_BOOTSTRAP']) || \Drupal::hasContainer()) {
- $container = \Drupal::getContainer();
- foreach ($this->_serviceIds as $key => $service_id) {
- if (!$container->has($service_id)) {
- unset($this->_serviceIds[$key]);
- }
- }
- }
$this->traitWakeup();
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Query/QueryInterface.php b/sites/all/modules/contrib/search/search_api/src/Query/QueryInterface.php
index 4d29a81be..552cf7cdd 100644
--- a/sites/all/modules/contrib/search/search_api/src/Query/QueryInterface.php
+++ b/sites/all/modules/contrib/search/search_api/src/Query/QueryInterface.php
@@ -286,6 +286,11 @@ interface QueryInterface extends ConditionSetInterface {
/**
* Executes this search query.
*
+ * The results of the search will be cached on the query, so subsequent calls
+ * of this method will always return the same result set (even if conditions
+ * were changed in between). If you want to re-execute a query, use
+ * getOriginalQuery().
+ *
* @return \Drupal\search_api\Query\ResultSetInterface
* The results of the search.
*
@@ -520,4 +525,14 @@ interface QueryInterface extends ConditionSetInterface {
*/
public function &getTags();
+ /**
+ * Retrieves the original version of the query, before preprocessing occurred.
+ *
+ * Will be a clone of this query if preprocessing has not already run.
+ *
+ * @return \Drupal\search_api\Query\Query
+ * The original, unpreprocessed version of this query.
+ */
+ public function getOriginalQuery();
+
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Task/IndexTaskManager.php b/sites/all/modules/contrib/search/search_api/src/Task/IndexTaskManager.php
index b85ffb19d..36f0db203 100644
--- a/sites/all/modules/contrib/search/search_api/src/Task/IndexTaskManager.php
+++ b/sites/all/modules/contrib/search/search_api/src/Task/IndexTaskManager.php
@@ -54,7 +54,7 @@ class IndexTaskManager implements IndexTaskManagerInterface, EventSubscriberInte
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
- $events['search_api.task.' . static::TRACK_ITEMS_TASK_TYPE][] = ['trackItems'];
+ $events['search_api.task.' . self::TRACK_ITEMS_TASK_TYPE][] = ['trackItems'];
return $events;
}
@@ -161,7 +161,7 @@ class IndexTaskManager implements IndexTaskManagerInterface, EventSubscriberInte
if ($reschedule) {
++$data['page'];
- $this->taskManager->addTask(static::TRACK_ITEMS_TASK_TYPE, NULL, $index, $data);
+ $this->taskManager->addTask(self::TRACK_ITEMS_TASK_TYPE, NULL, $index, $data);
}
}
@@ -178,7 +178,7 @@ class IndexTaskManager implements IndexTaskManagerInterface, EventSubscriberInte
'datasource' => $datasource_id,
'page' => 0,
];
- $this->taskManager->addTask(static::TRACK_ITEMS_TASK_TYPE, NULL, $index, $data);
+ $this->taskManager->addTask(self::TRACK_ITEMS_TASK_TYPE, NULL, $index, $data);
}
}
@@ -193,7 +193,7 @@ class IndexTaskManager implements IndexTaskManagerInterface, EventSubscriberInte
*/
protected function getTaskConditions(IndexInterface $index) {
return [
- 'type' => static::TRACK_ITEMS_TASK_TYPE,
+ 'type' => self::TRACK_ITEMS_TASK_TYPE,
'index_id' => $index->id(),
];
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Task/TaskManager.php b/sites/all/modules/contrib/search/search_api/src/Task/TaskManager.php
index 606ce1093..7640b391d 100644
--- a/sites/all/modules/contrib/search/search_api/src/Task/TaskManager.php
+++ b/sites/all/modules/contrib/search/search_api/src/Task/TaskManager.php
@@ -5,6 +5,7 @@ namespace Drupal\search_api\Task;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\search_api\IndexInterface;
@@ -58,6 +59,13 @@ class TaskManager implements TaskManagerInterface {
*/
protected $eventDispatcher;
+ /**
+ * The messenger service.
+ *
+ * @var \Drupal\Core\Messenger\MessengerInterface
+ */
+ protected $messenger;
+
/**
* Constructs a TaskManager object.
*
@@ -67,11 +75,14 @@ class TaskManager implements TaskManagerInterface {
* The event dispatcher.
* @param \Drupal\Core\StringTranslation\TranslationInterface $translation
* The string translation service.
+ * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+ * The messenger.
*/
- public function __construct(EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, TranslationInterface $translation) {
+ public function __construct(EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, TranslationInterface $translation, MessengerInterface $messenger) {
$this->entityTypeManager = $entity_type_manager;
$this->eventDispatcher = $event_dispatcher;
$this->setStringTranslation($translation);
+ $this->messenger = $messenger;
}
/**
@@ -267,6 +278,9 @@ class TaskManager implements TaskManagerInterface {
];
// Schedule the batch.
batch_set($batch_definition);
+ if (function_exists('drush_backend_batch_process')) {
+ drush_backend_batch_process();
+ }
}
/**
@@ -335,11 +349,11 @@ class TaskManager implements TaskManagerInterface {
'Successfully executed @count pending task.',
'Successfully executed @count pending tasks.'
);
- drupal_set_message($message);
+ $this->messenger->addStatus($message);
}
else {
// Notify the user about the batch job failure.
- drupal_set_message($this->t('An error occurred while trying to execute tasks. Check the logs for details.'), 'error');
+ $this->messenger->addError($this->t('An error occurred while trying to execute tasks. Check the logs for details.'));
}
}
diff --git a/sites/all/modules/contrib/search/search_api/src/UnsavedIndexConfiguration.php b/sites/all/modules/contrib/search/search_api/src/UnsavedIndexConfiguration.php
index 145e1cc47..3d8012003 100644
--- a/sites/all/modules/contrib/search/search_api/src/UnsavedIndexConfiguration.php
+++ b/sites/all/modules/contrib/search/search_api/src/UnsavedIndexConfiguration.php
@@ -14,7 +14,7 @@ use Drupal\search_api\Processor\ProcessorInterface;
use Drupal\search_api\Query\QueryInterface;
use Drupal\search_api\Query\ResultSetInterface;
use Drupal\search_api\Tracker\TrackerInterface;
-use Drupal\user\SharedTempStore;
+use Drupal\Core\TempStore\SharedTempStore;
/**
* Represents a configuration of an index that was not yet permanently saved.
@@ -31,7 +31,7 @@ class UnsavedIndexConfiguration implements IndexInterface, UnsavedConfigurationI
/**
* The shared temporary storage to use.
*
- * @var \Drupal\user\SharedTempStore
+ * @var \Drupal\Core\TempStore\SharedTempStore
*/
protected $tempStore;
@@ -61,7 +61,7 @@ class UnsavedIndexConfiguration implements IndexInterface, UnsavedConfigurationI
*
* @param \Drupal\search_api\IndexInterface $index
* The index to proxy.
- * @param \Drupal\user\SharedTempStore $temp_store
+ * @param \Drupal\Core\TempStore\SharedTempStore $temp_store
* The shared temporary storage to use.
* @param int|string $current_user_id
* Either the UID of the currently logged-in user, or the session ID (for
diff --git a/sites/all/modules/contrib/search/search_api/src/Utility/FieldsHelper.php b/sites/all/modules/contrib/search/search_api/src/Utility/FieldsHelper.php
index 3b6d57d7f..cc2c80961 100644
--- a/sites/all/modules/contrib/search/search_api/src/Utility/FieldsHelper.php
+++ b/sites/all/modules/contrib/search/search_api/src/Utility/FieldsHelper.php
@@ -490,4 +490,11 @@ class FieldsHelper implements FieldsHelperInterface {
return $fieldId;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function compareFieldLabels(FieldInterface $a, FieldInterface $b) {
+ return strnatcasecmp($a->getLabel(), $b->getLabel());
+ }
+
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Utility/FieldsHelperInterface.php b/sites/all/modules/contrib/search/search_api/src/Utility/FieldsHelperInterface.php
index 31a0f58ea..4612ac0cf 100644
--- a/sites/all/modules/contrib/search/search_api/src/Utility/FieldsHelperInterface.php
+++ b/sites/all/modules/contrib/search/search_api/src/Utility/FieldsHelperInterface.php
@@ -257,4 +257,18 @@ interface FieldsHelperInterface {
*/
public function getNewFieldId(IndexInterface $index, $propertyPath);
+ /**
+ * Compares two fields for alphabetic sorting according to their labels.
+ *
+ * @param \Drupal\search_api\Item\FieldInterface $a
+ * The first field.
+ * @param \Drupal\search_api\Item\FieldInterface $b
+ * The second field.
+ *
+ * @return int
+ * -1, 0 or 1 if the first field should, respectively, be considered less
+ * than, equal to or greater than the second.
+ */
+ public function compareFieldLabels(FieldInterface $a, FieldInterface $b);
+
}
diff --git a/sites/all/modules/contrib/search/search_api/src/Utility/PostRequestIndexing.php b/sites/all/modules/contrib/search/search_api/src/Utility/PostRequestIndexing.php
index a9cc74504..02f9c4dea 100644
--- a/sites/all/modules/contrib/search/search_api/src/Utility/PostRequestIndexing.php
+++ b/sites/all/modules/contrib/search/search_api/src/Utility/PostRequestIndexing.php
@@ -3,16 +3,15 @@
namespace Drupal\search_api\Utility;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
+use Drupal\Core\DestructableInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\search_api\LoggerTrait;
use Drupal\search_api\SearchApiException;
-use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-use Symfony\Component\HttpKernel\KernelEvents;
/**
* Provides a service for indexing items at the end of the page request.
*/
-class PostRequestIndexing implements PostRequestIndexingInterface, EventSubscriberInterface {
+class PostRequestIndexing implements PostRequestIndexingInterface, DestructableInterface {
use LoggerTrait;
@@ -46,20 +45,7 @@ class PostRequestIndexing implements PostRequestIndexingInterface, EventSubscrib
/**
* {@inheritdoc}
*/
- public static function getSubscribedEvents() {
- $events[KernelEvents::TERMINATE][] = ['onKernelTerminate'];
-
- return $events;
- }
-
- /**
- * Indexes all items that were registered for indexing in this page request.
- *
- * Invoked by the terminate kernel event.
- *
- * @see \Symfony\Component\HttpKernel\Event\PostResponseEvent
- */
- public function onKernelTerminate() {
+ public function destruct() {
foreach ($this->operations as $index_id => $item_ids) {
try {
$storage = $this->entityTypeManager->getStorage('search_api_index');
diff --git a/sites/all/modules/contrib/search/search_api/src/Utility/Utility.php b/sites/all/modules/contrib/search/search_api/src/Utility/Utility.php
index 856e4b6df..52a0f361b 100644
--- a/sites/all/modules/contrib/search/search_api/src/Utility/Utility.php
+++ b/sites/all/modules/contrib/search/search_api/src/Utility/Utility.php
@@ -3,12 +3,11 @@
namespace Drupal\search_api\Utility;
use Drupal\Component\Utility\NestedArray;
-use Drupal\Core\Config\ConfigFactoryOverrideInterface;
+use Drupal\Core\Config\Config;
use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\search_api\IndexInterface;
use Drupal\search_api\Plugin\search_api\data_type\value\TextToken;
-use Symfony\Component\DependencyInjection\TaggedContainerInterface;
/**
* Contains utility methods for the Search API.
@@ -167,31 +166,43 @@ class Utility {
}
$config_key = $entity_type->getConfigPrefix() . '.' . $entity->id();
- $overrides = [];
-
- // Overrides from tagged services.
- $container = \Drupal::getContainer();
- if ($container instanceof TaggedContainerInterface) {
- $tags = $container->findTaggedServiceIds('config.factory.override');
- foreach (array_keys($tags) as $service_id) {
- $override = $container->get($service_id);
- if ($override instanceof ConfigFactoryOverrideInterface) {
- $service_overrides = $override->loadOverrides([$config_key]);
- if (!empty($service_overrides[$config_key])) {
- // Existing overrides take precedence since these will have been
- // added by events with a higher priority.
- $arrays = [$service_overrides[$config_key], $overrides];
- $overrides = NestedArray::mergeDeepArray($arrays, TRUE);
- }
- }
- }
+ $config = \Drupal::config($config_key);
+ if (!$config->hasOverrides()) {
+ return [];
}
- // Overrides from settings.php. (This takes precedence over overrides from
- // services.)
- if (isset($GLOBALS['config'][$config_key])) {
- $arrays = [$overrides, $GLOBALS['config'][$config_key]];
- $overrides = NestedArray::mergeDeepArray($arrays, TRUE);
+ return static::collectOverrides($config, $config->get());
+ }
+
+ /**
+ * Collects overrides from a config object.
+ *
+ * @param \Drupal\Core\Config\Config $config
+ * The config object.
+ * @param array $values
+ * The array of values for the given $prefix.
+ * @param array $overrides
+ * (optional) The overrides collected so far. Internal use only.
+ * @param string $prefix
+ * (optional) The config key prefix for the current call level. Internal
+ * use only.
+ *
+ * @return array
+ * An associative array mapping property names to their overridden values.
+ */
+ protected static function collectOverrides(Config $config, array $values, array $overrides = [], $prefix = '') {
+ foreach ($values as $key => $value) {
+ $key = "$prefix$key";
+ if (!$config->hasOverrides($key)) {
+ continue;
+ }
+ if (is_array($value)) {
+ NestedArray::setValue($overrides, explode('.', $key), []);
+ $overrides = static::collectOverrides($config, $value, $overrides, "$key.");
+ }
+ else {
+ NestedArray::setValue($overrides, explode('.', $key), $value);
+ }
}
return $overrides;
@@ -207,4 +218,34 @@ class Utility {
return php_sapi_name() === 'cli';
}
+ /**
+ * Checks whether a certain value matches the configuration.
+ *
+ * This unifies checking for matches with the common configuration pattern of
+ * having one "All except those selected"/"Only the selected" option
+ * ("default") and a list of options to select.
+ *
+ * @param mixed $value
+ * The value to check.
+ * @param array $settings
+ * The settings to check against, as an associative array with the following
+ * keys:
+ * - default: Boolean defining the default for not-selected items. TRUE
+ * means "All except those selected", FALSE means "Only the selected".
+ * Defaults to TRUE.
+ * - selected: A numerically indexed array of the selected options. Defaults
+ * to an empty array.
+ *
+ * @return bool
+ * TRUE if the value matches according to the configuration, FALSE
+ * otherwise.
+ */
+ public static function matches($value, array $settings) {
+ $settings += [
+ 'default' => TRUE,
+ 'selected' => [],
+ ];
+ return in_array($value, $settings['selected']) != $settings['default'];
+ }
+
}
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test/search_api_test.info.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test/search_api_test.info.yml
index d8242e41c..474e13c3e 100644
--- a/sites/all/modules/contrib/search/search_api/tests/search_api_test/search_api_test.info.yml
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test/search_api_test.info.yml
@@ -7,8 +7,8 @@ dependencies:
# core: 8.x
hidden: true
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_db/config/install/search_api.server.database_search_server.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_db/config/install/search_api.server.database_search_server.yml
index 41bb0ae34..0e79fda44 100644
--- a/sites/all/modules/contrib/search/search_api/tests/search_api_test_db/config/install/search_api.server.database_search_server.yml
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_db/config/install/search_api.server.database_search_server.yml
@@ -5,7 +5,7 @@ backend: search_api_db
backend_config:
database: 'default:default'
min_chars: 3
- partial_matches: false
+ matching: words
status: true
langcode: en
dependencies:
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_db/search_api_test_db.info.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_db/search_api_test_db.info.yml
index 6cf28e880..4b3cd1eb1 100644
--- a/sites/all/modules/contrib/search/search_api/tests/search_api_test_db/search_api_test_db.info.yml
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_db/search_api_test_db.info.yml
@@ -8,8 +8,8 @@ dependencies:
# core: 8.x
hidden: true
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_example_content/search_api_test_example_content.info.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_example_content/search_api_test_example_content.info.yml
index 833357e35..365b23319 100644
--- a/sites/all/modules/contrib/search/search_api/tests/search_api_test_example_content/search_api_test_example_content.info.yml
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_example_content/search_api_test_example_content.info.yml
@@ -7,8 +7,8 @@ dependencies:
# core: 8.x
hidden: true
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/config/install/field.field.entity_test.article.links.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/config/install/field.field.entity_test_mulrev_changed.article.links.yml
similarity index 100%
rename from sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/config/install/field.field.entity_test.article.links.yml
rename to sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/config/install/field.field.entity_test_mulrev_changed.article.links.yml
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/config/install/field.storage.entity_test.links.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/config/install/field.storage.entity_test_mulrev_changed.links.yml
similarity index 100%
rename from sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/config/install/field.storage.entity_test.links.yml
rename to sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/config/install/field.storage.entity_test_mulrev_changed.links.yml
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/search_api_test_extraction.info.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/search_api_test_extraction.info.yml
index 645063f64..71819b0ef 100644
--- a/sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/search_api_test_extraction.info.yml
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_extraction/search_api_test_extraction.info.yml
@@ -7,8 +7,8 @@ dependencies:
# core: 8.x
hidden: true
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.info.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.info.yml
index 758f4cce4..fd7365aef 100644
--- a/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.info.yml
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.info.yml
@@ -7,8 +7,8 @@ dependencies:
# core: 8.x
hidden: true
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.module b/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.module
index 0591d319d..8aac84495 100644
--- a/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.module
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.module
@@ -31,5 +31,5 @@ function search_api_test_hooks_search_api_query_andrew_hill_alter(QueryInterface
* Implements hook_search_api_results_TAG_alter().
*/
function search_api_test_hooks_search_api_results_andrew_hill_alter(ResultSetInterface &$results) {
- drupal_set_message('Llama');
+ \Drupal::messenger()->addStatus('Llama');
}
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.search_api.inc b/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.search_api.inc
index 9a85b5d0d..e9daf1712 100644
--- a/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.search_api.inc
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_hooks/search_api_test_hooks.search_api.inc
@@ -70,22 +70,22 @@ function search_api_test_hooks_search_api_displays_alter(array &$displays) {
*/
function search_api_test_hooks_search_api_index_items_alter(IndexInterface $index, array &$items) {
unset($items['entity:node/1:en']);
- drupal_set_message('Stormy');
+ \Drupal::messenger()->addStatus('Stormy');
}
/**
* Implements hook_search_api_items_indexed().
*/
function search_api_test_hooks_search_api_items_indexed(IndexInterface $index, array $item_ids) {
- drupal_set_message('Please set me at ease');
+ \Drupal::messenger()->addStatus('Please set me at ease');
}
/**
* Implements hook_search_api_query_alter().
*/
function search_api_test_hooks_search_api_query_alter(QueryInterface &$query) {
- drupal_set_message('Funky blue note');
- drupal_set_message(sprintf('Search id: %s', $query->getSearchId(FALSE)));
+ \Drupal::messenger()->addStatus('Funky blue note');
+ \Drupal::messenger()->addStatus("Search id: {$query->getSearchId(FALSE)}");
$query->addTag('andrew_hill');
}
@@ -93,14 +93,14 @@ function search_api_test_hooks_search_api_query_alter(QueryInterface &$query) {
* Implements hook_search_api_results_alter().
*/
function search_api_test_hooks_search_api_results_alter(ResultSetInterface &$results) {
- drupal_set_message('Stepping into tomorrow');
+ \Drupal::messenger()->addStatus('Stepping into tomorrow');
}
/**
* Implements hook_search_api_index_reindex().
*/
function search_api_test_hooks_search_api_index_reindex(IndexInterface $index, $clear = FALSE) {
- drupal_set_message('Montara');
+ \Drupal::messenger()->addStatus('Montara');
}
/**
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_inconsistent_config/config/install/search_api.index.inconsistent_search_index.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_inconsistent_config/config/install/search_api.index.inconsistent_search_index.yml
new file mode 100644
index 000000000..58e08a78e
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_inconsistent_config/config/install/search_api.index.inconsistent_search_index.yml
@@ -0,0 +1,33 @@
+id: inconsistent_search_index
+name: 'Inconsistent search index'
+description: 'An index used for testing'
+read_only: false
+field_settings:
+ unknown_property:
+ label: 'Unknown property'
+ type: integer
+ datasource_id: 'entity:entity_test_mulrev_changed'
+ property_path: unknown_property
+processor_settings:
+ add_url:
+ weights:
+ preprocess_index: -30
+ aggregated_field:
+ weights:
+ add_properties: 20
+ search_api_test: { }
+options:
+ cron_limit: -1
+ index_directly: false
+datasource_settings:
+ 'entity:entity_test_mulrev_changed': { }
+tracker_settings:
+ 'default': { }
+server: inconsistent_search_server
+status: true
+langcode: en
+dependencies:
+ config:
+ - search_api.server.inconsistent_search_server
+ module:
+ - entity_test
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_inconsistent_config/config/install/search_api.server.inconsistent_search_server.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_inconsistent_config/config/install/search_api.server.inconsistent_search_server.yml
new file mode 100644
index 000000000..4b10016f6
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_inconsistent_config/config/install/search_api.server.inconsistent_search_server.yml
@@ -0,0 +1,10 @@
+id: inconsistent_search_server
+name: 'Inconsistent search server'
+description: 'A server used for testing'
+backend: search_api_test
+backend_config: { }
+status: false
+langcode: en
+dependencies:
+ module:
+ - search_api_test
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_inconsistent_config/search_api_test_inconsistent_config.info.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_inconsistent_config/search_api_test_inconsistent_config.info.yml
new file mode 100644
index 000000000..c89321afc
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_inconsistent_config/search_api_test_inconsistent_config.info.yml
@@ -0,0 +1,15 @@
+name: 'Search API Inconsistent Configs Test'
+type: module
+description: 'Support module for Search API tests'
+package: Search
+dependencies:
+ - search_api:search_api
+ - search_api:search_api_test
+# core: 8.x
+hidden: true
+
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
+core: '8.x'
+project: 'search_api'
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_tasks/search_api_test_tasks.info.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_tasks/search_api_test_tasks.info.yml
index 07ae08a2a..7c62c1d69 100644
--- a/sites/all/modules/contrib/search/search_api/tests/search_api_test_tasks/search_api_test_tasks.info.yml
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_tasks/search_api_test_tasks.info.yml
@@ -7,8 +7,8 @@ dependencies:
# core: 8.x
hidden: true
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_views/search_api_test_views.info.yml b/sites/all/modules/contrib/search/search_api/tests/search_api_test_views/search_api_test_views.info.yml
index fa71ea3ac..9dc6cfa1e 100644
--- a/sites/all/modules/contrib/search/search_api/tests/search_api_test_views/search_api_test_views.info.yml
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_views/search_api_test_views.info.yml
@@ -6,12 +6,13 @@ dependencies:
- search_api:search_api
- search_api:search_api_test_db
- drupal:node
+ - drupal:rest
- drupal:views
# core: 8.x
hidden: true
-# Information added by Drupal.org packaging script on 2018-02-23
-version: '8.x-1.7'
+# Information added by Drupal.org packaging script on 2018-07-19
+version: '8.x-1.9'
core: '8.x'
project: 'search_api'
-datestamp: 1519387691
+datestamp: 1531985591
diff --git a/sites/all/modules/contrib/search/search_api/tests/search_api_test_views/search_api_test_views.module b/sites/all/modules/contrib/search/search_api/tests/search_api_test_views/search_api_test_views.module
index 5e31a7fa1..2fa0006e5 100644
--- a/sites/all/modules/contrib/search/search_api/tests/search_api_test_views/search_api_test_views.module
+++ b/sites/all/modules/contrib/search/search_api/tests/search_api_test_views/search_api_test_views.module
@@ -22,6 +22,6 @@ function search_api_test_views_search_api_query_alter(QueryInterface $query) {
$message[] = "'$combined_property_path'";
}
}
- drupal_set_message(implode(' ', $message));
+ \Drupal::messenger()->addStatus(implode(' ', $message));
}
}
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Functional/ExampleContentTrait.php b/sites/all/modules/contrib/search/search_api/tests/src/Functional/ExampleContentTrait.php
index c24f7510a..3fff69d2a 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Functional/ExampleContentTrait.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Functional/ExampleContentTrait.php
@@ -17,6 +17,13 @@ trait ExampleContentTrait {
*/
protected $entities = [];
+ /**
+ * The Search API item IDs of the generated entities.
+ *
+ * @var string[]
+ */
+ protected $ids = [];
+
/**
* Sets up the necessary bundles on the test entity type.
*/
@@ -82,10 +89,12 @@ trait ExampleContentTrait {
* The created entity.
*/
protected function addTestEntity($id, array $values) {
- $storage = \Drupal::entityTypeManager()->getStorage('entity_test_mulrev_changed');
+ $entity_type = 'entity_test_mulrev_changed';
+ $storage = \Drupal::entityTypeManager()->getStorage($entity_type);
$values['id'] = $id;
$this->entities[$id] = $storage->create($values);
$this->entities[$id]->save();
+ $this->ids[$id] = Utility::createCombinedId("entity:$entity_type", "$id:en");
return $this->entities[$id];
}
@@ -114,8 +123,9 @@ trait ExampleContentTrait {
* An array of item IDs.
*/
protected function getItemIds(array $entity_ids) {
- $translate_ids = function ($entity_id) {
- return Utility::createCombinedId('entity:entity_test_mulrev_changed', $entity_id . ':en');
+ $map = $this->ids;
+ $translate_ids = function ($entity_id) use ($map) {
+ return $map[$entity_id];
};
return array_map($translate_ids, $entity_ids);
}
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Functional/IntegrationTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Functional/IntegrationTest.php
index 39d678daa..7b4ed0a5f 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Functional/IntegrationTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Functional/IntegrationTest.php
@@ -1206,6 +1206,7 @@ class IntegrationTest extends SearchApiBrowserTestBase {
$this->submitForm($edit, 'Save');
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains('All content was scheduled for reindexing so the new settings can take effect.');
+ $this->assertSession()->responseContains($this->getIndex()->toUrl()->toString());
}
/**
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Functional/ViewsTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Functional/ViewsTest.php
index 4a1106fdd..23e204998 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Functional/ViewsTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Functional/ViewsTest.php
@@ -31,7 +31,6 @@ class ViewsTest extends SearchApiBrowserTestBase {
public static $modules = [
'block',
'language',
- 'rest',
'search_api_test_views',
'views_ui',
];
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/BasicTrackerTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/BasicTrackerTest.php
index b7c273b7e..b6d8c8780 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/BasicTrackerTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/BasicTrackerTest.php
@@ -86,9 +86,8 @@ class BasicTrackerTest extends KernelTestBase {
public function testTracking($indexing_order) {
// Add a logger that throws an exception when used, so a caught exception
// within any of the tracker methods will still cause a test fail.
- // @todo Change to createMock() once we depend on Drupal 8.5+. See #2930839.
/** @var \PHPUnit_Framework_MockObject_MockObject|\Psr\Log\LoggerInterface $logger */
- $logger = $this->getMock(LoggerInterface::class);
+ $logger = $this->createMock(LoggerInterface::class);
$logger->method('log')
->willReturnCallback(function ($level, $message, array $variables) {
$error = 'Tracking operation threw ';
@@ -318,7 +317,7 @@ class BasicTrackerTest extends KernelTestBase {
$this->tracker->setDatabaseConnection($connection);
/** @var \PHPUnit_Framework_MockObject_MockObject|\Psr\Log\LoggerInterface $logger */
- $logger = $this->getMock(LoggerInterface::class);
+ $logger = $this->createMock(LoggerInterface::class);
$log = [];
$logger->method('log')->willReturnCallback(function () use (&$log) {
$log[] = func_get_args();
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/ConfigEntity/ConfigOverrideKernelTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/ConfigEntity/ConfigOverrideKernelTest.php
index 86a73e735..3c3e15737 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/ConfigEntity/ConfigOverrideKernelTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/ConfigEntity/ConfigOverrideKernelTest.php
@@ -197,7 +197,12 @@ class ConfigOverrideKernelTest extends KernelTestBase {
// Verify that overriding "status" prevents the server's indexes from being
// disabled when attempting to disable the server.
$GLOBALS['config']['search_api.server.test_server']['status'] = TRUE;
- $this->server->disable()->save();
+ \Drupal::configFactory()->clearStaticCache();
+ /** @var \Drupal\search_api\Entity\SearchApiConfigEntityStorage $server_storage */
+ $server_storage = \Drupal::entityTypeManager()
+ ->getStorage('search_api_server');
+ $server = $server_storage->loadOverrideFree($server->id());
+ $server->disable()->save();
\Drupal::configFactory()->clearStaticCache();
$index = Index::load($this->index->id());
$this->assertTrue($index->status());
@@ -206,9 +211,6 @@ class ConfigOverrideKernelTest extends KernelTestBase {
// Verify that overrides are not present when loading the server
// override-free.
- /** @var \Drupal\search_api\Entity\SearchApiConfigEntityStorage $server_storage */
- $server_storage = \Drupal::entityTypeManager()
- ->getStorage('search_api_server');
$server = $server_storage->loadOverrideFree($server->id());
$this->assertEquals('Test server', $server->label());
}
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/ConfigEntity/DefaultConfigEntityInstallationTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/ConfigEntity/DefaultConfigEntityInstallationTest.php
new file mode 100644
index 000000000..a8eaa59df
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/ConfigEntity/DefaultConfigEntityInstallationTest.php
@@ -0,0 +1,85 @@
+installEntitySchema('entity_test_mulrev_changed');
+ $this->installEntitySchema('search_api_task');
+ $this->installConfig('search_api');
+ }
+
+ /**
+ * Tests that installing config entities from an extension works correctly.
+ */
+ public function testExtensionInstallation() {
+ $this->installConfig('search_api_test_inconsistent_config');
+
+ $index = Index::load('inconsistent_search_index');
+ $this->assertNotNull($index);
+ $values = $index->toArray();
+
+ // Make sure the index was not processed at all upon saving.
+ $this->assertTrue($index->status());
+ $this->assertArrayNotHasKey('rendered_item', $values['processor_settings']);
+ $this->assertArrayHasKey('unknown_property', $values['field_settings']);
+ $methods = $this->getCalledMethods('processor');
+ $this->assertNotContains('preIndexSave', $methods);
+ }
+
+ /**
+ * Tests that creating new config entities directly works correctly.
+ */
+ public function testNormalEntityCreation() {
+ $dir = __DIR__ . '/../../../search_api_test_inconsistent_config/config/install/';
+ $yaml_file = $dir . 'search_api.server.inconsistent_search_server.yml';
+ $values = Yaml::decode(file_get_contents($yaml_file));
+ Server::create($values)->save();
+ $yaml_file = $dir . 'search_api.index.inconsistent_search_index.yml';
+ $values = Yaml::decode(file_get_contents($yaml_file));
+ Index::create($values)->save();
+
+ $index = Index::load('inconsistent_search_index');
+ $this->assertNotNull($index);
+ $values = $index->toArray();
+
+ // Make sure the index was not processed at all upon saving.
+ $this->assertFalse($index->status());
+ $this->assertArrayHasKey('rendered_item', $values['processor_settings']);
+ $this->assertArrayNotHasKey('unknown_property', $values['field_settings']);
+ $methods = $this->getCalledMethods('processor');
+ $this->assertContains('preIndexSave', $methods);
+ }
+
+}
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/ConfigEntity/DependencyRemovalTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/ConfigEntity/DependencyRemovalTest.php
index 014e0a97d..c9e16a63c 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/ConfigEntity/DependencyRemovalTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/ConfigEntity/DependencyRemovalTest.php
@@ -2,6 +2,8 @@
namespace Drupal\Tests\search_api\Kernel\ConfigEntity;
+use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
+use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
use Drupal\KernelTests\KernelTestBase;
use Drupal\field\Entity\FieldConfig;
@@ -304,8 +306,8 @@ class DependencyRemovalTest extends KernelTestBase {
// store (the index will purge any unsaved configuration of it upon
// deletion, which uses a "user-shared temp store", which in turn uses a
// key/value store).
- $mock = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
- $mock_factory = $this->getMock('Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface');
+ $mock = $this->createMock(KeyValueStoreExpirableInterface::class);
+ $mock_factory = $this->createMock(KeyValueExpirableFactoryInterface::class);
$mock_factory->method('get')->willReturn($mock);
$this->container->set('keyvalue.expirable', $mock_factory);
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Datasource/ContentEntityDatasourceTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Datasource/ContentEntityDatasourceTest.php
index c2bc267af..da028b7f0 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Datasource/ContentEntityDatasourceTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Datasource/ContentEntityDatasourceTest.php
@@ -169,6 +169,61 @@ class ContentEntityDatasourceTest extends KernelTestBase {
}
}
+ /**
+ * Tests viewing of items.
+ *
+ * @covers ::viewItem
+ * @covers ::viewMultipleItems
+ */
+ public function testItemViewing() {
+ $loaded_items = $this->datasource->loadMultiple($this->allItemIds);
+ $builder = \Drupal::entityTypeManager()
+ ->getViewBuilder('entity_test_mulrev_changed');
+
+ $item = $loaded_items['1:l0'];
+ $build = $this->datasource->viewItem($item, 'foobar');
+ $expected = [
+ '#entity_test_mulrev_changed' => $item->getValue(),
+ '#view_mode' => 'foobar',
+ '#cache' => [
+ 'tags' => [
+ 'entity_test_mulrev_changed:1',
+ 'entity_test_mulrev_changed_view',
+ ],
+ 'contexts' => [],
+ 'max-age' => -1,
+ ],
+ '#weight' => 0,
+ '#pre_render' => [
+ [$builder, 'build'],
+ ],
+ ];
+ $this->assertEquals($expected, $build);
+
+ $build = $this->datasource->viewMultipleItems($loaded_items, 'foobar');
+ $this->assertTrue($build['#sorted']);
+ $this->assertEquals([[$builder, 'buildMultiple']], $build['#pre_render']);
+ foreach ($loaded_items as $item_id => $item) {
+ /** @var \Drupal\Core\Entity\EntityInterface $entity */
+ $entity = $item->getValue();
+ $expected = [
+ '#entity_test_mulrev_changed' => $entity,
+ '#view_mode' => 'foobar',
+ '#cache' => [
+ 'tags' => [
+ 'entity_test_mulrev_changed:' . $entity->id(),
+ 'entity_test_mulrev_changed_view',
+ ],
+ 'contexts' => [],
+ 'max-age' => -1,
+ ],
+ ];
+ $this->assertArrayHasKey('#weight', $build[$item_id]);
+ unset($build[$item_id]['#weight']);
+ $this->assertEquals($expected, $build[$item_id]);
+ }
+ }
+
/**
* Verifies that paged item discovery works correctly.
*
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Index/IndexImportTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Index/IndexImportTest.php
index 9d4d4a2d5..6a4c67767 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Index/IndexImportTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Index/IndexImportTest.php
@@ -93,6 +93,9 @@ class IndexImportTest extends KernelTestBase {
];
$sync->write('search_api.index.database_search_index', $import_config);
+ // The system.site key is required for import validation.
+ $sync->write('system.site', []);
+
// Import the test configuration.
$config_importer = $this->configImporter();
$this->assertTrue($config_importer->hasUnprocessedConfigurationChanges(), 'Import prepared');
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/PostRequestIndexingTrait.php b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/PostRequestIndexingTrait.php
index dddcfc010..3430fd51d 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/PostRequestIndexingTrait.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/PostRequestIndexingTrait.php
@@ -12,7 +12,7 @@ trait PostRequestIndexingTrait {
*/
protected function triggerPostRequestIndexing() {
\Drupal::getContainer()->get('search_api.post_request_indexing')
- ->onKernelTerminate();
+ ->destruct();
}
}
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Processor/AddURLKernelTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Processor/AddURLKernelTest.php
new file mode 100644
index 000000000..4b6db222d
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Processor/AddURLKernelTest.php
@@ -0,0 +1,63 @@
+index, 'url');
+ $url_field->setType('string');
+ $url_field->setPropertyPath('search_api_url');
+ $url_field->setLabel('Item URL');
+ $this->index->addField($url_field);
+ $this->index->save();
+
+ $this->nodes[0] = Node::create([
+ 'title' => 'Test',
+ 'type' => 'article',
+ ]);
+ $this->nodes[0]->save();
+ }
+
+ /**
+ * Tests extracting the field for a search item.
+ *
+ * @covers ::addFieldValues
+ */
+ public function testItemFieldExtraction() {
+ $node = $this->nodes[0];
+ $id = Utility::createCombinedId('entity:node', $node->id() . ':en');
+ $item = \Drupal::getContainer()
+ ->get('search_api.fields_helper')
+ ->createItemFromObject($this->index, $node->getTypedData(), $id);
+
+ // Extract field values and check the value of the URL field.
+ $fields = $item->getFields();
+ $expected = [$node->toUrl('canonical')->toString()];
+ $this->assertEquals($expected, $fields['url']->getValues());
+ }
+
+}
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/System/QueryTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/System/QueryTest.php
index 0766c3360..c5b27f142 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/System/QueryTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/System/QueryTest.php
@@ -2,6 +2,7 @@
namespace Drupal\Tests\search_api\Kernel\System;
+use Drupal\Core\Messenger\MessengerInterface;
use Drupal\KernelTests\KernelTestBase;
use Drupal\search_api\Entity\Index;
use Drupal\search_api\Entity\Server;
@@ -102,18 +103,15 @@ class QueryTest extends KernelTestBase {
$this->assertEquals($level, $query->getProcessingLevel());
$query->addTag('andrew_hill');
- // @todo Use \Drupal::messenger() once we depend on Drupal 8.5+. See
- // #2931730.
- drupal_get_messages();
+ \Drupal::messenger()->deleteAll();
$query->execute();
- $messages = drupal_get_messages();
+ $messages = \Drupal::messenger()->all();
+ \Drupal::messenger()->deleteAll();
$methods = $this->getCalledMethods('processor');
if ($hooks_and_processors_invoked) {
- // @todo Replace "status" with MessengerInterface::TYPE_STATUS once we
- // depend on Drupal 8.5+. See #2931730.
$expected = [
- 'status' => [
+ MessengerInterface::TYPE_STATUS => [
'Funky blue note',
'Search id: ',
'Stepping into tomorrow',
@@ -225,4 +223,31 @@ class QueryTest extends KernelTestBase {
$this->assertInstanceOf('Drupal\search_api_test\Plugin\search_api\display\TestDisplay', $query->getDisplayPlugin());
}
+ /**
+ * Tests the getOriginalQuery() method.
+ */
+ public function testGetOriginalQuery() {
+ $this->getCalledMethods('backend');
+
+ $query = $this->index->query()
+ ->addCondition('search_api_id', 2, '<>');
+ $query_clone_1 = $query->getOriginalQuery();
+ $this->assertEquals($query, $query_clone_1);
+ $this->assertNotSame($query, $query_clone_1);
+
+ $query->sort('search_api_id');
+ $query_clone_2 = clone $query;
+ $query->execute();
+ $methods = $this->getCalledMethods('backend');
+ $this->assertEquals(['search'], $methods);
+ $this->assertFalse($query_clone_1->hasExecuted());
+
+ $original_query = $query->getOriginalQuery();
+ $this->assertEquals($query_clone_2, $original_query);
+ $this->assertFalse($original_query->hasExecuted());
+ $original_query->execute();
+ $methods = $this->getCalledMethods('backend');
+ $this->assertEquals(['search'], $methods);
+ }
+
}
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/System/SerializationTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/System/SerializationTest.php
index 5c624dad7..f266e560b 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/System/SerializationTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/System/SerializationTest.php
@@ -314,11 +314,11 @@ class SerializationTest extends KernelTestBase {
protected function setMockIndexStorage() {
$index = $this->createTestIndex();
- $storage = $this->getMock(EntityStorageInterface::class);
+ $storage = $this->createMock(EntityStorageInterface::class);
$storage->method('load')->willReturnMap([
[$index->id(), $index],
]);
- $entity_type_manager = $this->getMock(EntityTypeManagerInterface::class);
+ $entity_type_manager = $this->createMock(EntityTypeManagerInterface::class);
$entity_type_manager->method('getStorage')->willReturnMap([
['search_api_index', $storage],
]);
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Views/ViewsPropertyExtractionTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Views/ViewsPropertyExtractionTest.php
index 8e167457f..dfb48ebad 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Views/ViewsPropertyExtractionTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Kernel/Views/ViewsPropertyExtractionTest.php
@@ -57,8 +57,8 @@ class ViewsPropertyExtractionTest extends KernelTestBase {
$datasource_id = 'entity:user';
/** @var \Drupal\search_api\IndexInterface|\PHPUnit_Framework_MockObject_MockObject $index */
- $index = $this->getMock(IndexInterface::class);
- $property2 = $this->getMock(ConfigurablePropertyInterface::class);
+ $index = $this->createMock(IndexInterface::class);
+ $property2 = $this->createMock(ConfigurablePropertyInterface::class);
$property2->method('getProcessorId')->willReturn('processor2');
$property2->method('getDataType')->willReturn('string');
$property2->method('defaultConfiguration')->willReturn([]);
@@ -92,11 +92,11 @@ class ViewsPropertyExtractionTest extends KernelTestBase {
};
};
$value1 = $processor_property_value ?: 'Processor 1';
- $processor1 = $this->getMock(ProcessorInterface::class);
+ $processor1 = $this->createMock(ProcessorInterface::class);
$processor1->method('addFieldValues')
->willReturnCallback($generate_add_field_values($value1));
$value2 = $processor_property_value ?: 'Processor 2';
- $processor2 = $this->getMock(ProcessorInterface::class);
+ $processor2 = $this->createMock(ProcessorInterface::class);
$processor2->method('addFieldValues')
->willReturnCallback($generate_add_field_values($value2));
$index->method('getProcessor')->willReturnMap([
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/BackendPluginBaseTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/BackendPluginBaseTest.php
index 459f54c9b..ceb47c8f4 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/BackendPluginBaseTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/BackendPluginBaseTest.php
@@ -29,10 +29,10 @@ class BackendPluginBaseTest extends UnitTestCase {
* @dataProvider getQueryFulltextFieldsDataProvider
*/
public function testGetQueryFulltextFields($query_fields, array $expected) {
- $index = $this->getMock(IndexInterface::class);
+ $index = $this->createMock(IndexInterface::class);
$index->method('getFulltextFields')->willReturn(['field1', 'field2']);
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->method('getFulltextFields')->willReturn($query_fields);
$query->method('getIndex')->willReturn($index);
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/DateDataTypeTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/DateDataTypeTest.php
new file mode 100644
index 000000000..0b03a2678
--- /dev/null
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/DateDataTypeTest.php
@@ -0,0 +1,71 @@
+plugin = new DateDataType([], '', []);
+ }
+
+ /**
+ * Tests value conversion.
+ *
+ * @param mixed $value
+ * The incoming value.
+ * @param int $expected
+ * The expected converted value.
+ *
+ * @dataProvider getValueTestDataProvider
+ */
+ public function testGetValue($value, $expected) {
+ $value = $this->plugin->getValue($value);
+ $this->assertSame($expected, $value);
+ }
+
+ /**
+ * Provides test data for testGetValue().
+ *
+ * @return array[]
+ * An array of argument arrays for testGetValue().
+ *
+ * @see \Drupal\Tests\search_api\Unit\DateDataTypeTest::testGetValue()
+ */
+ public function getValueTestDataProvider() {
+ $t = 1400000000;
+ $f = 'Y-m-d H:i:s';
+ return [
+ 'timestamp' => [$t, $t],
+ 'string timestamp' => ["$t", $t],
+ 'float timestamp' => [$t + 0.12, $t],
+ 'date string' => [gmdate($f, $t), $t],
+ 'date string with timezone' => [date($f . 'P', $t), $t],
+ ];
+ }
+
+}
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/ItemFieldTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/ItemFieldTest.php
index 0755eec97..4274d4f68 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/ItemFieldTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/ItemFieldTest.php
@@ -2,6 +2,7 @@
namespace Drupal\Tests\search_api\Unit;
+use Drupal\search_api\DataType\DataTypeInterface;
use Drupal\search_api\Entity\Index;
use Drupal\search_api\Item\Field;
use Drupal\Tests\UnitTestCase;
@@ -28,7 +29,7 @@ class ItemFieldTest extends UnitTestCase {
protected function setUp() {
parent::setUp();
- $data_type = $this->getMock('Drupal\search_api\DataType\DataTypeInterface');
+ $data_type = $this->createMock(DataTypeInterface::class);
$data_type->expects($this->any())
->method('getValue')
->willReturnCallback(function ($v) {
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/AddURLTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/AddURLTest.php
index 59857c029..0372178fd 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/AddURLTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/AddURLTest.php
@@ -4,6 +4,8 @@ namespace Drupal\Tests\search_api\Unit\Processor;
use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
use Drupal\Core\TypedData\DataDefinitionInterface;
+use Drupal\search_api\Datasource\DatasourceInterface;
+use Drupal\search_api\IndexInterface;
use Drupal\search_api\Plugin\search_api\processor\AddURL;
use Drupal\Tests\UnitTestCase;
@@ -49,7 +51,7 @@ class AddURLTest extends UnitTestCase {
->will($this->returnValue('http://www.example.com/node/example'));
// Mock the data source of the indexer to return the mocked url object.
- $datasource = $this->getMock('Drupal\search_api\Datasource\DatasourceInterface');
+ $datasource = $this->createMock(DatasourceInterface::class);
$datasource->expects($this->any())
->method('getItemUrl')
->withAnyParameters()
@@ -57,7 +59,7 @@ class AddURLTest extends UnitTestCase {
// Create a mock for the index to return the datasource mock.
/** @var \Drupal\search_api\IndexInterface $index */
- $index = $this->index = $this->getMock('Drupal\search_api\IndexInterface');
+ $index = $this->index = $this->createMock(IndexInterface::class);
$this->index->expects($this->any())
->method('getDatasource')
->with('entity:node')
@@ -130,7 +132,7 @@ class AddURLTest extends UnitTestCase {
}
// Verify that there are no properties if a datasource is given.
- $datasource = $this->getMock('Drupal\search_api\Datasource\DatasourceInterface');
+ $datasource = $this->createMock(DatasourceInterface::class);
$properties = $this->processor->getPropertyDefinitions($datasource);
$this->assertEmpty($properties, 'Datasource-specific properties did not get changed.');
}
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/AggregatedFieldsTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/AggregatedFieldsTest.php
index 6e588d2fd..664606adb 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/AggregatedFieldsTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/AggregatedFieldsTest.php
@@ -63,7 +63,7 @@ class AggregatedFieldsTest extends UnitTestCase {
protected function setUp() {
parent::setUp();
- $datasource = $this->getMock(DatasourceInterface::class);
+ $datasource = $this->createMock(DatasourceInterface::class);
$datasource->expects($this->any())
->method('getPropertyDefinitions')
->willReturn([]);
@@ -99,11 +99,7 @@ class AggregatedFieldsTest extends UnitTestCase {
$this->index->addProcessor($this->processor);
$this->setUpMockContainer();
- $plugin_helper = $this->getMockBuilder(PluginHelperInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $plugin_helper->method('getProcessorsByStage')
- ->willReturn([]);
+ $plugin_helper = $this->createMock(PluginHelperInterface::class);
$this->container->set('search_api.plugin_helper', $plugin_helper);
// We want to check correct data type handling, so we need a somewhat more
@@ -120,7 +116,7 @@ class AggregatedFieldsTest extends UnitTestCase {
return '*' . $value;
}
};
- $data_type = $this->getMock(DataTypeInterface::class);
+ $data_type = $this->createMock(DataTypeInterface::class);
$data_type->method('getValue')
->willReturnCallback($this->valueCallback);
$data_type_manager->method('createInstance')
@@ -292,7 +288,7 @@ class AggregatedFieldsTest extends UnitTestCase {
$this->assertEquals($expected_description, $properties['aggregated_field']->getDescription(), 'Correct description set in the data definition.');
// Verify that there are no properties if a datasource is given.
- $datasource = $this->getMock(DatasourceInterface::class);
+ $datasource = $this->createMock(DatasourceInterface::class);
$properties = $this->processor->getPropertyDefinitions($datasource);
$this->assertEmpty($properties, 'Datasource-specific properties did not get changed.');
}
@@ -302,13 +298,13 @@ class AggregatedFieldsTest extends UnitTestCase {
*/
public function testFieldExtraction() {
/** @var \Drupal\Tests\search_api\Unit\TestComplexDataInterface|\PHPUnit_Framework_MockObject_MockObject $object */
- $object = $this->getMock(TestComplexDataInterface::class);
- $bar_foo_property = $this->getMock(TypedDataInterface::class);
+ $object = $this->createMock(TestComplexDataInterface::class);
+ $bar_foo_property = $this->createMock(TypedDataInterface::class);
$bar_foo_property->method('getValue')
->willReturn('value3');
$bar_foo_property->method('getDataDefinition')
->willReturn(new DataDefinition());
- $bar_property = $this->getMock(TestComplexDataInterface::class);
+ $bar_property = $this->createMock(TestComplexDataInterface::class);
$bar_property->method('get')
->willReturnMap([
['foo', $bar_foo_property],
@@ -317,7 +313,7 @@ class AggregatedFieldsTest extends UnitTestCase {
->willReturn([
'foo' => TRUE,
]);
- $foobar_property = $this->getMock(TypedDataInterface::class);
+ $foobar_property = $this->createMock(TypedDataInterface::class);
$foobar_property->method('getValue')
->willReturn('wrong_value2');
$foobar_property->method('getDataDefinition')
@@ -334,7 +330,7 @@ class AggregatedFieldsTest extends UnitTestCase {
]);
/** @var \Drupal\search_api\IndexInterface|\PHPUnit_Framework_MockObject_MockObject $index */
- $index = $this->getMock(IndexInterface::class);
+ $index = $this->createMock(IndexInterface::class);
$fields_helper = \Drupal::getContainer()->get('search_api.fields_helper');
$field = $fields_helper->createField($index, 'aggregated_field', [
@@ -371,7 +367,7 @@ class AggregatedFieldsTest extends UnitTestCase {
],
],
]);
- $processor_mock = $this->getMock(ProcessorInterface::class);
+ $processor_mock = $this->createMock(ProcessorInterface::class);
$processor_mock->method('addFieldValues')
->willReturnCallback(function (ItemInterface $item) {
foreach ($item->getFields(FALSE) as $field) {
@@ -394,7 +390,7 @@ class AggregatedFieldsTest extends UnitTestCase {
$this->processor->setIndex($index);
/** @var \Drupal\search_api\Datasource\DatasourceInterface|\PHPUnit_Framework_MockObject_MockObject $datasource */
- $datasource = $this->getMock(DatasourceInterface::class);
+ $datasource = $this->createMock(DatasourceInterface::class);
$datasource->method('getPluginId')
->willReturn('entity:test1');
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/EntityStatusTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/EntityStatusTest.php
index bf6140ee2..4e84876c6 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/EntityStatusTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/EntityStatusTest.php
@@ -9,6 +9,8 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
use Drupal\file\Entity\File;
use Drupal\node\Entity\Node;
+use Drupal\search_api\Datasource\DatasourceInterface;
+use Drupal\search_api\IndexInterface;
use Drupal\search_api\Plugin\search_api\processor\EntityStatus;
use Drupal\search_api\Utility\Utility;
use Drupal\Tests\UnitTestCase;
@@ -56,10 +58,10 @@ class EntityStatusTest extends UnitTestCase {
$this->processor = new EntityStatus([], 'entity_status', []);
- $this->index = $this->getMock('Drupal\search_api\IndexInterface');
+ $this->index = $this->createMock(IndexInterface::class);
foreach (['node', 'comment', 'user', 'file'] as $entity_type) {
- $datasource = $this->getMock('Drupal\search_api\Datasource\DatasourceInterface');
+ $datasource = $this->createMock(DatasourceInterface::class);
$datasource->expects($this->any())
->method('getEntityTypeId')
->will($this->returnValue($entity_type));
@@ -92,7 +94,7 @@ class EntityStatusTest extends UnitTestCase {
// We therefore need to ensure each of these calls returns an appropriate
// value.
$self = $this;
- $entity_type_manager = $this->getMock(EntityTypeManagerInterface::class);
+ $entity_type_manager = $this->createMock(EntityTypeManagerInterface::class);
$entity_type_manager->method('getDefinition')
->willReturnCallback(function ($entity_type_id) use ($self) {
$entity_type = $self->getMock(EntityTypeInterface::class);
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/FieldsProcessorPluginBaseTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/FieldsProcessorPluginBaseTest.php
index 13fd9c446..d2bcc0eb6 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/FieldsProcessorPluginBaseTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/FieldsProcessorPluginBaseTest.php
@@ -41,7 +41,7 @@ class FieldsProcessorPluginBaseTest extends UnitTestCase {
parent::setUp();
$this->setUpMockContainer();
- $this->index = $this->getMock('Drupal\search_api\IndexInterface');
+ $this->index = $this->createMock(IndexInterface::class);
$this->index->expects($this->any())
->method('status')
->will($this->returnValue(TRUE));
@@ -121,7 +121,7 @@ class FieldsProcessorPluginBaseTest extends UnitTestCase {
// Since it's not possible to override an already specified method on a mock
// object, we need to create a new mock object for the index in this test.
/** @var \Drupal\search_api\IndexInterface|\PHPUnit_Framework_MockObject_MockObject $index */
- $index = $this->getMock(IndexInterface::class);
+ $index = $this->createMock(IndexInterface::class);
$index->method('getFields')->willReturn([
'float_field' => (new Field($this->index, ''))->setType('float'),
'float_field_2' => (new Field($this->index, ''))->setType('float'),
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/HighlightTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/HighlightTest.php
index 02d31b158..05a07eca6 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/HighlightTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/HighlightTest.php
@@ -52,7 +52,7 @@ class HighlightTest extends UnitTestCase {
$this->processor = new Highlight([], 'highlight', []);
- $this->index = $this->getMock(IndexInterface::class);
+ $this->index = $this->createMock(IndexInterface::class);
$this->index->expects($this->any())
->method('getFulltextFields')
->willReturn(['body', 'title']);
@@ -86,18 +86,19 @@ class HighlightTest extends UnitTestCase {
* Tests postprocessing with an empty result set.
*/
public function testPostprocessSearchResultsWithEmptyResult() {
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$results = $this->getMockBuilder(ResultSet::class)
- ->setMethods(['getResultCount'])
+ ->setMethods(['getResultCount', 'getQuery', 'getResultItems'])
->setConstructorArgs([$query])
->getMock();
$results->expects($this->once())
->method('getResultCount')
->will($this->returnValue(0));
- $results->expects($this->never())
- ->method('getQuery');
+ $results->expects($this->once())
+ ->method('getQuery')
+ ->willReturn(NULL);
$results->expects($this->never())
->method('getResultItems');
/** @var \Drupal\search_api\Query\ResultSet $results */
@@ -109,13 +110,13 @@ class HighlightTest extends UnitTestCase {
* Makes sure that queries with "basic" processing set are ignored.
*/
public function testPostprocessBasicQuery() {
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_BASIC);
$results = $this->getMockBuilder(ResultSet::class)
- ->setMethods(['getResultCount', 'getQuery'])
+ ->setMethods(['getResultCount', 'getQuery', 'getResultItems'])
->setConstructorArgs([$query])
->getMock();
@@ -136,13 +137,13 @@ class HighlightTest extends UnitTestCase {
* Tests postprocessing on a query without keywords.
*/
public function testPostprocessSearchResultsWithoutKeywords() {
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
$results = $this->getMockBuilder(ResultSet::class)
- ->setMethods(['getResultCount', 'getQuery'])
+ ->setMethods(['getResultCount', 'getQuery', 'getResultItems'])
->setConstructorArgs([$query])
->getMock();
@@ -167,7 +168,7 @@ class HighlightTest extends UnitTestCase {
* Tests field highlighting with a normal result set.
*/
public function testPostprocessSearchResultsWithResults() {
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -213,7 +214,7 @@ class HighlightTest extends UnitTestCase {
'suffix' => '',
]);
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -256,7 +257,7 @@ class HighlightTest extends UnitTestCase {
public function testPostprocessSearchResultsWithoutHighlight() {
$this->processor->setConfiguration(['highlight' => 'never']);
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -308,7 +309,7 @@ class HighlightTest extends UnitTestCase {
public function testPostprocessSearchResultsHighlightPartial($text, $keywords, $highlighted) {
$this->processor->setConfiguration(['highlight_partial' => TRUE]);
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -382,7 +383,7 @@ class HighlightTest extends UnitTestCase {
* Tests field highlighting when previous highlighting is present.
*/
public function testPostprocessSearchResultsWithPreviousHighlighting() {
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -428,7 +429,7 @@ class HighlightTest extends UnitTestCase {
* Tests whether highlighting works on a longer text.
*/
public function testPostprocessSearchResultsExcerpt() {
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -471,7 +472,7 @@ class HighlightTest extends UnitTestCase {
* Tests whether highlighting works on a longer text matching near the end.
*/
public function testPostprocessSearchResultsExerptMatchNearEnd() {
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -516,7 +517,7 @@ class HighlightTest extends UnitTestCase {
public function testPostprocessSearchResultsWithChangedExcerptLength() {
$this->processor->setConfiguration(['excerpt_length' => 64]);
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -561,7 +562,7 @@ class HighlightTest extends UnitTestCase {
public function testPostprocessSearchResultsWithoutExcerpt() {
$this->processor->setConfiguration(['excerpt' => FALSE]);
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -618,7 +619,7 @@ class HighlightTest extends UnitTestCase {
'will',
],
];
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -663,7 +664,7 @@ class HighlightTest extends UnitTestCase {
* Tests field highlighting and excerpts for two fields.
*/
public function testPostprocessSearchResultsWithTwoFields() {
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -721,7 +722,7 @@ class HighlightTest extends UnitTestCase {
* Tests field highlighting and excerpts with two items.
*/
public function testPostprocessSearchResultsWithTwoItems() {
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -774,7 +775,7 @@ class HighlightTest extends UnitTestCase {
* Tests excerpts with some fields excluded.
*/
public function testExcerptExcludeFields() {
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->expects($this->once())
->method('getProcessingLevel')
->willReturn(QueryInterface::PROCESSING_FULL);
@@ -834,13 +835,13 @@ class HighlightTest extends UnitTestCase {
*/
public function testFieldExtraction() {
/** @var \Drupal\Tests\search_api\Unit\TestComplexDataInterface|\PHPUnit_Framework_MockObject_MockObject $object */
- $object = $this->getMock(TestComplexDataInterface::class);
- $bar_foo_property = $this->getMock(TypedDataInterface::class);
+ $object = $this->createMock(TestComplexDataInterface::class);
+ $bar_foo_property = $this->createMock(TypedDataInterface::class);
$bar_foo_property->method('getValue')
->willReturn('value3 foo');
$bar_foo_property->method('getDataDefinition')
->willReturn(new DataDefinition());
- $bar_property = $this->getMock(TestComplexDataInterface::class);
+ $bar_property = $this->createMock(TestComplexDataInterface::class);
$bar_property->method('get')
->willReturnMap([
['foo', $bar_foo_property],
@@ -849,7 +850,7 @@ class HighlightTest extends UnitTestCase {
->willReturn([
'foo' => TRUE,
]);
- $foobar_property = $this->getMock(TypedDataInterface::class);
+ $foobar_property = $this->createMock(TypedDataInterface::class);
$foobar_property->method('getValue')
->willReturn('wrong_value2 foo');
$foobar_property->method('getDataDefinition')
@@ -891,7 +892,7 @@ class HighlightTest extends UnitTestCase {
],
],
]);
- $processor_mock = $this->getMock(ProcessorInterface::class);
+ $processor_mock = $this->createMock(ProcessorInterface::class);
$processor_mock->method('addFieldValues')
->willReturnCallback(function (ItemInterface $item) {
foreach ($item->getFields(FALSE) as $field) {
@@ -914,7 +915,7 @@ class HighlightTest extends UnitTestCase {
$this->processor->setIndex($this->index);
/** @var \Drupal\search_api\Datasource\DatasourceInterface|\PHPUnit_Framework_MockObject_MockObject $datasource */
- $datasource = $this->getMock(DatasourceInterface::class);
+ $datasource = $this->createMock(DatasourceInterface::class);
$datasource->method('getPluginId')
->willReturn('entity:test1');
@@ -932,7 +933,7 @@ class HighlightTest extends UnitTestCase {
$this->processor->setConfiguration(['excerpt' => FALSE]);
/** @var \Drupal\search_api\Query\QueryInterface|\PHPUnit_Framework_MockObject_MockObject $query */
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->method('getOriginalKeys')
->willReturn('foo');
$query->expects($this->once())
@@ -960,6 +961,63 @@ class HighlightTest extends UnitTestCase {
$this->assertEquals($expected, $fields);
}
+ /**
+ * Tests field highlighting with a result set that has some highlighting data.
+ */
+ public function testPostprocessSearchResultsWithExistingHighlighting() {
+ $query = $this->createMock(QueryInterface::class);
+ $query->expects($this->once())
+ ->method('getProcessingLevel')
+ ->willReturn(QueryInterface::PROCESSING_FULL);
+ $query->expects($this->atLeastOnce())
+ ->method('getOriginalKeys')
+ ->will($this->returnValue('foo'));
+ /** @var \Drupal\search_api\Query\QueryInterface $query */
+
+ $body = $this->createTestField('body', 'entity:node/body');
+ $title = $this->createTestField('title', 'entity:node/title');
+
+ $this->index->expects($this->atLeastOnce())
+ ->method('getFields')
+ ->will($this->returnValue(['body' => $body, 'title' => $title]));
+
+ $this->processor->setIndex($this->index);
+
+ $body_values = ['Some foo value'];
+ $title_values = ['The foo title'];
+ $fields = [
+ 'entity:node/body' => [
+ 'type' => 'text',
+ 'values' => $body_values,
+ ],
+ 'entity:node/title' => [
+ 'type' => 'text',
+ 'values' => $title_values,
+ ],
+ ];
+
+ $items = $this->createItems($this->index, 2, $fields);
+ $items[$this->itemIds[0]]->setExtraData('highlighted_fields', [
+ 'title' => ['The foo title'],
+ ]);
+ $items[$this->itemIds[1]]->setExtraData('highlighted_fields', [
+ 'body' => ['Some foo value'],
+ ]);
+
+ $results = new ResultSet($query);
+ $results->setResultItems($items);
+ $results->setResultCount(1);
+
+ $this->processor->postprocessSearchResults($results);
+
+ $fields = $items[$this->itemIds[0]]->getExtraData('highlighted_fields');
+ $this->assertEquals('The foo title', $fields['title'][0], 'Existing highlighting data for title was correctly kept.');
+ $this->assertEquals('Some foo value', $fields['body'][0], 'Highlighting is correctly applied to body field.');
+ $fields = $items[$this->itemIds[1]]->getExtraData('highlighted_fields');
+ $this->assertEquals('The foo title', $fields['title'][0], 'Highlighting is correctly applied to title field.');
+ $this->assertEquals('Some foo value', $fields['body'][0], 'Existing highlighting data for body was correctly kept.');
+ }
+
/**
* Creates a field object for testing.
*
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/RoleFilterTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/RoleFilterTest.php
index 0961001cb..58c082278 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/RoleFilterTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/RoleFilterTest.php
@@ -4,6 +4,7 @@ namespace Drupal\Tests\search_api\Unit\Processor;
use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
use Drupal\search_api\Datasource\DatasourceInterface;
+use Drupal\search_api\IndexInterface;
use Drupal\search_api\Plugin\search_api\processor\RoleFilter;
use Drupal\search_api\Utility\Utility;
use Drupal\Tests\search_api\Unit\TestNodeInterface;
@@ -46,14 +47,14 @@ class RoleFilterTest extends UnitTestCase {
$this->processor = new RoleFilter([], 'role_filter', []);
/** @var \Drupal\search_api\IndexInterface $index */
- $index = $this->getMock('Drupal\search_api\IndexInterface');
+ $index = $this->createMock(IndexInterface::class);
- $node_datasource = $this->getMock(DatasourceInterface::class);
+ $node_datasource = $this->createMock(DatasourceInterface::class);
$node_datasource->expects($this->any())
->method('getEntityTypeId')
->will($this->returnValue('node'));
/** @var \Drupal\search_api\Datasource\DatasourceInterface $node_datasource */
- $user_datasource = $this->getMock(DatasourceInterface::class);
+ $user_datasource = $this->createMock(DatasourceInterface::class);
$user_datasource->expects($this->any())
->method('getEntityTypeId')
->will($this->returnValue('user'));
@@ -95,7 +96,7 @@ class RoleFilterTest extends UnitTestCase {
* Tests preprocessing search items with an inclusive filter.
*/
public function testFilterInclusive() {
- $configuration['roles'] = ['authenticated' => 'authenticated'];
+ $configuration['roles'] = ['authenticated'];
$configuration['default'] = 0;
$this->processor->setConfiguration($configuration);
@@ -110,7 +111,7 @@ class RoleFilterTest extends UnitTestCase {
* Tests preprocessing search items with an exclusive filter.
*/
public function testFilterExclusive() {
- $configuration['roles'] = ['editor' => 'editor'];
+ $configuration['roles'] = ['editor'];
$configuration['default'] = 1;
$this->processor->setConfiguration($configuration);
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/StemmerTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/StemmerTest.php
index 9e727cbd9..b75177db9 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/StemmerTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/StemmerTest.php
@@ -40,7 +40,7 @@ class StemmerTest extends UnitTestCase {
* @covers ::preprocessIndexItems
*/
public function testPreprocessIndexItems() {
- $index = $this->getMock(IndexInterface::class);
+ $index = $this->createMock(IndexInterface::class);
$item_en = $this->getMockBuilder(ItemInterface::class)
->disableOriginalConstructor()
@@ -88,7 +88,7 @@ class StemmerTest extends UnitTestCase {
*/
public function testPreprocessSearchQuery(array $languages = NULL, $should_process) {
/** @var \Drupal\search_api\Query\QueryInterface|\PHPUnit_Framework_MockObject_MockObject $query */
- $query = $this->getMock(QueryInterface::class);
+ $query = $this->createMock(QueryInterface::class);
$query->method('getLanguages')->willReturn($languages);
// Unfortunately, returning a reference (as getKeys() has to do for
// processing to work) doesn't seem to be possible with a mock object. But
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/StopwordsTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/StopwordsTest.php
index 46b9e2fce..effcd6039 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/StopwordsTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/StopwordsTest.php
@@ -2,6 +2,7 @@
namespace Drupal\Tests\search_api\Unit\Processor;
+use Drupal\search_api\IndexInterface;
use Drupal\search_api\Plugin\search_api\processor\Stopwords;
use Drupal\Tests\UnitTestCase;
@@ -92,7 +93,7 @@ class StopwordsTest extends UnitTestCase {
* Tests the processor's preprocessSearchQuery() method.
*/
public function testPreprocessSearchQuery() {
- $index = $this->getMock('Drupal\search_api\IndexInterface');
+ $index = $this->createMock(IndexInterface::class);
$index->expects($this->any())
->method('status')
->will($this->returnValue(TRUE));
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TestItemsTrait.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TestItemsTrait.php
index 8b1910fc4..6dfb511f5 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TestItemsTrait.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TestItemsTrait.php
@@ -11,6 +11,7 @@ use Drupal\search_api\Utility\DataTypeHelper;
use Drupal\search_api\Utility\FieldsHelper;
use Drupal\search_api\Item\Item;
use Drupal\search_api\Query\Query;
+use Drupal\search_api\Utility\QueryHelperInterface;
use Drupal\search_api\Utility\Utility;
/**
@@ -136,7 +137,7 @@ trait TestItemsTrait {
->getMock();
$fieldsHelper = new FieldsHelper($entityTypeManager, $entityFieldManager, $entityBundleInfo, $dataTypeHelper);
- $queryHelper = $this->getMock('Drupal\search_api\Utility\QueryHelperInterface');
+ $queryHelper = $this->createMock(QueryHelperInterface::class);
$queryHelper->method('createQuery')
->willReturnCallback(function (IndexInterface $index, array $options = []) {
return Query::create($index, $options);
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TokenizerTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TokenizerTest.php
index dcd2dd909..cdac9a528 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TokenizerTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TokenizerTest.php
@@ -2,7 +2,6 @@
namespace Drupal\Tests\search_api\Unit\Processor;
-use Drupal\Component\Utility\Unicode;
use Drupal\search_api\Plugin\search_api\processor\Tokenizer;
use Drupal\search_api\Utility\Utility;
use Drupal\Tests\UnitTestCase;
@@ -184,10 +183,10 @@ class TokenizerTest extends UnitTestCase {
// Generate characters consisting of starts, midpoints, and ends.
$chars = [];
foreach ($starts as $key => $value) {
- $chars[] = self::codepointToUtf8($starts[$key]);
+ $chars[] = static::codepointToUtf8($starts[$key]);
$mid = round(0.5 * ($starts[$key] + $ends[$key]));
- $chars[] = self::codepointToUtf8($mid);
- $chars[] = self::codepointToUtf8($ends[$key]);
+ $chars[] = static::codepointToUtf8($mid);
+ $chars[] = static::codepointToUtf8($ends[$key]);
}
// Merge into a single string and tokenize.
@@ -298,8 +297,8 @@ class TokenizerTest extends UnitTestCase {
// never removed). Split this into 30-character chunks, so we don't run
// into limits of truncation.
$start = 0;
- while ($start < Unicode::strlen($string)) {
- $newstr = Unicode::substr($string, $start, 30);
+ while ($start < mb_strlen($string)) {
+ $newstr = mb_substr($string, $start, 30);
// Special case: leading zeros are removed from numeric strings,
// and there's one string in this file that is numbers starting with
// zero, so prepend a 1 on that string.
@@ -313,7 +312,7 @@ class TokenizerTest extends UnitTestCase {
}
foreach ($strings as $key => $string) {
$simplified = $this->invokeMethod('simplifyText', [$string]);
- $this->assertGreaterThanOrEqual(Unicode::strlen($string), Unicode::strlen($simplified), "Nothing is removed from string $key.");
+ $this->assertGreaterThanOrEqual(mb_strlen($string), mb_strlen($simplified), "Nothing is removed from string $key.");
}
// Test the low-numbered ASCII control characters separately. They are not
diff --git a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TransliterationTest.php b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TransliterationTest.php
index 63bcbaaa1..44da8a814 100644
--- a/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TransliterationTest.php
+++ b/sites/all/modules/contrib/search/search_api/tests/src/Unit/Processor/TransliterationTest.php
@@ -2,6 +2,8 @@
namespace Drupal\Tests\search_api\Unit\Processor;
+use Drupal\Component\Transliteration\TransliterationInterface;
+use Drupal\search_api\IndexInterface;
use Drupal\search_api\Plugin\search_api\processor\Transliteration;
use Drupal\Tests\UnitTestCase;
@@ -29,13 +31,13 @@ class TransliterationTest extends UnitTestCase {
public function setUp() {
parent::setUp();
- $this->index = $this->getMock('Drupal\search_api\IndexInterface');
+ $this->index = $this->createMock(IndexInterface::class);
$this->setUpMockContainer();
$this->processor = new Transliteration([], 'transliteration', []);
$this->processor->setLangcode('en');
- $transliterator = $this->getMock('\Drupal\Component\Transliteration\TransliterationInterface');
+ $transliterator = $this->createMock(TransliterationInterface::class);
$transliterate = function ($string, $langcode = 'en', $unknown_character = '?', $max_length = NULL) {
return "translit-$string-$langcode$unknown_character$max_length";
};
diff --git a/sites/default/config/sync/pathauto.settings.yml b/sites/default/config/sync/pathauto.settings.yml
index 3cfdb999b..c8bdadbbe 100644
--- a/sites/default/config/sync/pathauto.settings.yml
+++ b/sites/default/config/sync/pathauto.settings.yml
@@ -45,3 +45,11 @@ update_action: 2
_core:
default_config_hash: GcMSgi6uAfG5R_FGEsWUVCvRPkNIzPUH2bNVcx6H0JA
langcode: fr
+safe_tokens:
+ - alias
+ - alias
+ - path
+ - join-path
+ - login-url
+ - url
+ - url-brief
diff --git a/sites/default/config/sync/search_api.server.edlp_db.yml b/sites/default/config/sync/search_api.server.edlp_db.yml
index 0e87a5fab..6ea4fff6e 100644
--- a/sites/default/config/sync/search_api.server.edlp_db.yml
+++ b/sites/default/config/sync/search_api.server.edlp_db.yml
@@ -11,7 +11,7 @@ backend: search_api_db
backend_config:
database: 'default:default'
min_chars: 3
- partial_matches: true
autocomplete:
suggest_suffix: true
suggest_words: true
+ matching: partial