{% if facet.widget.type %}
{%- set attributes = attributes.addClass('item-list__' ~ facet.widget.type) %}
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_custom_widget/facets_custom_widget.info.yml b/frontend/drupal9/web/modules/contrib/facets/tests/facets_custom_widget/facets_custom_widget.info.yml
index 866ad784a..95b915ffa 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/facets_custom_widget/facets_custom_widget.info.yml
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_custom_widget/facets_custom_widget.info.yml
@@ -5,7 +5,7 @@ package: 'Testing'
hidden: true
core_version_requirement: ^9.2 || ^10.0
-# Information added by Drupal.org packaging script on 2022-04-04
-version: '2.0.2'
+# Information added by Drupal.org packaging script on 2022-07-09
+version: '2.0.4'
project: 'facets'
-datestamp: 1649070272
+datestamp: 1657367472
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_events_test/facets_events_test.info.yml b/frontend/drupal9/web/modules/contrib/facets/tests/facets_events_test/facets_events_test.info.yml
index ae76c68d5..84cf57401 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/facets_events_test/facets_events_test.info.yml
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_events_test/facets_events_test.info.yml
@@ -5,7 +5,7 @@ package: 'Testing'
hidden: true
core_version_requirement: ^9.2 || ^10.0
-# Information added by Drupal.org packaging script on 2022-04-04
-version: '2.0.2'
+# Information added by Drupal.org packaging script on 2022-07-09
+version: '2.0.4'
project: 'facets'
-datestamp: 1649070272
+datestamp: 1657367472
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/facets_processors_collection.info.yml b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/facets_processors_collection.info.yml
new file mode 100644
index 000000000..0b5b986ae
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/facets_processors_collection.info.yml
@@ -0,0 +1,13 @@
+name: 'Facets processors collection'
+type: module
+description: 'Contains collection of test facet processors'
+package: 'Testing'
+hidden: true
+core_version_requirement: ^9.2 || ^10.0
+dependencies:
+ - facets:facets
+
+# Information added by Drupal.org packaging script on 2022-07-09
+version: '2.0.4'
+project: 'facets'
+datestamp: 1657367472
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/facets_processors_collection.module b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/facets_processors_collection.module
new file mode 100644
index 000000000..0861b625f
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/facets_processors_collection.module
@@ -0,0 +1,19 @@
+get('facets_processors_collection_alter_string_query_handler', FALSE)
+ ) {
+ $query_types['string'] = 'search_api_string_cached';
+ }
+}
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/facets_processors_collection.services.yml b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/facets_processors_collection.services.yml
new file mode 100644
index 000000000..4e9e133cd
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/facets_processors_collection.services.yml
@@ -0,0 +1,28 @@
+services:
+ cache_context.fpc_build:
+ class: Drupal\facets_processors_collection\Cache\FpcCacheContext
+ argumets:
+ type: build
+ tags:
+ - { name: cache.context }
+
+ cache_context.fpc_sort:
+ class: Drupal\facets_processors_collection\Cache\FpcCacheContext
+ argumets:
+ type: sort
+ tags:
+ - { name: cache.context }
+
+ cache_context.fpc_post_query:
+ class: Drupal\facets_processors_collection\Cache\FpcCacheContext
+ argumets:
+ type: post_query
+ tags:
+ - { name: cache.context }
+
+ cache_context.fpc_query_type_plugin:
+ class: Drupal\facets_processors_collection\Cache\FpcCacheContext
+ argumets:
+ type: query_type_plugin
+ tags:
+ - { name: cache.context }
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Cache/FpcCacheContext.php b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Cache/FpcCacheContext.php
new file mode 100644
index 000000000..00760033f
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Cache/FpcCacheContext.php
@@ -0,0 +1,86 @@
+type = $type;
+ }
+
+ /**
+ * Get all allowed context types.
+ *
+ * @return array
+ * Array of context types: all processor stages + query_type plugin.
+ */
+ protected static function getAllowedTypes() {
+ return array_merge(static::$processorStages, [static::QUERY_PLUGIN]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getLabel() {
+ return t(
+ 'FPC: cache context, cab be one of the following: %stages.',
+ ['%stages' => implode(', ', static::getAllowedTypes())]
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getContext() {
+ return 'fpc_' . $this->type;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheableMetadata() {
+ return new CacheableMetadata();
+ }
+
+}
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/processor/FpcBuildProcessor.php b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/processor/FpcBuildProcessor.php
new file mode 100644
index 000000000..dca3dad97
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/processor/FpcBuildProcessor.php
@@ -0,0 +1,59 @@
+setDisplayValue('Test ' . $result->getDisplayValue());
+ }
+ // An example cache tag that can be added from the ::build().
+ $facet->addCacheTags(['fpc:added_within_build_method']);
+
+ return $results;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheTags() {
+ return Cache::mergeTags(parent::getCacheTags(), ['fpc:build_processor']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheContexts() {
+ return Cache::mergeContexts(parent::getCacheContexts(), ['fpc_build']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheMaxAge() {
+ return Cache::PERMANENT;
+ }
+
+}
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/processor/FpcPostQueryProcessor.php b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/processor/FpcPostQueryProcessor.php
new file mode 100644
index 000000000..6fe8a4610
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/processor/FpcPostQueryProcessor.php
@@ -0,0 +1,52 @@
+addCacheTags(['fpc:added_within_postQuery_method']);
+ }
+
+}
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/processor/FpcSortProcessor.php b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/processor/FpcSortProcessor.php
new file mode 100644
index 000000000..c2d2038b5
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/processor/FpcSortProcessor.php
@@ -0,0 +1,60 @@
+disables cache"),
+ * stages = {
+ * "sort" = 50
+ * }
+ * )
+ */
+class FpcSortRandomProcessor extends FpcSortProcessor {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function sortResults(Result $a, Result $b) {
+ return random_int(-1, 1);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheMaxAge() {
+ // As sorting should be random, we can't cache results.
+ return 0;
+ }
+
+}
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/query_type/CacheableQueryTypePlugin.php b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/query_type/CacheableQueryTypePlugin.php
new file mode 100644
index 000000000..bb1d38bc9
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_processors_collection/src/Plugin/facets/query_type/CacheableQueryTypePlugin.php
@@ -0,0 +1,27 @@
+query->addCacheTags(['fpc:query_plugin_type_plugin']);
+ $this->query->addCacheContexts(['fpc_query_type_plugin']);
+ }
+
+}
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_query_processor/facets_query_processor.info.yml b/frontend/drupal9/web/modules/contrib/facets/tests/facets_query_processor/facets_query_processor.info.yml
index 901b23d36..6eeb1cc76 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/facets_query_processor/facets_query_processor.info.yml
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_query_processor/facets_query_processor.info.yml
@@ -5,7 +5,7 @@ package: 'Testing'
hidden: true
core_version_requirement: ^9.2 || ^10.0
-# Information added by Drupal.org packaging script on 2022-04-04
-version: '2.0.2'
+# Information added by Drupal.org packaging script on 2022-07-09
+version: '2.0.4'
project: 'facets'
-datestamp: 1649070272
+datestamp: 1657367472
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_query_processor/facets_query_processor.services.yml b/frontend/drupal9/web/modules/contrib/facets/tests/facets_query_processor/facets_query_processor.services.yml
new file mode 100644
index 000000000..5163aeb58
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_query_processor/facets_query_processor.services.yml
@@ -0,0 +1,14 @@
+services:
+ cache_context.dummy_query_build:
+ class: Drupal\facets_query_processor\Cache\DummyQuery
+ argumets:
+ type: build
+ tags:
+ - { name: cache.context }
+
+ cache_context.dummy_query_pre_query:
+ class: Drupal\facets_query_processor\Cache\DummyQuery
+ argumets:
+ type: pre_query
+ tags:
+ - { name: cache.context }
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_query_processor/src/Plugin/facets/url_processor/DummyQuery.php b/frontend/drupal9/web/modules/contrib/facets/tests/facets_query_processor/src/Plugin/facets/url_processor/DummyQuery.php
index 9bb268ba7..105f571f7 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/facets_query_processor/src/Plugin/facets/url_processor/DummyQuery.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_query_processor/src/Plugin/facets/url_processor/DummyQuery.php
@@ -2,8 +2,11 @@
namespace Drupal\facets_query_processor\Plugin\facets\url_processor;
+use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\facets\FacetInterface;
use Drupal\facets\Plugin\facets\url_processor\QueryString;
+use Drupal\facets\Utility\FacetsUrlGenerator;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -21,10 +24,33 @@ class DummyQuery extends QueryString {
/**
* {@inheritdoc}
*/
- public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $eventDispatcher) {
+ public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $eventDispatcher, FacetsUrlGenerator $urlGenerator) {
// Override the default separator.
$configuration['separator'] = '||';
- parent::__construct($configuration, $plugin_id, $plugin_definition, $request, $entity_type_manager, $eventDispatcher);
+ parent::__construct($configuration, $plugin_id, $plugin_definition, $request, $entity_type_manager, $eventDispatcher, $urlGenerator);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildUrls(FacetInterface $facet, array $results) {
+ $facet->addCacheTags(['dummy_query_build_urls_tag']);
+ $facet->addCacheContexts(['dummy_query_build']);
+ return parent::buildUrls($facet, $results);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheTags() {
+ return Cache::mergeTags(parent::getCacheTags(), ['dummy_query_pre_query_tag']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheContexts() {
+ return Cache::mergeContexts(parent::getCacheContexts(), ['dummy_query_pre_query']);
}
}
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_search_api_dependency/config/install/views.view.search_api_test_view.yml b/frontend/drupal9/web/modules/contrib/facets/tests/facets_search_api_dependency/config/install/views.view.search_api_test_view.yml
index d13feac71..0b617b038 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/facets_search_api_dependency/config/install/views.view.search_api_test_view.yml
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_search_api_dependency/config/install/views.view.search_api_test_view.yml
@@ -1,76 +1,34 @@
-base_field: search_api_id
-base_table: search_api_index_database_search_index
-core: 8.x
-description: ''
+langcode: en
status: true
+dependencies:
+ config:
+ - search_api.index.database_search_index
+ module:
+ - search_api
+id: search_api_test_view
+label: 'Search API Test Fulltext search view'
+module: views
+description: ''
+tag: ''
+base_table: search_api_index_database_search_index
+base_field: search_api_id
display:
default:
- display_plugin: default
id: default
display_title: Master
+ display_plugin: default
position: 0
display_options:
- access:
- type: none
- options: { }
- cache:
- type: none
- options: { }
- query:
- type: search_api_query
- options:
- skip_access: true
- exposed_form:
- type: basic
- options:
- submit_button: Search
- 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: full
- options:
- items_per_page: 10
- offset: 0
- id: 0
- total_pages: null
- expose:
- items_per_page: false
- items_per_page_label: 'Items per page'
- items_per_page_options: '5, 10, 20, 40, 60'
- items_per_page_options_all: false
- items_per_page_options_all_label: '- All -'
- offset: false
- offset_label: Offset
- tags:
- previous: '‹ previous'
- next: 'next ›'
- first: '« first'
- last: 'last »'
- quantity: 9
- style:
- type: default
- row:
- type: search_api
- options:
- view_modes:
- bundle:
- 'article': default
- 'page': default
- datasource:
- 'entity:entity_test': default
+ title: 'Fulltext test index'
fields:
search_api_id:
+ id: search_api_id
table: search_api_index_database_search_index
field: search_api_id
- id: search_api_id
- plugin_id: numeric
relationship: none
group_type: group
admin_label: ''
+ plugin_id: numeric
label: 'Entity ID'
exclude: false
alter:
@@ -117,9 +75,81 @@ display:
decimal: .
separator: ','
format_plural: false
- format_plural_string: "1\x03@count"
+ format_plural_string: !!binary MQNAY291bnQ=
prefix: ''
suffix: ''
+ pager:
+ type: full
+ options:
+ offset: 0
+ items_per_page: 10
+ total_pages: null
+ id: 0
+ tags:
+ next: 'next ›'
+ previous: '‹ previous'
+ first: '« first'
+ last: 'last »'
+ expose:
+ items_per_page: false
+ items_per_page_label: 'Items per page'
+ items_per_page_options: '5, 10, 20, 40, 60'
+ items_per_page_options_all: false
+ items_per_page_options_all_label: '- All -'
+ offset: false
+ offset_label: Offset
+ quantity: 9
+ exposed_form:
+ type: basic
+ options:
+ submit_button: Search
+ reset_button: false
+ reset_button_label: Reset
+ exposed_sorts_label: 'Sort by'
+ expose_sort_order: true
+ sort_asc_label: Asc
+ sort_desc_label: Desc
+ access:
+ type: none
+ options: { }
+ cache:
+ type: none
+ options: { }
+ empty: { }
+ sorts:
+ search_api_id:
+ id: search_api_id
+ table: search_api_index_database_search_index
+ field: search_api_id
+ relationship: none
+ group_type: group
+ admin_label: ''
+ plugin_id: search_api
+ order: ASC
+ expose:
+ label: ''
+ field_identifier: search_api_id
+ exposed: false
+ arguments:
+ search_api_datasource:
+ id: search_api_datasource
+ table: search_api_index_database_search_index
+ field: search_api_datasource
+ plugin_id: search_api
+ break_phrase: true
+ type:
+ id: type
+ table: search_api_index_database_search_index
+ field: type
+ plugin_id: search_api
+ break_phrase: false
+ not: true
+ keywords:
+ id: keywords
+ table: search_api_index_database_search_index
+ field: keywords
+ plugin_id: search_api
+ break_phrase: true
filters:
search_api_fulltext:
id: search_api_fulltext
@@ -128,6 +158,7 @@ display:
relationship: none
group_type: group
admin_label: ''
+ plugin_id: search_api_fulltext
operator: and
value: ''
group: 1
@@ -138,6 +169,8 @@ display:
description: ''
use_operator: true
operator: search_api_fulltext_op
+ operator_limit_selection: false
+ operator_list: { }
identifier: search_api_fulltext
required: false
remember: false
@@ -160,14 +193,13 @@ display:
group_items: { }
min_length: 3
fields: { }
- plugin_id: search_api_fulltext
id:
- plugin_id: search_api_numeric
id: id
table: search_api_index_database_search_index
field: id
relationship: none
admin_label: ''
+ plugin_id: search_api_numeric
operator: '='
group: 1
exposed: true
@@ -177,6 +209,8 @@ display:
description: ''
use_operator: true
operator: id_op
+ operator_limit_selection: false
+ operator_list: { }
identifier: id
required: false
remember: false
@@ -187,12 +221,12 @@ display:
administrator: '0'
is_grouped: false
created:
- plugin_id: search_api_date
id: created
table: search_api_index_database_search_index
field: created
relationship: none
admin_label: ''
+ plugin_id: search_api_date
operator: '='
group: 1
exposed: true
@@ -202,6 +236,8 @@ display:
description: ''
use_operator: true
operator: created_op
+ operator_limit_selection: false
+ operator_list: { }
identifier: created
required: false
remember: false
@@ -212,12 +248,12 @@ display:
administrator: '0'
is_grouped: false
keywords:
- plugin_id: search_api_string
id: keywords
table: search_api_index_database_search_index
field: keywords
relationship: none
admin_label: ''
+ plugin_id: search_api_string
operator: '='
group: 1
exposed: true
@@ -227,6 +263,8 @@ display:
description: ''
use_operator: true
operator: keywords_op
+ operator_limit_selection: false
+ operator_list: { }
identifier: keywords
required: false
remember: false
@@ -237,13 +275,13 @@ display:
administrator: '0'
is_grouped: false
search_api_language:
- plugin_id: search_api_language
id: search_api_language
table: search_api_index_database_search_index
field: search_api_language
relationship: none
admin_label: ''
- operator: 'in'
+ plugin_id: search_api_language
+ operator: in
group: 1
exposed: true
expose:
@@ -252,6 +290,8 @@ display:
description: ''
use_operator: true
operator: language_op
+ operator_limit_selection: false
+ operator_list: { }
identifier: language
required: false
remember: false
@@ -261,20 +301,22 @@ display:
anonymous: '0'
administrator: '0'
is_grouped: false
- sorts:
- search_api_id:
- id: search_api_id
- table: search_api_index_database_search_index
- field: search_api_id
- relationship: none
- group_type: group
- admin_label: ''
- order: ASC
- exposed: false
- expose:
- label: ''
- plugin_id: search_api
- title: 'Fulltext test index'
+ style:
+ type: default
+ row:
+ type: search_api
+ options:
+ view_modes:
+ bundle:
+ article: default
+ page: default
+ datasource:
+ 'entity:entity_test': default
+ query:
+ type: search_api_query
+ options:
+ skip_access: true
+ relationships: { }
header:
result:
id: result
@@ -283,54 +325,117 @@ display:
relationship: none
group_type: group
admin_label: ''
- content: 'Displaying @total search results'
plugin_id: result
+ content: 'Displaying @total search results'
footer: { }
- empty: { }
- relationships: { }
- arguments:
- search_api_datasource:
- plugin_id: search_api
- id: search_api_datasource
- table: search_api_index_database_search_index
- field: search_api_datasource
- break_phrase: true
- type:
- plugin_id: search_api
- id: type
- table: search_api_index_database_search_index
- field: type
- break_phrase: false
- not: true
- keywords:
- plugin_id: search_api
- id: keywords
- table: search_api_index_database_search_index
- field: keywords
- break_phrase: true
- page_1:
- display_plugin: page
- id: page_1
- display_title: Page
- position: 1
- display_options:
- path: search-api-test-fulltext
+ display_extenders: { }
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_interface'
+ - url
+ - url.query_args
+ tags:
+ - 'config:search_api.index.database_search_index'
block_1:
- display_plugin: block
id: block_1
display_title: Block
- position: 2
+ display_plugin: block
+ position: 3
display_options:
- display_extenders: { }
defaults:
use_ajax: false
use_ajax: true
-label: 'Search API Test Fulltext search view'
-module: views
-id: search_api_test_view
-tag: ''
-langcode: en
-dependencies:
- module:
- - search_api
- - facets_search_api_dependency
+ display_extenders: { }
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_interface'
+ - url
+ - url.query_args
+ tags:
+ - 'config:search_api.index.database_search_index'
+ block_1_sapi_tag:
+ id: block_1_sapi_tag
+ display_title: 'Block Search API cache tag'
+ display_plugin: block
+ position: 4
+ display_options:
+ cache:
+ type: search_api_tag
+ options: { }
+ defaults:
+ cache: false
+ use_ajax: false
+ use_ajax: true
+ display_extenders: { }
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_interface'
+ - url
+ - url.query_args
+ tags:
+ - 'config:search_api.index.database_search_index'
+ page_1:
+ id: page_1
+ display_title: Page
+ display_plugin: page
+ position: 1
+ display_options:
+ display_extenders: { }
+ path: search-api-test-fulltext
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_interface'
+ - url
+ - url.query_args
+ tags:
+ - 'config:search_api.index.database_search_index'
+ page_2_sapi_tag:
+ id: page_2_sapi_tag
+ display_title: 'Page Search API cache tag'
+ display_plugin: page
+ position: 2
+ display_options:
+ cache:
+ type: search_api_tag
+ options: { }
+ defaults:
+ cache: false
+ display_extenders: { }
+ path: search-api-test-fulltext-cache-tag
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_interface'
+ - url
+ - url.query_args
+ tags:
+ - 'config:search_api.index.database_search_index'
+ page_2_sapi_time:
+ id: page_2_sapi_time
+ display_title: 'Page Search API cache time'
+ display_plugin: page
+ position: 2
+ display_options:
+ cache:
+ type: search_api_time
+ options:
+ results_lifespan: 21600
+ results_lifespan_custom: 0
+ output_lifespan: 518400
+ output_lifespan_custom: 0
+ defaults:
+ cache: false
+ display_extenders: { }
+ path: search-api-test-fulltext-cache-time
+ cache_metadata:
+ max-age: -1
+ contexts:
+ - 'languages:language_interface'
+ - url
+ - url.query_args
+ tags:
+ - 'config:search_api.index.database_search_index'
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/facets_search_api_dependency/facets_search_api_dependency.info.yml b/frontend/drupal9/web/modules/contrib/facets/tests/facets_search_api_dependency/facets_search_api_dependency.info.yml
index 581616aef..57efe0587 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/facets_search_api_dependency/facets_search_api_dependency.info.yml
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/facets_search_api_dependency/facets_search_api_dependency.info.yml
@@ -9,7 +9,7 @@ dependencies:
- drupal:views
core_version_requirement: ^9.2 || ^10.0
-# Information added by Drupal.org packaging script on 2022-04-04
-version: '2.0.2'
+# Information added by Drupal.org packaging script on 2022-07-09
+version: '2.0.4'
project: 'facets'
-datestamp: 1649070272
+datestamp: 1657367472
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/BlockTestTrait.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/BlockTestTrait.php
index 748b8e2bd..49432a587 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/BlockTestTrait.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/BlockTestTrait.php
@@ -85,9 +85,7 @@ trait BlockTestTrait {
* The id of the block.
*/
protected function deleteBlock($id) {
- // Delete a facet block through the UI, the text for the success message has
- // changed in Drupal::VERSION 9.3.
- $orig_success_message = 'The block ' . $this->blocks[$id]->label() . ' has been removed' . (\Drupal::VERSION >= 9.3 ? ' from the Footer region' : '') . '.';
+ $orig_success_message = 'The block ' . $this->blocks[$id]->label() . ' has been removed from the Footer region.';
$this->drupalGet('admin/structure/block/manage/' . $this->blocks[$id]->id(), ['query' => ['destination' => 'admin']]);
$this->clickLink('Remove block');
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/BreadcrumbIntegrationTest.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/BreadcrumbIntegrationTest.php
index 7aa9b48b0..47d29c702 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/BreadcrumbIntegrationTest.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/BreadcrumbIntegrationTest.php
@@ -121,7 +121,7 @@ class BreadcrumbIntegrationTest extends FacetsTestBase {
*/
protected function editFacetConfig(array $config = []) {
$this->drupalGet('admin/config/search/facets');
- $this->clickLink('Configure', 1);
+ $this->clickLink('Configure', 2);
$default_config = [
'filter_key' => 'f',
'url_processor' => 'query_string',
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/HierarchicalFacetIntegrationTest.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/HierarchicalFacetIntegrationTest.php
index a3052cd39..19536b6e2 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/HierarchicalFacetIntegrationTest.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/HierarchicalFacetIntegrationTest.php
@@ -383,7 +383,7 @@ class HierarchicalFacetIntegrationTest extends FacetsTestBase {
*/
public function testHierarchyBreadcrumb() {
$this->drupalGet('admin/config/search/facets');
- $this->clickLink('Configure', 1);
+ $this->clickLink('Configure', 2);
$default_config = [
'filter_key' => 'f',
'url_processor' => 'query_string',
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/IntegrationCacheTest.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/IntegrationCacheTest.php
new file mode 100644
index 000000000..24674c446
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/IntegrationCacheTest.php
@@ -0,0 +1,741 @@
+enableWebsiteCache();
+ $this->setUpExampleStructure();
+ $this->insertExampleContent();
+ $this->assertEquals(5, $this->indexItems($this->indexId), '5 items were indexed.');
+
+ $this->facetStorage = $this->container->get('entity_type.manager')
+ ->getStorage('facets_facet');
+ $this->entityTestStorage = \Drupal::entityTypeManager()
+ ->getStorage('entity_test_mulrev_changed');
+ }
+
+ /**
+ * Tests various operations via the Facets' admin UI.
+ *
+ * Cached implementation of testBlockView integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testBlockView()
+ */
+ public function testFramework() {
+ $facet_id = 'test_facet_name';
+ $this->drupalGet(static::VIEW_URL);
+ // By default, the view should show all entities.
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+
+ $this->createFacet('Test Facet name', $facet_id, 'type', static::VIEW_DISPLAY);
+
+ // Verify that the facet results are correct.
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('item');
+ $this->assertSession()->pageTextContains('article');
+
+ // Verify that facet blocks appear as expected.
+ $this->assertFacetBlocksAppear();
+
+ // Verify that the facet only shows when the facet source is visible, it
+ // should not show up on the user page.
+ $this->drupalGet('
');
+ $this->assertNoFacetBlocksAppear();
+
+ // Do not show the block on empty behaviors.
+ $this->clearIndex();
+ $this->drupalGet(static::VIEW_URL);
+
+ // Verify that no facet blocks appear. Empty behavior "None" is selected by
+ // default.
+ $this->assertNoFacetBlocksAppear();
+
+ // Verify that the "empty_text" appears as expected.
+ $settings = [
+ 'behavior' => 'text',
+ 'text' => 'No results found for this block!',
+ 'text_format' => 'plain_text',
+ ];
+ $facet = $this->getFacetById($facet_id);
+ $facet->setEmptyBehavior($settings);
+ $this->facetStorage->save($facet);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->responseContains('block-test-facet-name');
+ $this->assertSession()->responseContains('No results found for this block!');
+ }
+
+ /**
+ * Tests that a block view also works.
+ *
+ * Cached implementation of testBlockView integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testBlockView()
+ */
+ public function testBlockView() {
+ $webAssert = $this->assertSession();
+ $this->createFacet(
+ 'Block view facet',
+ 'block_view_facet',
+ 'type',
+ 'block_1_sapi_tag',
+ 'views_block__search_api_test_view'
+ );
+
+ // Place the views block in the footer of all pages.
+ $block_settings = [
+ 'region' => 'sidebar_first',
+ 'id' => 'view_block',
+ ];
+ $this->drupalPlaceBlock('views_block:search_api_test_view-block_1_sapi_tag', $block_settings);
+
+ // By default, the view should show all entities.
+ $this->drupalGet('');
+ $webAssert->pageTextContains('Fulltext test index');
+ $webAssert->pageTextContains('Displaying 5 search results');
+ $webAssert->pageTextContains('item');
+ $webAssert->pageTextContains('article');
+
+ // Click the item link, and test that filtering of results actually works.
+ $this->clickLink('item');
+ $webAssert->pageTextContains('Displaying 3 search results');
+ }
+
+ /**
+ * Tests that an url alias works correctly.
+ *
+ * Cached implementation of testUrlAlias integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testUrlAlias()
+ */
+ public function testUrlAlias() {
+ $facet_id = 'ab_facet';
+ $this->createFacet('ab Facet', $facet_id, 'type', static::VIEW_DISPLAY);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertFacetLabel('item');
+ $this->assertFacetLabel('article');
+
+ $this->clickLink('item');
+ $url = Url::fromUserInput('/' . static::VIEW_URL, ['query' => ['f' => ['ab_facet:item']]]);
+ $this->assertSession()->addressEquals($url);
+
+ $this->updateFacet($facet_id, ['url_alias' => 'llama']);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertFacetLabel('item');
+ $this->assertFacetLabel('article');
+
+ $this->clickLink('item');
+ $url = Url::fromUserInput('/' . static::VIEW_URL, ['query' => ['f' => ['llama:item']]]);
+ $this->assertSession()->addressEquals($url);
+ }
+
+ /**
+ * Tests facet dependencies.
+ *
+ * Cached implementation of testFacetDependencies integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testFacetDependencies()
+ */
+ public function testFacetDependencies() {
+ $facet_name = "DependableFacet";
+ $facet_id = 'dependablefacet';
+
+ $depending_facet_name = "DependingFacet";
+ $depending_facet_id = "dependingfacet";
+
+ $this->createFacet($facet_name, $facet_id, 'type', static::VIEW_DISPLAY);
+ $this->createFacet($depending_facet_name, $depending_facet_id, 'keywords', static::VIEW_DISPLAY);
+
+ // Go to the view and test that both facets are shown. Item and article
+ // come from the DependableFacet, orange and grape come from DependingFacet.
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertFacetLabel('grape');
+ $this->assertFacetLabel('orange');
+ $this->assertFacetLabel('item');
+ $this->assertFacetLabel('article');
+ $this->assertFacetBlocksAppear();
+
+ // Change the visiblity settings of the DependingFacet.
+ $facet = $this->getFacetById($depending_facet_id);
+ $processor = [
+ 'processor_id' => 'dependent_processor',
+ 'weights' => ['build' => 5],
+ 'settings' => [
+ $facet_id => [
+ 'enable' => TRUE,
+ 'condition' => 'values',
+ 'values' => 'item',
+ 'negate' => FALSE,
+ ],
+ ],
+ ];
+ $facet->addProcessor($processor);
+ $this->facetStorage->save($facet);
+
+ // Go to the view and test that only the types are shown.
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->linkNotExists('grape');
+ $this->assertSession()->linkNotExists('orange');
+ $this->assertFacetLabel('item');
+ $this->assertFacetLabel('article');
+
+ // Click on the item, and test that this shows the keywords.
+ $this->clickLink('item');
+ $this->assertFacetLabel('grape');
+ $this->assertFacetLabel('orange');
+
+ // Go back to the view, click on article and test that the keywords are
+ // hidden.
+ $this->drupalGet(static::VIEW_URL);
+ $this->clickLink('article');
+ $this->assertSession()->linkNotExists('grape');
+ $this->assertSession()->linkNotExists('orange');
+
+ // Change the visibility settings to negate the previous settings.
+ $processor['settings'][$facet_id]['negate'] = TRUE;
+ $facet->addProcessor($processor);
+ $this->facetStorage->save($facet);
+
+ // Go to the view and test only the type facet is shown.
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertFacetLabel('item');
+ $this->assertFacetLabel('article');
+ $this->assertFacetLabel('grape');
+ $this->assertFacetLabel('orange');
+
+ // Click on the article, and test that this shows the keywords.
+ $this->clickLink('article');
+ $this->assertFacetLabel('grape');
+ $this->assertFacetLabel('orange');
+
+ // Go back to the view, click on item and test that the keywords are
+ // hidden.
+ $this->drupalGet(static::VIEW_URL);
+ $this->clickLink('item');
+ $this->assertSession()->linkNotExists('grape');
+ $this->assertSession()->linkNotExists('orange');
+
+ // Disable negation again.
+ $processor['settings'][$facet_id]['negate'] = FALSE;
+ $facet->addProcessor($processor);
+ $this->facetStorage->save($facet);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+ $this->assertSession()->linkNotExists('grape');
+ $this->clickLink('item');
+ $this->assertSession()->pageTextContains('Displaying 3 search results');
+ $this->assertSession()->linkExists('grape');
+ $this->clickLink('grape');
+ $this->assertSession()->pageTextContains('Displaying 1 search results');
+ // Disable item again, and the grape should not be reflected in the search
+ // result anymore.
+ $this->clickLink('item');
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+ }
+
+ /**
+ * Tests the facet's and/or functionality.
+ *
+ * Cached implementation of testAndOrFacet integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testAndOrFacet()
+ */
+ public function testAndOrFacet() {
+ $facet_id = 'test_facet';
+
+ $this->createFacet('test & facet', $facet_id, 'type', static::VIEW_DISPLAY);
+ $this->updateFacet($facet_id, ['query_operator' => 'and']);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertFacetLabel('item');
+ $this->assertFacetLabel('article');
+
+ $this->clickLink('item');
+ $this->checkFacetIsActive('item');
+ $this->assertSession()->linkNotExists('article');
+
+ $this->updateFacet($facet_id, ['query_operator' => 'or']);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertFacetLabel('item');
+ $this->assertFacetLabel('article');
+
+ $this->clickLink('item (3)');
+ $this->checkFacetIsActive('item');
+ $this->assertFacetLabel('article (2)');
+ }
+
+ /**
+ * Tests the facet's exclude functionality.
+ *
+ * Cached implementation of testExcludeFacet integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testExcludeFacet()
+ */
+ public function testExcludeFacet() {
+ $facet_id = 'test_facet';
+ $this->createFacet('test & facet', $facet_id, 'type', static::VIEW_DISPLAY);
+ $this->updateFacet($facet_id, ['exclude' => TRUE]);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('foo bar baz');
+ $this->assertSession()->pageTextContains('foo baz');
+ $this->assertFacetLabel('item');
+
+ $this->clickLink('item');
+ $this->checkFacetIsActive('item');
+ $this->assertSession()->pageTextContains('foo baz');
+ $this->assertSession()->pageTextContains('bar baz');
+ $this->assertSession()->pageTextNotContains('foo bar baz');
+
+ $this->updateFacet($facet_id, ['exclude' => FALSE]);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('foo bar baz');
+ $this->assertSession()->pageTextContains('foo baz');
+ $this->assertFacetLabel('item');
+
+ $this->clickLink('item');
+ $this->checkFacetIsActive('item');
+ $this->assertSession()->pageTextContains('foo bar baz');
+ $this->assertSession()->pageTextContains('foo test');
+ $this->assertSession()->pageTextContains('bar');
+ $this->assertSession()->pageTextNotContains('foo baz');
+ }
+
+ /**
+ * Tests the facet's exclude functionality for a date field.
+ *
+ * Cached implementation of testExcludeFacetDate integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testExcludeFacetDate()
+ */
+ public function testExcludeFacetDate() {
+ $facet_id = $field_name = 'created';
+
+ $this->entityTestStorage->create([
+ 'name' => 'foo new',
+ 'body' => 'test test',
+ 'type' => 'item',
+ 'keywords' => ['orange'],
+ 'category' => 'item_category',
+ $field_name => 1490000000,
+ ])->save();
+
+ $this->entityTestStorage->create([
+ 'name' => 'foo old',
+ 'body' => 'test test',
+ 'type' => 'item',
+ 'keywords' => ['orange'],
+ 'category' => 'item_category',
+ $field_name => 1460000000,
+ ])->save();
+
+ $this->assertEquals(2, $this->indexItems($this->indexId), '2 items were indexed.');
+
+ $this->createFacet('Created', $facet_id, $field_name, static::VIEW_DISPLAY);
+ $facet = $this->getFacetById($facet_id);
+ $facet->addProcessor([
+ 'processor_id' => 'date_item',
+ 'weights' => ['build' => 35],
+ 'settings' => [
+ 'date_display' => 'actual_date',
+ 'granularity' => SearchApiDate::FACETAPI_DATE_MONTH,
+ 'hierarchy' => FALSE,
+ 'date_format' => '',
+ ],
+ ]);
+ $this->facetStorage->save($facet);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('foo old');
+ $this->assertSession()->pageTextContains('foo new');
+ $this->clickLink('March 2017');
+ $this->checkFacetIsActive('March 2017');
+ $this->assertSession()->pageTextContains('foo new');
+ $this->assertSession()->pageTextNotContains('foo old');
+
+ $this->updateFacet($facet->id(), ['exclude' => TRUE]);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->clickLink('March 2017');
+ $this->checkFacetIsActive('March 2017');
+ $this->assertSession()->pageTextContains('foo old');
+ $this->assertSession()->pageTextNotContains('foo new');
+ }
+
+ /**
+ * Tests allow only one active item.
+ *
+ * Cached implementation of testAllowOneActiveItem integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testAllowOneActiveItem()
+ */
+ public function testAllowOneActiveItem() {
+ $this->createFacet('Spotted wood owl', 'spotted_wood_owl', 'keywords', static::VIEW_DISPLAY);
+
+ $facet = $this->getFacetById('spotted_wood_owl');
+ $facet->setShowOnlyOneResult(TRUE);
+ $this->facetStorage->save($facet);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+ $this->assertFacetLabel('grape');
+ $this->assertFacetLabel('orange');
+
+ $this->clickLink('grape');
+ $this->assertSession()->pageTextContains('Displaying 3 search results');
+ $this->checkFacetIsActive('grape');
+ $this->assertFacetLabel('orange');
+
+ $this->clickLink('orange');
+ $this->assertSession()->pageTextContains('Displaying 3 search results');
+ $this->assertFacetLabel('grape');
+ $this->checkFacetIsActive('orange');
+ }
+
+ /**
+ * Tests calculations of facet count.
+ *
+ * Cached implementation of testFacetCountCalculations integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testFacetCountCalculations()
+ */
+ public function testFacetCountCalculations() {
+ $this->createFacet('Type', 'type', 'type', static::VIEW_DISPLAY);
+ $this->createFacet('Keywords', 'keywords', 'keywords', static::VIEW_DISPLAY);
+ foreach (['type', 'keywords'] as $facet_id) {
+ $this->updateFacet($facet_id, ['query_operator' => 'and']);
+ }
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+ $this->assertFacetLabel('article (2)');
+ $this->assertFacetLabel('grape (3)');
+
+ // Make sure that after clicking on article, which has only 2 entities,
+ // there are only 2 items left in the results for other facets as well.
+ // In this case, that means we can't have 3 entities tagged with grape. Both
+ // remaining entities are tagged with grape and strawberry.
+ $this->clickPartialLink('article');
+ $this->assertSession()->pageTextNotContains('(3)');
+ $this->assertFacetLabel('grape (2)');
+ $this->assertFacetLabel('strawberry (2)');
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+ $this->assertFacetLabel('article (2)');
+ $this->assertFacetLabel('grape (3)');
+
+ // Make sure that after clicking on grape, which has only 3 entities, there
+ // are only 3 items left in the results for other facets as well. In this
+ // case, that means 2 entities of type article and 1 item.
+ $this->clickPartialLink('grape');
+ $this->assertSession()->pageTextContains('Displaying 3 search results');
+ $this->assertFacetLabel('article (2)');
+ $this->assertFacetLabel('item (1)');
+ }
+
+ /**
+ * Tests the hard limit setting.
+ *
+ * Cached implementation of testHardLimit integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testHardLimit()
+ */
+ public function testHardLimit() {
+ $this->createFacet('Owl', 'owl', 'keywords', static::VIEW_DISPLAY);
+ $facet = $this->getFacetById('owl');
+ $facet->addProcessor([
+ 'processor_id' => 'active_widget_order',
+ 'weights' => ['sort' => 20],
+ 'settings' => [],
+ ]);
+ $facet->addProcessor([
+ 'processor_id' => 'display_value_widget_order',
+ 'weights' => ['build' => 40],
+ 'settings' => [],
+ ]);
+ $this->facetStorage->save($facet);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+ $this->assertFacetLabel('grape (3)');
+ $this->assertFacetLabel('orange (3)');
+ $this->assertFacetLabel('apple (2)');
+ $this->assertFacetLabel('banana (1)');
+ $this->assertFacetLabel('strawberry (2)');
+
+ $this->updateFacet($facet->id(), ['hard_limit' => 3]);
+
+ $this->drupalGet(static::VIEW_URL);
+ // We're still testing for 5 search results here, the hard limit only limits
+ // the facets, not the search results.
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+ $this->assertFacetLabel('grape (3)');
+ $this->assertFacetLabel('orange (3)');
+ $this->assertFacetLabel('apple (2)');
+ $this->assertSession()->pageTextNotContains('banana (0)');
+ $this->assertSession()->pageTextNotContains('strawberry (0)');
+ }
+
+ /**
+ * Test minimum amount of items.
+ *
+ * Cached implementation of testMinimumAmount integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testMinimumAmount()
+ */
+ public function testMinimumAmount() {
+ $this->createFacet('Elf owl', 'elf_owl', 'type', static::VIEW_DISPLAY);
+ $this->updateFacet('elf_owl', ['min_count' => 1]);
+
+ // See that both article and item are showing.
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+ $this->assertFacetLabel('article (2)');
+ $this->assertFacetLabel('item (3)');
+
+ $this->updateFacet('elf_owl', ['min_count' => 3]);
+
+ // See that article is now hidden, item should still be showing.
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+ $this->assertSession()->pageTextNotContains('article');
+ $this->assertFacetLabel('item (3)');
+ }
+
+ /**
+ * Tests the visibility of facet source.
+ *
+ * Cached implementation of testFacetSourceVisibility integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testFacetSourceVisibility()
+ */
+ public function testFacetSourceVisibility() {
+ $this->createFacet('Vicuña', 'vicuna', 'type', static::VIEW_DISPLAY);
+ // Facet appears only on the search page for which it was created.
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertFacetBlocksAppear();
+ $this->drupalGet('');
+ $this->assertNoFacetBlocksAppear();
+
+ $facet = $this->getFacetById('vicuna');
+ $facet->setOnlyVisibleWhenFacetSourceIsVisible(FALSE);
+ $this->facetStorage->save($facet);
+
+ // Test that the facet source is visible on the search page and user/2 page.
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertFacetBlocksAppear();
+ $this->drupalGet('');
+ $this->assertFacetBlocksAppear();
+ }
+
+ /**
+ * Tests behavior with multiple enabled facets and their interaction.
+ *
+ * Cached implementation of testMultipleFacets integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testMultipleFacets()
+ */
+ public function testMultipleFacets() {
+ // Create 2 facets.
+ $this->createFacet('Snow Owl', 'snow_owl', 'type', static::VIEW_DISPLAY);
+ $this->createFacet('Forest Owl', 'forest_owl', 'category', static::VIEW_DISPLAY);
+
+ foreach (['snow_owl', 'forest_owl'] as $facet_id) {
+ $this->updateFacet($facet_id, ['min_count' => 0]);
+ }
+
+ // Go to the view and check the default behavior.
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+ $this->assertFacetLabel('item (3)');
+ $this->assertFacetLabel('article (2)');
+ $this->assertFacetLabel('item_category (2)');
+ $this->assertFacetLabel('article_category (2)');
+
+ // Start filtering.
+ $this->clickPartialLink('item_category');
+ $this->assertSession()->pageTextContains('Displaying 2 search results');
+ $this->checkFacetIsActive('item_category');
+ $this->assertFacetLabel('item (2)');
+
+ // Go back to the overview and start another filter, from the second facet
+ // block this time.
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextContains('Displaying 5 search results');
+ $this->clickPartialLink('article (2)');
+ $this->assertSession()->pageTextContains('Displaying 2 search results');
+ $this->checkFacetIsActive('article');
+ $this->assertFacetLabel('article_category (2)');
+ $this->assertFacetLabel('item_category (0)');
+ }
+
+ /**
+ * Tests that the configuration for showing a title works.
+ *
+ * Cached implementation of testShowTitle integration test.
+ *
+ * @see \Drupal\Tests\facets\Functional\IntegrationTest::testShowTitle()
+ */
+ public function testShowTitle() {
+ $this->createFacet('Llama', 'llama', 'type', static::VIEW_DISPLAY);
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->pageTextNotContains('Llama');
+
+ $this->updateFacet('llama', ['show_title' => TRUE]);
+
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()->responseContains('Llama
');
+ $this->assertSession()->pageTextContains('Llama');
+ }
+
+ /**
+ * Test facet blocks cache invalidation.
+ *
+ * Test covers search page with a facets and standalone facet block on FP.
+ */
+ public function testFacetBlockCacheNewContentIndexing() {
+ $this->createFacet('Test Facet name', 'test_facet_name', 'type', static::VIEW_DISPLAY);
+
+ $facet = $this->getFacetById('test_facet_name');
+ $facet->setOnlyVisibleWhenFacetSourceIsVisible(FALSE);
+ $this->facetStorage->save($facet);
+
+ foreach (['', static::VIEW_URL] as $url) {
+ $this->drupalGet($url);
+ $this->assertFacetLabel('article (2)');
+ $this->assertFacetLabel('item (3)');
+ }
+
+ $this->entityTestStorage->create([
+ 'name' => 'foo jiz baz',
+ 'body' => 'test test and a bit more test',
+ 'type' => 'item',
+ 'keywords' => ['orange', 'black'],
+ 'category' => 'item_category',
+ ])->save();
+
+ // Entity was added but not indexed yet, so facet state should remain the
+ // same.
+ foreach (['', static::VIEW_URL] as $url) {
+ $this->drupalGet($url);
+ $this->assertFacetLabel('article (2)');
+ $this->assertFacetLabel('item (3)');
+ }
+
+ // Index 1 remaining item and check that count has been updated.
+ $this->assertEquals(1, $this->indexItems($this->indexId), '1 item was indexed.');
+ foreach (['', static::VIEW_URL] as $url) {
+ $this->drupalGet($url);
+ $this->assertFacetLabel('article (2)');
+ $this->assertFacetLabel('item (4)');
+ }
+ }
+
+ /**
+ * Enable website page caching, set 1 day max age.
+ */
+ protected function enableWebsiteCache() {
+ $max_age = 86400;
+ $this->config('system.performance')
+ ->set('cache.page.max_age', $max_age)
+ ->save();
+ $this->drupalGet(static::VIEW_URL);
+ $this->assertSession()
+ ->responseHeaderContains('Cache-Control', 'max-age=' . $max_age);
+ }
+
+ /**
+ * Get facet entity by ids.
+ *
+ * @param string $id
+ * Facet id.
+ *
+ * @return \Drupal\facets\FacetInterface
+ * Loaded facet object.
+ */
+ protected function getFacetById(string $id): FacetInterface {
+ return $this->facetStorage->load($id);
+ }
+
+ /**
+ * Update facet tith with given values.
+ *
+ * @param string $id
+ * The facet entity ID.
+ * @param array $settings
+ * Array with values keyed by property names.
+ *
+ * @return \Drupal\facets\FacetInterface
+ * An updated facet entity.
+ */
+ protected function updateFacet(string $id, array $settings): FacetInterface {
+ $facet = $this->getFacetById($id);
+ foreach ($settings as $name => $value) {
+ $facet->set($name, $value);
+ }
+ $this->facetStorage->save($facet);
+
+ return $facet;
+ }
+
+}
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/IntegrationTest.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/IntegrationTest.php
index 59974200c..a7c3e809b 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/IntegrationTest.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/IntegrationTest.php
@@ -202,7 +202,7 @@ class IntegrationTest extends FacetsTestBase {
$this->assertFacetLabel('article');
$this->clickLink('item');
- $url = Url::fromUserInput('/search-api-test-fulltext', ['query' => ['f[0]' => 'ab_facet:item']]);
+ $url = Url::fromUserInput('/search-api-test-fulltext', ['query' => ['f' => ['ab_facet:item']]]);
$this->assertSession()->addressEquals($url);
$this->drupalGet($facet_edit_page);
@@ -213,7 +213,7 @@ class IntegrationTest extends FacetsTestBase {
$this->assertFacetLabel('article');
$this->clickLink('item');
- $url = Url::fromUserInput('/search-api-test-fulltext', ['query' => ['f[0]' => 'llama:item']]);
+ $url = Url::fromUserInput('/search-api-test-fulltext', ['query' => ['f' => ['llama:item']]]);
$this->assertSession()->addressEquals($url);
}
@@ -811,7 +811,7 @@ class IntegrationTest extends FacetsTestBase {
// Make sure numbers are displayed.
$edit = [
'widget_config[show_numbers]' => 1,
- 'facet_settings[min_count]' => 0,
+ 'facet_settings[min_count]' => 1,
];
$this->drupalGet('admin/config/search/facets/snow_owl/edit');
$this->submitForm($edit, 'Save');
@@ -840,7 +840,9 @@ class IntegrationTest extends FacetsTestBase {
$this->assertSession()->pageTextContains('Displaying 2 search results');
$this->checkFacetIsActive('article');
$this->assertFacetLabel('article_category (2)');
- $this->assertFacetLabel('item_category (0)');
+ // As min_count=1 and query_operator='and' we expect zero-result
+ // item_category to be hidden, see testMultipleFacets().
+ $this->assertSession()->pageTextNotContains('item_category');
}
/**
@@ -873,29 +875,34 @@ class IntegrationTest extends FacetsTestBase {
* Check that the disabling of the cache works.
*/
public function testViewsCacheDisable() {
- // Load the view, verify cache settings.
- $view = Views::getView('search_api_test_view');
- $view->setDisplay('page_1');
- $current_cache = $view->display_handler->getOption('cache');
- $this->assertEquals('none', $current_cache['type']);
- $view->display_handler->setOption('cache', ['type' => 'tag']);
- $view->save();
- $current_cache = $view->display_handler->getOption('cache');
- $this->assertEquals('tag', $current_cache['type']);
-
- // Create a facet and check for the cache disabled message.
- $id = "western_screech_owl";
- $name = "Western screech owl";
- $this->createFacet($name, $id);
- $this->drupalGet('admin/config/search/facets/' . $id . '/settings');
- $this->submitForm([], 'Save');
- $this->assertSession()->pageTextContains('Caching of view Search API Test Fulltext search view has been disabled.');
-
- // Check the view's cache settings again to see if they've been updated.
- $view = Views::getView('search_api_test_view');
- $view->setDisplay('page_1');
- $current_cache = $view->display_handler->getOption('cache');
- $this->assertEquals('none', $current_cache['type']);
+ $caches = [
+ // Tag cache plugin should be replaced by none, as it's not supported.
+ 'page_1' => 'none',
+ // Search API cache plugin shouldn't be changed.
+ 'page_2_sapi_tag' => 'search_api_tag',
+ 'page_2_sapi_time' => 'search_api_time',
+ ];
+ foreach ($caches as $display_id => $expected_cache_plugin) {
+ // Create a facet and check for the cache disabled message.
+ $id = 'western_screech_owl_' . $display_id;
+ $name = 'Western screech owl';
+ $this->createFacet($name, $id, 'type', $display_id);
+ $this->drupalGet('admin/config/search/facets/' . $id . '/settings');
+ $this->submitForm([], 'Save');
+ $warning = 'You may experience issues, because Search API Test Fulltext search view use cache. In case you will try to turn set cache plugin to none.';
+ if ($display_id === 'page_1') {
+ // Make sure that user will get a warning about source cache plugin.
+ $this->assertSession()->pageTextNotContains($warning);
+ }
+ else {
+ $this->assertSession()->pageTextContains($warning);
+ }
+ // Check the view's cache settings again to see if they've been updated.
+ $view = Views::getView('search_api_test_view');
+ $view->setDisplay($display_id);
+ $current_cache = $view->display_handler->getOption('cache');
+ $this->assertEquals($expected_cache_plugin, $current_cache['type']);
+ }
}
/**
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/Rest/FacetResourceTestBase.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/Rest/FacetResourceTestBase.php
index 88b22934a..5301a54fc 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/Rest/FacetResourceTestBase.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/Rest/FacetResourceTestBase.php
@@ -77,6 +77,8 @@ abstract class FacetResourceTestBase extends EntityResourceTestBase {
'id' => 'owl',
'langcode' => 'en',
'min_count' => 1,
+ 'missing' => FALSE,
+ 'missing_label' => 'others',
'name' => NULL,
'only_visible_when_facet_source_is_visible' => NULL,
'processor_configs' => [
@@ -113,4 +115,17 @@ abstract class FacetResourceTestBase extends EntityResourceTestBase {
// @todo Update after https://www.drupal.org/node/2300677.
}
+ /**
+ * The expected cache contexts for the GET/HEAD response of the test entity.
+ *
+ * @see ::testGet
+ *
+ * @return string[]
+ */
+ protected function getExpectedCacheContexts() {
+ return array_merge(parent::getExpectedCacheContexts(), [
+ 'url.query_args',
+ ]);
+ }
+
}
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/UrlIntegrationTest.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/UrlIntegrationTest.php
index b8afb95d1..027ae868e 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/UrlIntegrationTest.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Functional/UrlIntegrationTest.php
@@ -66,7 +66,7 @@ class UrlIntegrationTest extends FacetsTestBase {
// Go to the only enabled facet source's config and change the filter key.
$this->drupalGet('admin/config/search/facets');
- $this->clickLink('Configure', 1);
+ $this->clickLink('Configure', 2);
$edit = [
'filter_key' => 'y',
@@ -90,7 +90,7 @@ class UrlIntegrationTest extends FacetsTestBase {
// Go to the only enabled facet source's config and change the url
// processor.
$this->drupalGet('admin/config/search/facets');
- $this->clickLink('Configure', 1);
+ $this->clickLink('Configure', 2);
$edit = [
'filter_key' => 'y',
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Kernel/Entity/FacetFacetSourceTest.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Kernel/Entity/FacetFacetSourceTest.php
index e29daf4ca..c01a545ce 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Kernel/Entity/FacetFacetSourceTest.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Kernel/Entity/FacetFacetSourceTest.php
@@ -31,7 +31,6 @@ class FacetFacetSourceTest extends EntityKernelTestBase {
'search_api_db',
'search_api_test_db',
'search_api_test_example_content',
- 'search_api_test_views',
'views',
'rest',
'serialization',
@@ -60,7 +59,7 @@ class FacetFacetSourceTest extends EntityKernelTestBase {
'search_api_test_db',
]);
- $this->installConfig('search_api_test_views');
+ $this->installConfig('facets_search_api_dependency');
}
/**
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Kernel/FacetManager/DefaultFacetManagerTest.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Kernel/FacetManager/DefaultFacetManagerTest.php
index a840b44c4..72d19d74c 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Kernel/FacetManager/DefaultFacetManagerTest.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Kernel/FacetManager/DefaultFacetManagerTest.php
@@ -2,16 +2,18 @@
namespace Drupal\Tests\facets\Kernel\FacetManager;
-use Drupal\facets\Entity\Facet;
-use Drupal\KernelTests\KernelTestBase;
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Cache\CacheableMetadata;
+use Drupal\facets\FacetInterface;
+use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
/**
* Provides the DefaultFacetManager test.
*
* @group facets
- * @coversDefaultClass Drupal\facets\FacetManager\DefaultFacetManager
+ * @coversDefaultClass \Drupal\facets\FacetManager\DefaultFacetManager
*/
-class DefaultFacetManagerTest extends KernelTestBase {
+class DefaultFacetManagerTest extends EntityKernelTestBase {
/**
* {@inheritdoc}
@@ -19,16 +21,58 @@ class DefaultFacetManagerTest extends KernelTestBase {
protected static $modules = [
'facets',
'search_api',
+ 'search_api_db',
+ 'search_api_test_db',
+ 'facets_processors_collection',
+ 'facets_search_api_dependency',
+ 'facets_query_processor',
'system',
'user',
+ 'views',
+ 'rest',
+ 'serialization',
];
+ /**
+ * Facets entity storage.
+ *
+ * @var \Drupal\Core\Config\Entity\ConfigEntityStorage
+ */
+ protected $facetStorage;
+
+ /**
+ * An instance of the "facets.manager" service.
+ *
+ * @var \Drupal\facets\FacetManager\DefaultFacetManager
+ */
+ protected $facetManager;
+
/**
* {@inheritdoc}
*/
public function setUp(): void {
parent::setUp();
+
$this->installEntitySchema('facets_facet');
+ $this->installEntitySchema('entity_test_mulrev_changed');
+ $this->installEntitySchema('search_api_task');
+
+ $state_service = \Drupal::state();
+ $state_service->set('search_api_use_tracking_batch', FALSE);
+
+ // Set tracking page size so tracking will work properly.
+ \Drupal::configFactory()
+ ->getEditable('search_api.settings')
+ ->set('tracking_page_size', 100)
+ ->save();
+
+ $this->installConfig([
+ 'search_api_test_db',
+ 'facets_search_api_dependency',
+ ]);
+
+ $this->facetStorage = $this->entityTypeManager->getStorage('facets_facet');
+ $this->facetManager = $this->container->get('facets.manager');
}
/**
@@ -38,16 +82,15 @@ class DefaultFacetManagerTest extends KernelTestBase {
*/
public function testGetEnabledFacets() {
/** @var \Drupal\facets\FacetManager\DefaultFacetManager $dfm */
- $dfm = \Drupal::service('facets.manager');
- $returnValue = $dfm->getEnabledFacets();
+ $returnValue = $this->facetManager->getEnabledFacets();
$this->assertEmpty($returnValue);
// Create a facet.
- $entity = $this->createAndSaveFacet('test_facet');
+ $entity = $this->createAndSaveFacet('Mercury', 'planets');
- $returnValue = $dfm->getEnabledFacets();
+ $returnValue = $this->facetManager->getEnabledFacets();
$this->assertNotEmpty($returnValue);
- $this->assertSame($entity->id(), $returnValue['test_facet']->id());
+ $this->assertSame($entity->id(), $returnValue['Mercury']->id());
}
/**
@@ -56,73 +99,286 @@ class DefaultFacetManagerTest extends KernelTestBase {
* @covers ::getFacetsByFacetSourceId
*/
public function testGetFacetsByFacetSourceId() {
- /** @var \Drupal\facets\FacetManager\DefaultFacetManager $dfm */
- $dfm = \Drupal::service('facets.manager');
- $this->assertEmpty($dfm->getFacetsByFacetSourceId('planets'));
+ $this->assertEmpty($this->facetManager->getFacetsByFacetSourceId('planets'));
// Create 2 different facets with a unique facet source id.
- $entity = $this->createAndSaveFacet('Jupiter');
- $entity->setFacetSourceId('planets');
- $entity->save();
- $entity = $this->createAndSaveFacet('Pluto');
- $entity->setFacetSourceId('former_planets');
- $entity->save();
+ $this->createAndSaveFacet('Jupiter', 'planets');
+ $this->createAndSaveFacet('Pluto', 'former_planets');
- $planetFacets = $dfm->getFacetsByFacetSourceId('planets');
+ $planetFacets = $this->facetManager->getFacetsByFacetSourceId('planets');
$this->assertNotEmpty($planetFacets);
$this->assertCount(1, $planetFacets);
$this->assertSame('Jupiter', $planetFacets['Jupiter']->id());
- $formerPlanetFacets = $dfm->getFacetsByFacetSourceId('former_planets');
+ $formerPlanetFacets = $this->facetManager->getFacetsByFacetSourceId('former_planets');
$this->assertNotEmpty($formerPlanetFacets);
$this->assertCount(1, $formerPlanetFacets);
$this->assertSame('Pluto', $formerPlanetFacets['Pluto']->id());
// Make pluto a planet again.
+ $entity = $this->facetStorage->load('Pluto');
$entity->setFacetSourceId('planets');
- $entity->save();
+ $this->facetStorage->save($entity);
// Test that we now hit the static cache.
- $planetFacets = $dfm->getFacetsByFacetSourceId('planets');
+ $planetFacets = $this->facetManager->getFacetsByFacetSourceId('planets');
$this->assertNotEmpty($planetFacets);
$this->assertCount(1, $planetFacets);
// Change the 'facets' property on the manager to public, so we can
// overwrite it here. This is because otherwise we run into the static
// caches.
- $facetsProperty = new \ReflectionProperty($dfm, 'facets');
- $facetsProperty->setAccessible(TRUE);
- $facetsProperty->setValue($dfm, []);
+ $this->resetFacetsManagerStaticCache();
// Now that the static cache is reset, test that we have 2 planets.
- $planetFacets = $dfm->getFacetsByFacetSourceId('planets');
+ $planetFacets = $this->facetManager->getFacetsByFacetSourceId('planets');
$this->assertNotEmpty($planetFacets);
$this->assertCount(2, $planetFacets);
$this->assertSame('Jupiter', $planetFacets['Jupiter']->id());
$this->assertSame('Pluto', $planetFacets['Pluto']->id());
}
+ /**
+ * Tests the cachebillity data passed into search query.
+ */
+ public function testAlterQueryCacheabilityMetadata() {
+ // @see facets_processors_collection_facets_search_api_query_type_mapping_alter().
+ \Drupal::state()->set('facets_processors_collection_alter_string_query_handler', TRUE);
+
+ $view = $this->entityTypeManager
+ ->getStorage('view')
+ ->load('search_api_test_view')
+ ->getExecutable();
+ $view->setDisplay('page_1');
+
+ $query = $view->getQuery()->getSearchApiQuery();
+
+ // Create facets for a SAPI view display.
+ $facet_source = 'search_api:views_page__search_api_test_view__page_1';
+ $facet_mars = $this->createAndSaveFacet('Mars', $facet_source);
+ $facet_neptune = $this->createAndSaveFacet('Neptune', $facet_source);
+ $expected_tags = array_unique(array_merge(
+ $query->getCacheTags(),
+ $facet_mars->getCacheTags(),
+ $facet_neptune->getCacheTags(),
+ [
+ 'fpc:query_plugin_type_plugin',
+ 'dummy_query_pre_query_tag',
+ ]
+ ));
+ $this->resetFacetsManagerStaticCache();
+ $expected_contexts = array_unique(array_merge(
+ $query->getCacheContexts(),
+ $facet_mars->getFacetSource()->getCacheContexts(),
+ [
+ 'fpc_query_type_plugin',
+ 'dummy_query_pre_query',
+ ]
+ ));
+
+ // Make sure that query cachebillity will include facets cache tags e.g.
+ // view results will depends on the facet configuration.
+ $this->facetManager->alterQuery($query, $facet_source);
+ $this->assertCacheabillityArrays($expected_contexts, $query->getCacheContexts());
+ $this->assertCacheabillityArrays($expected_tags, $query->getCacheTags());
+ }
+
+ /**
+ * Tests the cachebillity data passed into search query.
+ *
+ * @param string $facet_source_id
+ * The tested facet source ID.
+ * @param array $expected_metadata
+ * The expected cache metadata for the given facet source.
+ *
+ * @dataProvider testBuildCacheabilityMetadataProvider
+ */
+ public function testBuildCacheabilityMetadata(string $facet_source_id, array $expected_metadata) {
+ $facet = $this->createAndSaveFacet('mars', $facet_source_id);
+
+ $cacheable_processors = [
+ 'fpc_post_query_processor',
+ 'fpc_build_processor',
+ 'fpc_sort_processor',
+ ];
+
+ foreach ($cacheable_processors as $processor) {
+ $facet->addProcessor([
+ 'processor_id' => $processor,
+ 'weights' => [],
+ 'settings' => [],
+ ]);
+ }
+
+ $facet->setOnlyVisibleWhenFacetSourceIsVisible(FALSE);
+ $this->facetStorage->save($facet);
+ // Make sure that new processor is taken into consideration.
+ $this->resetFacetsManagerStaticCache();
+
+ $build = [];
+ $metadata = CacheableMetadata::createFromObject($facet);
+ $metadata->applyTo($build);
+ $this->assertEquals($expected_metadata['max-age'], $build['#cache']['max-age']);
+ $this->assertCacheabillityArrays($expected_metadata['contexts'], $build['#cache']['contexts']);
+ $this->assertCacheabillityArrays($expected_metadata['tags'], $build['#cache']['tags']);
+
+ $facet->removeProcessor('fpc_sort_processor');
+ // Test that un-cacheable plugin kills the cache.
+ $facet->addProcessor([
+ 'processor_id' => 'fpc_sort_random_processor',
+ 'settings' => [],
+ 'weights' => [],
+ ]);
+
+ $this->facetStorage->save($facet);
+ $this->resetFacetsManagerStaticCache();
+
+ $build = [];
+ $metadata = CacheableMetadata::createFromObject($facet);
+ $metadata->applyTo($build);
+
+ $this->assertEquals(0, $build['#cache']['max-age']);
+ $this->assertCacheabillityArrays($expected_metadata['contexts'], $build['#cache']['contexts']);
+ $this->assertCacheabillityArrays($expected_metadata['tags'], $build['#cache']['tags']);
+ }
+
/**
* Create and save a facet, for usage in test-scenario's.
*
* @param string $id
* The id.
+ * @param string $source
+ * The source id.
*
* @return \Drupal\facets\FacetInterface
* The newly created facet.
*/
- protected function createAndSaveFacet($id) {
- // Create a facet.
- $entity = Facet::create([
+ protected function createAndSaveFacet(string $id, string $source): FacetInterface {
+ /** @var \Drupal\facets\FacetInterface $facet */
+ $facet = $this->facetStorage->create([
'id' => $id,
'name' => 'Test facet',
]);
- $entity->setWidget('links');
- $entity->setEmptyBehavior(['behavior' => 'none']);
- $entity->setFacetSourceId('fluffy');
- $entity->save();
+ $facet->setWidget('links');
+ $facet->setFieldIdentifier('type');
+ $facet->setEmptyBehavior(['behavior' => 'none']);
+ $facet->setFacetSourceId($source);
- return $entity;
+ $facet->addProcessor([
+ 'processor_id' => 'url_processor_handler',
+ 'settings' => [],
+ 'weights' => [],
+ ]);
+
+ $this->facetStorage->save($facet);
+ // Add dummy processor instead of default, to test its cachebillity.
+ $source = $facet->getFacetSourceConfig();
+ $source->setUrlProcessor('dummy_query');
+ $source->save();
+
+ return $facet;
+ }
+
+ /**
+ * Reset static facets.manager static cache.
+ *
+ * @todo discuss whether or not this should be done automatically when facet
+ * gets inserted/updated or deleted.
+ */
+ protected function resetFacetsManagerStaticCache() {
+ foreach (['builtFacets', 'facets', 'processedFacets'] as $prop) {
+ $facetsProperty = new \ReflectionProperty($this->facetManager, $prop);
+ $facetsProperty->setAccessible(TRUE);
+ $facetsProperty->setValue($this->facetManager, []);
+ $facetsProperty->setAccessible(FALSE);
+ }
+ }
+
+ /**
+ * Assert that actual cachebillity matches expected one.
+ */
+ public function assertCacheabillityArrays($expected, $actual, string $message = ''): void {
+ foreach ([&$expected, &$actual] as &$array) {
+ foreach ($array as &$value) {
+ if (is_array($value)) {
+ sort($value);
+ }
+ }
+ }
+ sort($expected);
+ sort($actual);
+ $this->assertEquals($expected, $actual, $message);
+ }
+
+ /**
+ * Data provider for testBuildCacheabilityMetadata().
+ *
+ * @return array
+ * Array of method call argument arrays for testBuildCacheabilityMetadata().
+ *
+ * @see ::testBuildCacheabilityMetadata
+ */
+ public function testBuildCacheabilityMetadataProvider() {
+ $basic = [
+ 'contexts' => [
+ // Facet API uses Request query params to populate active facets values.
+ 'url.query_args',
+ // Added by build fpc_post_query_processor process plugin.
+ 'fpc_post_query',
+ // Added by build fpc_build_processor process plugin.
+ 'fpc_build',
+ // Added by build fpc_sort_processor process plugin.
+ 'fpc_sort',
+ // Added by Url "dummy_query" url processor.
+ 'dummy_query_pre_query',
+ // Added by views view source plugin.
+ 'url',
+ 'languages:language_interface',
+ ],
+ 'tags' => [
+ // Facet controls query and look & feel of the facet results, so it's
+ // config should be present as a cache dependency.
+ 'config:facets.facet.mars',
+ // Added by build fpc_post_query_processor process plugin.
+ 'fpc:post_query_processor',
+ // Added by Url "dummy_query" url processor.
+ 'dummy_query_pre_query_tag',
+ // Added by build fpc_build_processor process plugin.
+ 'fpc:build_processor',
+ // Added by build fpc_sort_processor process plugin.
+ 'fpc:sort_processor',
+ // Added by views view source plugin.
+ 'config:views.view.search_api_test_view',
+ 'config:search_api.index.database_search_index',
+ ],
+ ];
+ return [
+ // Expected cacheability for the facet with a source with disabled cache.
+ [
+ 'search_api:views_page__search_api_test_view__page_1',
+ $basic + ['max-age' => 0],
+ ],
+ // Expected cacheability for the facet with a source that has TAG cache
+ // strategy.
+ [
+ 'search_api:views_page__search_api_test_view__page_2_sapi_tag',
+ array_merge_recursive(
+ $basic,
+ [
+ 'tags' => [
+ 'search_api_list:database_search_index',
+ ],
+ 'max-age' => Cache::PERMANENT,
+ ]
+ ),
+ ],
+ // Expected cacheability for the facet with a source that has TIME cache
+ // strategy.
+ [
+ 'search_api:views_page__search_api_test_view__page_2_sapi_time',
+ $basic + ['max-age' => 518400],
+ ],
+ ];
}
}
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/processor/DependentFacetProcessorTest.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/processor/DependentFacetProcessorTest.php
index ac717d472..6d90b716d 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/processor/DependentFacetProcessorTest.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/processor/DependentFacetProcessorTest.php
@@ -2,13 +2,18 @@
namespace Drupal\Tests\facets\Unit\Plugin\processor;
+use Drupal\Core\Config\Entity\ConfigEntityType;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\facets\Entity\Facet;
use Drupal\facets\FacetManager\DefaultFacetManager;
use Drupal\facets\Plugin\facets\processor\DependentFacetProcessor;
+use Drupal\facets\Processor\ProcessorPluginManager;
use Drupal\facets\Result\Result;
use Drupal\Tests\UnitTestCase;
+use Symfony\Component\EventDispatcher\EventDispatcher;
/**
* Unit test for processor.
@@ -36,6 +41,35 @@ class DependentFacetProcessorTest extends UnitTestCase {
new Result($facet, 'church_owl', 'Church owl', 1),
new Result($facet, 'barn_owl', 'Barn owl', 1),
];
+
+ $facet_entity_type = $this->getMockBuilder(ConfigEntityType::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $facet_entity_type->method('getConfigPrefix')
+ ->willReturn('facets.facet');
+
+ $entity_type_manager = $this->getMockBuilder(EntityTypeManager::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $entity_type_manager->method('getDefinition')
+ ->with('facets_facet')
+ ->willReturn($facet_entity_type);
+
+ $processor_plugin_manager = $this->getMockBuilder(ProcessorPluginManager::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $processor_plugin_manager->method('getDefinitions')
+ ->willReturn([]);
+
+ $event_dispatcher = $this->getMockBuilder(EventDispatcher::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $container = new ContainerBuilder();
+ $container->set('entity_type.manager', $entity_type_manager);
+ $container->set('plugin.manager.facets.processor', $processor_plugin_manager);
+ $container->set('event_dispatcher', $event_dispatcher);
+ \Drupal::setContainer($container);
}
/**
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/processor/ListItemProcessorTest.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/processor/ListItemProcessorTest.php
index 46d95746b..9e9d96e77 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/processor/ListItemProcessorTest.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/processor/ListItemProcessorTest.php
@@ -2,19 +2,24 @@
namespace Drupal\Tests\facets\Unit\Plugin\processor;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\Entity\ConfigEntityType;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Entity\EntityTypeBundleInfo;
+use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
use Drupal\facets\Entity\Facet;
use Drupal\facets\FacetSource\FacetSourcePluginInterface;
use Drupal\facets\FacetSource\FacetSourcePluginManager;
use Drupal\facets\Plugin\facets\processor\ListItemProcessor;
+use Drupal\facets\Processor\ProcessorPluginManager;
use Drupal\facets\Result\Result;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\Tests\UnitTestCase;
use Drupal\Core\Config\ConfigManager;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Field\BaseFieldDefinition;
+use Symfony\Component\EventDispatcher\EventDispatcher;
/**
* Unit test for processor.
@@ -37,6 +42,8 @@ class ListItemProcessorTest extends UnitTestCase {
*/
protected $results;
+ protected $processor_plugin_manager;
+
/**
* Creates a new processor object for use in the tests.
*/
@@ -74,6 +81,15 @@ class ListItemProcessorTest extends UnitTestCase {
$facet_source->expects($this->any())
->method('getDataDefinition')
->willReturn($data_definition);
+ $facet_source->expects($this->any())
+ ->method('getCacheContexts')
+ ->willReturn([]);
+ $facet_source->expects($this->any())
+ ->method('getCacheTags')
+ ->willReturn([]);
+ $facet_source->expects($this->any())
+ ->method('getCacheMaxAge')
+ ->willReturn(CacheBackendInterface::CACHE_PERMANENT);
// Add the plugin manager.
$pluginManager = $this->getMockBuilder(FacetSourcePluginManager::class)
@@ -88,8 +104,34 @@ class ListItemProcessorTest extends UnitTestCase {
$this->processor = new ListItemProcessor([], 'list_item', [], $config_manager, $entity_field_manager, $entity_type_bundle_info);
+ $facet_entity_type = $this->getMockBuilder(ConfigEntityType::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $facet_entity_type->method('getConfigPrefix')
+ ->willReturn('facets.facet');
+
+ $entity_type_manager = $this->getMockBuilder(EntityTypeManager::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $entity_type_manager->method('getDefinition')
+ ->with('facets_facet')
+ ->willReturn($facet_entity_type);
+
+ $this->processor_plugin_manager = $this->getMockBuilder(ProcessorPluginManager::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->processor_plugin_manager->method('getDefinitions')
+ ->willReturn(['list_item' => ['class' => ListItemProcessor::class]]);
+
+ $event_dispatcher = $this->getMockBuilder(EventDispatcher::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
$container = new ContainerBuilder();
$container->set('plugin.manager.facets.facet_source', $pluginManager);
+ $container->set('entity_type.manager', $entity_type_manager);
+ $container->set('plugin.manager.facets.processor', $this->processor_plugin_manager);
+ $container->set('event_dispatcher', $event_dispatcher);
\Drupal::setContainer($container);
}
@@ -100,6 +142,16 @@ class ListItemProcessorTest extends UnitTestCase {
$module_field = $this->getMockBuilder(FieldStorageConfig::class)
->disableOriginalConstructor()
->getMock();
+ // Return cache field metadata.
+ $module_field->expects($this->exactly(1))
+ ->method('getCacheContexts')
+ ->willReturn([]);
+ $module_field->expects($this->exactly(1))
+ ->method('getCacheTags')
+ ->willReturn(['module_field_tag']);
+ $module_field->expects($this->exactly(1))
+ ->method('getCacheMaxAge')
+ ->willReturn(12345);
// Make sure that when the processor calls loadConfigEntityByName the field
// we created here is called.
@@ -119,6 +171,8 @@ class ListItemProcessorTest extends UnitTestCase {
->getMock();
$processor = new ListItemProcessor([], 'list_item', [], $config_manager, $entity_field_manager, $entity_type_bundle_info);
+ $this->processor_plugin_manager->method('createInstance')
+ ->willReturn($processor);
// Config entity field facet.
$module_field_facet = new Facet([], 'facets_facet');
@@ -131,13 +185,15 @@ class ListItemProcessorTest extends UnitTestCase {
'settings' => [],
]);
- /** @var \Drupal\facets\Result\Result[] $module_field_facet- */
+ /** @var \Drupal\facets\Result\Result[] $module_field_results */
$module_field_results = $processor->build($module_field_facet, $this->results);
$this->assertCount(3, $module_field_results);
$this->assertEquals('llama', $module_field_results[0]->getDisplayValue());
$this->assertEquals('badger', $module_field_results[1]->getDisplayValue());
$this->assertEquals('kitten', $module_field_results[2]->getDisplayValue());
+ $this->assertContains('module_field_tag', $module_field_facet->getCacheTags());
+ $this->assertEquals(12345, $module_field_facet->getCacheMaxAge());
}
/**
@@ -147,6 +203,16 @@ class ListItemProcessorTest extends UnitTestCase {
$module_field = $this->getMockBuilder(FieldStorageConfig::class)
->disableOriginalConstructor()
->getMock();
+ // Return cache field metadata.
+ $module_field->expects($this->exactly(1))
+ ->method('getCacheContexts')
+ ->willReturn([]);
+ $module_field->expects($this->exactly(1))
+ ->method('getCacheTags')
+ ->willReturn(['module_field_tag']);
+ $module_field->expects($this->exactly(1))
+ ->method('getCacheMaxAge')
+ ->willReturn(54321);
$config_manager = $this->getMockBuilder(ConfigManager::class)
->disableOriginalConstructor()
@@ -164,6 +230,8 @@ class ListItemProcessorTest extends UnitTestCase {
->getMock();
$processor = new ListItemProcessor([], 'list_item', [], $config_manager, $entity_field_manager, $entity_type_bundle_info);
+ $this->processor_plugin_manager->method('createInstance')
+ ->willReturn($processor);
// Config entity field facet.
$module_field_facet = new Facet([], 'facets_facet');
@@ -175,6 +243,8 @@ class ListItemProcessorTest extends UnitTestCase {
'weights' => [],
'settings' => [],
]);
+ $cache_tags = $module_field_facet->getCacheTags();
+
/** @var \Drupal\facets\Result\Result[] $module_field_facet- */
$module_field_results = $processor->build($module_field_facet, $this->results);
@@ -182,6 +252,8 @@ class ListItemProcessorTest extends UnitTestCase {
$this->assertEquals('llama', $module_field_results[0]->getDisplayValue());
$this->assertEquals('badger', $module_field_results[1]->getDisplayValue());
$this->assertEquals('kitten', $module_field_results[2]->getDisplayValue());
+ $this->assertSame(array_merge($cache_tags, ['module_field_tag']), $module_field_facet->getCacheTags());
+ $this->assertEquals(54321, $module_field_facet->getCacheMaxAge());
}
/**
@@ -195,6 +267,16 @@ class ListItemProcessorTest extends UnitTestCase {
$base_field = $this->getMockBuilder(BaseFieldDefinition::class)
->disableOriginalConstructor()
->getMock();
+ // Return cache field metadata.
+ $base_field->expects($this->exactly(1))
+ ->method('getCacheContexts')
+ ->willReturn([]);
+ $base_field->expects($this->exactly(1))
+ ->method('getCacheTags')
+ ->willReturn(['base_field_tag']);
+ $base_field->expects($this->exactly(1))
+ ->method('getCacheMaxAge')
+ ->willReturn(1235813);
$entity_field_manager = $this->getMockBuilder(EntityFieldManager::class)
->disableOriginalConstructor()
@@ -211,6 +293,8 @@ class ListItemProcessorTest extends UnitTestCase {
->getMock();
$processor = new ListItemProcessor([], 'list_item', [], $config_manager, $entity_field_manager, $entity_type_bundle_info);
+ $this->processor_plugin_manager->method('createInstance')
+ ->willReturn($processor);
// Base prop facet.
$base_prop_facet = new Facet([], 'facets_facet');
@@ -222,6 +306,7 @@ class ListItemProcessorTest extends UnitTestCase {
'weights' => [],
'settings' => [],
]);
+ $cache_tags = $base_prop_facet->getCacheTags();
/** @var \Drupal\facets\Result\Result[] $base_prop_results */
$base_prop_results = $processor->build($base_prop_facet, $this->results);
@@ -230,6 +315,8 @@ class ListItemProcessorTest extends UnitTestCase {
$this->assertEquals('llama', $base_prop_results[0]->getDisplayValue());
$this->assertEquals('badger', $base_prop_results[1]->getDisplayValue());
$this->assertEquals('kitten', $base_prop_results[2]->getDisplayValue());
+ $this->assertSame(array_merge($cache_tags, ['base_field_tag']), $base_prop_facet->getCacheTags());
+ $this->assertEquals(1235813, $base_prop_facet->getCacheMaxAge());
}
/**
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/url_processor/QueryStringTest.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/url_processor/QueryStringTest.php
index 6e5ecdef5..39e7312e8 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/url_processor/QueryStringTest.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/url_processor/QueryStringTest.php
@@ -4,6 +4,7 @@ namespace Drupal\Tests\facets\Unit\Plugin\url_processor;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Http\RequestStack;
use Drupal\Core\Path\PathValidatorInterface;
use Drupal\facets\Entity\Facet;
use Drupal\facets\Entity\FacetSource;
@@ -13,6 +14,8 @@ use Drupal\facets\FacetSource\FacetSourcePluginManager;
use Drupal\facets\Plugin\facets\url_processor\QueryString;
use Drupal\facets\Result\Result;
use Drupal\facets\Result\ResultInterface;
+use Drupal\facets\UrlProcessor\UrlProcessorPluginManager;
+use Drupal\facets\Utility\FacetsUrlGenerator;
use Drupal\Tests\Core\Routing\TestRouterInterface;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -56,6 +59,13 @@ class QueryStringTest extends UnitTestCase {
*/
protected $eventDispatcher;
+ /**
+ * The URL generator.
+ *
+ * @var \Drupal\facets\Utility\FacetsUrlGenerator
+ */
+ protected $urlGenerator;
+
/**
* Creates a new processor object for use in the tests.
*/
@@ -63,6 +73,7 @@ class QueryStringTest extends UnitTestCase {
parent::setUp();
$this->eventDispatcher = $this->createMock(EventDispatcherInterface::class);
+ $this->urlGenerator = new FacetsUrlGenerator($this->createMock(UrlProcessorPluginManager::class), $this->createMock(EntityTypeManagerInterface::class));
$facet = new Facet([], 'facets_facet');
$this->originalResults = [
@@ -74,6 +85,8 @@ class QueryStringTest extends UnitTestCase {
];
$this->setContainer();
+
+ drupal_static_reset();
}
/**
@@ -82,7 +95,7 @@ class QueryStringTest extends UnitTestCase {
public function testEmptyProcessorConfiguration() {
$this->expectException(InvalidProcessorException::class);
$this->expectExceptionMessage("The url processor doesn't have the required 'facet' in the configuration array.");
- new QueryString([], 'test', [], new Request(), $this->entityManager, $this->eventDispatcher);
+ new QueryString([], 'test', [], new Request(), $this->entityManager, $this->eventDispatcher, $this->urlGenerator);
}
/**
@@ -116,7 +129,7 @@ class QueryStringTest extends UnitTestCase {
$request = new Request();
$request->query->set('f', ['test:badger']);
- $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $entityTypeManager, $this->eventDispatcher);
+ $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $entityTypeManager, $this->eventDispatcher, $this->urlGenerator);
$this->processor->setActiveItems($facet);
$this->assertEquals(['badger'], $facet->getActiveItems());
@@ -153,7 +166,7 @@ class QueryStringTest extends UnitTestCase {
$request = new Request();
$request->query->set('f', ['test:badger', 'test:mushroom', 'donkey:kong']);
- $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $entityTypeManager, $this->eventDispatcher);
+ $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $entityTypeManager, $this->eventDispatcher, $this->urlGenerator);
$this->processor->setActiveItems($facet);
$this->assertEquals(['badger', 'mushroom'], $facet->getActiveItems());
@@ -170,7 +183,7 @@ class QueryStringTest extends UnitTestCase {
$request = new Request();
$request->query->set('f', []);
- $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $this->entityManager, $this->eventDispatcher);
+ $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $this->entityManager, $this->eventDispatcher, $this->urlGenerator);
$results = $this->processor->buildUrls($facet, []);
$this->assertEmpty($results);
}
@@ -187,7 +200,7 @@ class QueryStringTest extends UnitTestCase {
$request = new Request();
$request->query->set('f', []);
- $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $this->entityManager, $this->eventDispatcher);
+ $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $this->entityManager, $this->eventDispatcher, $this->urlGenerator);
$results = $this->processor->buildUrls($facet, $this->originalResults);
$this->assertEquals('f', $this->processor->getFilterKey());
@@ -237,7 +250,7 @@ class QueryStringTest extends UnitTestCase {
$request = new Request();
$request->query->set('f', ['king:kong']);
- $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $entityTypeManager, $this->eventDispatcher);
+ $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $entityTypeManager, $this->eventDispatcher, $this->urlGenerator);
$results = $this->processor->buildUrls($facet, $original_results);
/** @var \Drupal\facets\Result\ResultInterface $r */
@@ -265,7 +278,7 @@ class QueryStringTest extends UnitTestCase {
$this->originalResults[1]->setActiveState(TRUE);
$this->originalResults[2]->setActiveState(TRUE);
- $this->processor = new QueryString(['facet' => $facet], 'query_string', [], new Request(), $this->entityManager, $this->eventDispatcher);
+ $this->processor = new QueryString(['facet' => $facet], 'query_string', [], new Request(), $this->entityManager, $this->eventDispatcher, $this->urlGenerator);
$results = $this->processor->buildUrls($facet, $this->originalResults);
$this->assertEquals('route:test?f%5B0%5D=test%3A' . $results[0]->getRawValue(), $results[0]->getUrl()->toUriString());
@@ -305,7 +318,7 @@ class QueryStringTest extends UnitTestCase {
$request = new Request();
$request->query->set('ab', []);
- $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $this->entityManager, $this->eventDispatcher);
+ $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $this->entityManager, $this->eventDispatcher, $this->urlGenerator);
$results = $this->processor->buildUrls($facet, $this->originalResults);
/** @var \Drupal\facets\Result\ResultInterface $r */
@@ -324,7 +337,7 @@ class QueryStringTest extends UnitTestCase {
$facet->setUrlAlias('test');
$facet->setFacetSourceId('facet_source__dummy');
- $this->processor = new QueryString(['facet' => $facet, 'separator' => '__'], 'query_string', [], new Request(), $this->entityManager, $this->eventDispatcher);
+ $this->processor = new QueryString(['facet' => $facet, 'separator' => '__'], 'query_string', [], new Request(), $this->entityManager, $this->eventDispatcher, $this->urlGenerator);
$results = $this->processor->buildUrls($facet, $this->originalResults);
foreach ($results as $result) {
@@ -359,7 +372,7 @@ class QueryStringTest extends UnitTestCase {
$facet->setUrlAlias('test');
$facet->setFacetSourceId('facet_source__dummy');
- $this->processor = new QueryString(['facet' => $facet], 'query_string', [], new Request(), $this->entityManager, $this->eventDispatcher);
+ $this->processor = new QueryString(['facet' => $facet], 'query_string', [], new Request(), $this->entityManager, $this->eventDispatcher, $this->urlGenerator);
$results = $this->processor->buildUrls($facet, $this->originalResults);
foreach ($results as $result) {
@@ -379,10 +392,20 @@ class QueryStringTest extends UnitTestCase {
->method('matchRequest')
->willThrowException(new ResourceNotFoundException());
+ $request = new Request();
+
+ $request_stack = $this->getMockBuilder(RequestStack::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $request_stack->expects($this->any())
+ ->method('getCurrentRequest')
+ ->willReturn($request);
+
// Get the container from the setUp method and change it with the
// implementation created here, that has the route parameters.
$container = \Drupal::getContainer();
$container->set('router.no_access_checks', $router);
+ $container->set('request_stack', $request_stack);
\Drupal::setContainer($container);
// Create facet.
@@ -391,7 +414,7 @@ class QueryStringTest extends UnitTestCase {
$facet->setUrlAlias('test');
$facet->setFacetSourceId('facet_source__dummy');
- $this->processor = new QueryString(['facet' => $facet], 'query_string', [], new Request(), $this->entityManager, $this->eventDispatcher);
+ $this->processor = new QueryString(['facet' => $facet], 'query_string', [], $request, $this->entityManager, $this->eventDispatcher, $this->urlGenerator);
$results = $this->processor->buildUrls($facet, $this->originalResults);
diff --git a/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/widget/LinksWidgetTest.php b/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/widget/LinksWidgetTest.php
index e344e282d..e23a4ae87 100644
--- a/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/widget/LinksWidgetTest.php
+++ b/frontend/drupal9/web/modules/contrib/facets/tests/src/Unit/Plugin/widget/LinksWidgetTest.php
@@ -10,6 +10,7 @@ use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\facets\FacetSource\FacetSourcePluginManager;
use Drupal\facets\UrlProcessor\UrlProcessorInterface;
+use Drupal\facets\Utility\FacetsUrlGenerator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\ParameterBag;
@@ -273,10 +274,15 @@ class LinksWidgetTest extends WidgetTestBase {
->method('getStorage')
->willReturn($storage);
+ $facets_url_generator = $this->getMockBuilder(FacetsUrlGenerator::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
$container = new ContainerBuilder();
$container->set('router.no_access_checks', $router);
$container->set('entity_type.manager', $em);
$container->set('plugin.manager.facets.url_processor', $manager);
+ $container->set('facets.utility.url_generator', $facets_url_generator);
\Drupal::setContainer($container);
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/CHANGELOG.txt b/frontend/drupal9/web/modules/contrib/metatag/CHANGELOG.txt
index b4abaf33e..4553d4786 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/CHANGELOG.txt
+++ b/frontend/drupal9/web/modules/contrib/metatag/CHANGELOG.txt
@@ -1,3 +1,69 @@
+Metatag 8.x-1.20, 2022-07-12
+----------------------------
+#3257588 by Eugene Bocharov, lobodacyril, jippie1948, Kasey_MK, djween, awasson,
+ DamienMcKenna, Valdes14, laura.florey, stacypendell: DB update hangs at
+ metatag 8109 - Update mask_icon values to the new structure.
+#3258978 by heddn, DamienMcKenna: tokenize not in config schema for
+ metatag_display_extender.
+#3258346 by Eugene Bocharov, jedgar1mx, 4kant, Renrhaf, DamienMcKenna, kriboogh:
+ Error: Call to a member function __wakeup() on null.
+#3113761 by DamienMcKenna, thalles, rokzabukovec, Diego_Mow, urvashi_vora:
+ Coding standards cleanup.
+#3261505 by DamienMcKenna, Eugene Bocharov, Sergiu Stici: In php 8.1 the explode
+ function throws a notice when default value is null.
+#3265679 by DamienMcKenna: Additional coding standards bugs.
+#3241256 by ndf, sabina.h, idebr, DamienMcKenna: Remove redundant HTTP headers
+ for canonical and short_link tags.
+#3262308 by YahyaAlHamad, DamienMcKenna: metatag_update_8109 fails because of
+ unknown column.
+#3261467 by DamienMcKenna, HnLn: in php 8.1 preg_match in
+ metatag_get_route_entity throws notice when route is null.
+#3266326 by victoria-marina, Guilherme Rabelo, DamienMcKenna: Use Dependency
+ Injection in MetatagManager.
+#3265567 by DamienMcKenna, Anatolij Zajika, PCate: PHP8 undefined array key
+ "description".
+#3266406 by szato, DamienMcKenna: Don't assume the 'first_row_tokens' cache key
+ is defined.
+#3264449 by DamienMcKenna, gilles_webstanz: Trim og:description doesn't work.
+#3258427 by Eugene Bocharov, mrshowerman, saranchuk_hys, phthlaap, apaderno,
+ Kulturmensch, DamienMcKenna, quicksketch: TypeError: preg_match_all():
+ Arg #2 ($subject) must be of type string, array given in preg_match_all().
+#3258358 by Eugene Bocharov, sashken2, DamienMcKenna, modernrockstar: Empty
+ values saved in 'mask_icon' meta tag.
+#3269670 by DamienMcKenna, sd123: Trimming even trims metatags shorter than the
+ limit.
+#3269742 by DamienMcKenna, z3cka: Migrate D7 Product Display node metatag data
+ to D9 Drupal Commerce Product entities.
+#3280904 by DamienMcKenna, 3li: Automatic conversion of false to array is
+ deprecated.
+#3278924 by lamp5, DamienMcKenna: Translation of title metatag is limited to
+ 128 characters.
+#3271284 by Shashwat Purav: Double occurrences of word "the".
+#3257520 by er.garg.karan, DamienMcKenna: Default Drupal favicon icon on core
+ before 9.3.
+#3281987 by DamienMcKenna: Sort configuration items prior to saving.
+#3284465 by DamienMcKenna, murilohp: Deprecated obsolete meta
+ http-equiv="content-language".
+#3270951 by marciaibanez, tmaiochi, Guilherme Rabelo, chakkche, DamienMcKenna:
+ Coding standards improvements.
+#3112509 by DamienMcKenna, ciprian.stavovei, Renrhaf, sitiveni: Convert
+ "author" tag to HTML 5.2 spec, deprecate Google+ Author tag.
+#3280745 by DamienMcKenna, Anybody: Trimming should use multibyte functions.
+#3112509 by DamienMcKenna: Fix regression in Google+ tests.
+#2563655 by DamienMcKenna, waldomero: Absorb Metatag Routes module to allow
+ per-path/route configurations.
+#3268439 by chakkche, bygeoffthompson, DamienMcKenna, Ruturaj Chaubey: Optional
+ overflow control on expanded Metatag field widget.
+#3231981 by sanduhrs, DamienMcKenna: Add support for SIWECOS website security
+ scanner.
+#3198100 by thejimbirch, DamienMcKenna, sriharsha.uppuluri: Two Google meta tags
+ conflict with each other.
+#3077442 by daniel.bosen, DamienMcKenna, esdrasterrero, Vivek Panicker,
+ Supreetam09, rigoucr: Current language through the language manager doesn't
+ work (decoupled site).
+#3295569 by DamienMcKenna: 8.x-1.x tests fail against PHP 7.3.
+
+
Metatag 8.x-1.19, 2022-01-06
----------------------------
#3104170 by DamienMcKenna, tobiasb, marcoliver, hosterholz, Berdir: Do not send
diff --git a/frontend/drupal9/web/modules/contrib/metatag/README.md b/frontend/drupal9/web/modules/contrib/metatag/README.md
index aa178116d..b16a888ff 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/README.md
+++ b/frontend/drupal9/web/modules/contrib/metatag/README.md
@@ -21,7 +21,6 @@ Metatag for Drupal 9 requires the following:
* [Token](https://www.drupal.org/project/token): Provides a popup browser to
see the available tokens for use in meta tag fields.
-
## Features
The primary features include:
@@ -36,6 +35,9 @@ The primary features include:
tags, site verification tags and more; all but the basic meta tags are kept
in separate submodules.
+* Configuration can be added for individual paths using the Metatag Custom
+ Routes submodule.
+
* The fifteen Dublin Core Basic Element Set 1.1 meta tags may be added by
enabling the "Metatag: Dublin Core" submodule.
diff --git a/frontend/drupal9/web/modules/contrib/metatag/config/schema/metatag.metatag_tag.schema.yml b/frontend/drupal9/web/modules/contrib/metatag/config/schema/metatag.metatag_tag.schema.yml
index 8ad5e98cc..bc6555702 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/config/schema/metatag.metatag_tag.schema.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/config/schema/metatag.metatag_tag.schema.yml
@@ -69,7 +69,7 @@ metatag.metatag_tag.standout:
type: label
label: 'Standout'
metatag.metatag_tag.title:
- type: label
+ type: text
label: 'Page title'
metatag.metatag_tag.icbm:
type: label
@@ -89,3 +89,6 @@ metatag.metatag_tag.set_cookie:
metatag.metatag_tag.google:
type: label
label: 'Google'
+metatag.metatag_tag.author:
+ type: label
+ label: 'Author'
diff --git a/frontend/drupal9/web/modules/contrib/metatag/config/schema/metatag.settings.schema.yml b/frontend/drupal9/web/modules/contrib/metatag/config/schema/metatag.settings.schema.yml
index 97d74ae8d..645608228 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/config/schema/metatag.settings.schema.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/config/schema/metatag.settings.schema.yml
@@ -23,3 +23,6 @@ metatag.settings:
sequence:
type: integer
label: 'Tag maximum length in characters'
+ tag_scroll_max_height:
+ type: string
+ label: 'Add max height value'
diff --git a/frontend/drupal9/web/modules/contrib/metatag/css/firehose_widget.css b/frontend/drupal9/web/modules/contrib/metatag/css/firehose_widget.css
new file mode 100644
index 000000000..c601bce58
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/metatag/css/firehose_widget.css
@@ -0,0 +1,9 @@
+/**
+ * @file
+ * Custom CSS for the Firehose widget.
+ */
+
+.metatags {
+ max-height: 500px;
+ overflow-y: overlay;
+}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag.info.yml
index 64ce8e22a..aab4eb2b3 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag.info.yml
@@ -10,7 +10,7 @@ dependencies:
test_dependencies:
- devel:devel
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag.install b/frontend/drupal9/web/modules/contrib/metatag/metatag.install
index ef2b19830..55b08764c 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag.install
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag.install
@@ -91,6 +91,7 @@ function metatag_update_8109(&$sandbox) {
$field_counter = 0;
// Get all of the field storage entities of type metatag.
+ /** @var \Drupal\field\FieldStorageConfigInterface[] $field_storage_configs */
$field_storage_configs = \Drupal::entityTypeManager()
->getStorage('field_storage_config')
->loadByProperties(['type' => 'metatag']);
@@ -101,7 +102,10 @@ function metatag_update_8109(&$sandbox) {
// Get the individual fields (field instances) associated with bundles.
$fields = \Drupal::entityTypeManager()
->getStorage('field_config')
- ->loadByProperties(['field_name' => $field_name]);
+ ->loadByProperties([
+ 'field_name' => $field_name,
+ 'entity_type' => $field_storage->getTargetEntityTypeId(),
+ ]);
foreach ($fields as $field) {
// Get the bundle this field is attached to.
@@ -157,30 +161,27 @@ function metatag_update_8109(&$sandbox) {
$field_value_field = $sandbox['fields'][$current_field]['field_value_field'];
// Loop through the field(s) and update the mask_icon values if necessary.
- while ($counter <= $max_per_batch) {
- if (isset($current_field_records[$current_record])) {
- $record = $current_field_records[$current_record];
+ while ($counter <= $max_per_batch && isset($current_field_records[$current_record])) {
+ $record = $current_field_records[$current_record];
- // Strip any empty tags or ones matching the field's defaults and leave
- // only the overridden tags in $new_tags.
- $tags = unserialize($record->$field_value_field);
- if (isset($tags['mask-icon'])) {
- $tags['mask_icon'] = [
- 'href' => $tags['mask-icon'],
- ];
+ // Strip any empty tags or ones matching the field's defaults and leave
+ // only the overridden tags in $new_tags.
+ $tags = unserialize($record->$field_value_field, ['allowed_classes' => FALSE]);
+ if (isset($tags['mask-icon'])) {
+ $tags['mask_icon'] = [
+ 'href' => $tags['mask-icon'],
+ ];
- $tags_string = serialize($tags);
- \Drupal::database()->update($field_table)
- ->fields([
- $field_value_field => $tags_string,
- ])
- ->condition('entity_id', $record->entity_id)
- ->condition('revision_id', $record->revision_id)
- ->condition('langcode', $record->langcode)
- ->execute();
- }
+ $tags_string = serialize($tags);
+ \Drupal::database()->update($field_table)
+ ->fields([
+ $field_value_field => $tags_string,
+ ])
+ ->condition('entity_id', $record->entity_id)
+ ->condition('revision_id', $record->revision_id)
+ ->condition('langcode', $record->langcode)
+ ->execute();
}
-
$counter++;
$current_record++;
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag.libraries.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag.libraries.yml
new file mode 100644
index 000000000..6db3adf4b
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag.libraries.yml
@@ -0,0 +1,6 @@
+# Custom libraries for the Metatag module.
+
+firehose_widget:
+ css:
+ theme:
+ css/firehose_widget.css: {}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag.module b/frontend/drupal9/web/modules/contrib/metatag/metatag.module
index 1c7e66cf3..11efd0b2c 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag.module
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag.module
@@ -5,8 +5,8 @@
* Contains metatag.module.
*/
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Component\Plugin\Factory\DefaultFactory;
-use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
@@ -26,8 +26,8 @@ use Drupal\taxonomy\Plugin\migrate\source\d7\Term as Term7;
use Drupal\taxonomy\TermInterface;
use Drupal\user\Plugin\migrate\source\d6\User as User6;
use Drupal\user\Plugin\migrate\source\d7\User as User7;
-use Drupal\Core\Render\HtmlResponseAttachmentsProcessor;
use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\commerce_migrate_commerce\Plugin\migrate\source\commerce1\ProductDisplay;
/**
* Implements hook_help().
@@ -143,7 +143,6 @@ function metatag_page_attachments(array &$attachments) {
$attachments['#attached']['html_head'] = [];
}
- $head_links = [];
foreach ($metatag_attachments['#attached']['html_head'] as $item) {
// Do not attach a title meta tag as this unnecessarily duplicates the
// title tag.
@@ -153,32 +152,6 @@ function metatag_page_attachments(array &$attachments) {
}
$attachments['#attached']['html_head'][] = $item;
-
- // Also add a HTTP header "Link:" for canonical URLs and shortlinks.
- // See HtmlResponseAttachmentsProcessor::processHtmlHeadLink() for the
- // implementation of the functionality in core.
- if (isset($item[0]['#attributes']['href'])) {
- if (in_array($item[1], ['canonical_url', 'shortlink'])) {
- $attributes = $item[0]['#attributes'];
-
- $href = '<' . Html::escape($attributes['href']) . '>';
- unset($attributes['href']);
- $param = HtmlResponseAttachmentsProcessor::formatHttpHeaderAttributes($attributes);
- if (!empty($param)) {
- $href .= ';' . $param;
- }
- $head_links[] = $href;
- }
- }
- }
-
- // If any HTTP Header items were found, add them too.
- if (!empty($head_links)) {
- $attachments['#attached']['http_header'][] = [
- 'Link',
- implode(', ', $head_links),
- FALSE,
- ];
}
}
}
@@ -301,11 +274,12 @@ function _metatag_remove_duplicate_entity_tags(array &$build) {
// Check to see if the page currently outputs a canonical and/or shortlink
// tag.
if (isset($metatag_attachments['#attached']['html_head'])) {
+ $tags_to_look_for = ['canonical', 'shortlink'];
foreach ($metatag_attachments['#attached']['html_head'] as $metatag_item) {
if (in_array($metatag_item[1], ['canonical_url', 'shortlink'])) {
// Metatag provides rel="canonical" and/or rel="shortlink" tags.
foreach ($build['#attached']['html_head_link'] as $key => $item) {
- if (isset($item[0]['rel']) && in_array($item[0]['rel'], ['canonical', 'shortlink'])) {
+ if (isset($item[0]['rel']) && in_array($item[0]['rel'], $tags_to_look_for)) {
// Remove the link rel="canonical" or link rel="shortlink" tag
// from the entity's build array.
unset($build['#attached']['html_head_link'][$key]);
@@ -348,13 +322,18 @@ function metatag_is_current_route_supported() {
/**
* Returns the entity of the current route.
*
- * @return Drupal\Core\Entity\EntityInterface
+ * @return Drupal\Core\Entity\EntityInterface|null
* The entity or NULL if this is not an entity route.
*/
function metatag_get_route_entity() {
$route_match = \Drupal::routeMatch();
$route_name = $route_match->getRouteName();
+ // In certain circumstances the route can be empty.
+ if (is_null($route_name)) {
+ return NULL;
+ }
+
// Look for a canonical entity view page, e.g. node/{nid}, user/{uid}, etc.
$matches = [];
preg_match('/entity\.(.*)\.(latest[_-]version|canonical)/', $route_name, $matches);
@@ -732,6 +711,11 @@ function metatag_migrate_prepare_row(Row $row, MigrateSourceInterface $source, M
// E.g. d7_user.
$source_type = 'user';
}
+ // Custom handling for Drupal Commerce.
+ elseif (\Drupal::moduleHandler()->moduleExists('commerce_migrate_commerce') && is_a($source, ProductDisplay::class)) {
+ // Products were nodes in Drupal 7 so map the $source_type to node.
+ $source_type = 'node';
+ }
else {
// Not supported now, nothing to do.
return;
@@ -808,24 +792,31 @@ function metatag_migrate_prepare_row(Row $row, MigrateSourceInterface $source, M
// @todo Write a more general version rather than a switch statement.
switch ($source_type) {
case 'node':
- // define('NODEWORDS_TYPE_NODE', 5);
+ // @code
+ // define('NODEWORDS_TYPE_NODE', 5);
+ // @endcode
$nodeword_type = 5;
$entity_id = $row->getSourceProperty('nid');
break;
case 'taxonomy_term':
- // define('NODEWORDS_TYPE_TERM', 6);
+ // @code
+ // define('NODEWORDS_TYPE_TERM', 6);
+ // @endcode
$nodeword_type = 6;
$entity_id = $row->getSourceProperty('tid');
break;
case 'user':
- // define('NODEWORDS_TYPE_USER', 8);
+ // @code
+ // define('NODEWORDS_TYPE_USER', 8);
+ // @endcode
$nodeword_type = 8;
$entity_id = $row->getSourceProperty('uid');
break;
}
- // @todo
+ // @todo Migrate these configuration items.
+ // @code
// define('NODEWORDS_TYPE_BLOG', 13);
// define('NODEWORDS_TYPE_DEFAULT', 1);
// define('NODEWORDS_TYPE_ERRORPAGE', 2);
@@ -837,7 +828,7 @@ function metatag_migrate_prepare_row(Row $row, MigrateSourceInterface $source, M
// define('NODEWORDS_TYPE_PAGER', 4);
// define('NODEWORDS_TYPE_TRACKER', 7);
// define('NODEWORDS_TYPE_VOCABULARY', 9);
-
+ // @endcode
/** @var \Drupal\migrate\Plugin\migrate\source\SqlBase $source */
/** @var \Drupal\Core\Database\Query\SelectInterface $query */
$query = $source->getDatabase()->select('nodewords', 'nw')
@@ -847,7 +838,7 @@ function metatag_migrate_prepare_row(Row $row, MigrateSourceInterface $source, M
->orderBy('nw.name');
$value = $query->execute()->fetchAllKeyed();
- $row->setSourceProperty('pseudo_metatag_entities', $value);
+ $row->setSourceProperty('pseudo_metatag_entities', $value);
}
}
}
@@ -1001,7 +992,7 @@ function _metatag_is_migration_plugin_supported(array $definition) {
return FALSE;
}
}
- catch (\Drupal\Component\Plugin\Exception\PluginNotFoundException $e) {
+ catch (PluginNotFoundException $e) {
// If the entity type doesn't exist, neither with the migration plugin.
return FALSE;
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag.post_update.php b/frontend/drupal9/web/modules/contrib/metatag/metatag.post_update.php
index ba9beeb64..641c77c14 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag.post_update.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag.post_update.php
@@ -26,3 +26,160 @@ function metatag_post_update_convert_mask_icon_to_array_values(&$sandbox) {
return FALSE;
});
}
+
+/**
+ * The author meta tag was moved into the main module: configuration.
+ */
+function metatag_post_update_convert_author_config(&$sandbox) {
+ $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class);
+ $config_entity_updater->update($sandbox, 'metatag_defaults', function (MetatagDefaults $metatag_defaults) {
+ if ($metatag_defaults->hasTag('google_plus_author')) {
+ $tags = $metatag_defaults->get('tags');
+ $tags['author'] = $metatag_defaults->getTag('google_plus_author');
+ unset($tags['google_plus_author']);
+ $metatag_defaults->set('tags', $tags);
+ return TRUE;
+ }
+ return FALSE;
+ });
+}
+
+/**
+ * The author meta tag was moved into the main module: entity data.
+ */
+function metatag_post_update_convert_author_data(&$sandbox) {
+ // This whole top section only needs to be done the first time.
+ if (!isset($sandbox['records_processed'])) {
+ $sandbox['records_processed'] = 0;
+ $sandbox['total_records'] = 0;
+ $sandbox['current_field'] = 0;
+ $sandbox['current_record'] = 0;
+
+ // Counter to enumerate the fields so we can access them in the array
+ // by number rather than name.
+ $field_counter = 0;
+
+ // Get all of the field storage entities of type metatag.
+ /** @var \Drupal\field\FieldStorageConfigInterface[] $field_storage_configs */
+ $field_storage_configs = \Drupal::entityTypeManager()
+ ->getStorage('field_storage_config')
+ ->loadByProperties(['type' => 'metatag']);
+
+ foreach ($field_storage_configs as $field_storage) {
+ $field_name = $field_storage->getName();
+
+ // Get the individual fields (field instances) associated with bundles.
+ $fields = \Drupal::entityTypeManager()
+ ->getStorage('field_config')
+ ->loadByProperties([
+ 'field_name' => $field_name,
+ 'entity_type' => $field_storage->getTargetEntityTypeId(),
+ ]);
+
+ foreach ($fields as $field) {
+ // Get the bundle this field is attached to.
+ $bundle = $field->getTargetBundle();
+
+ // Determine the table and "value" field names.
+ $table_mapping = Drupal::entityTypeManager()
+ ->getStorage($field->getTargetEntityTypeId())
+ ->getTableMapping();
+ $field_table = $table_mapping->getFieldTableName($field_name);
+ $field_value_field = $table_mapping->getFieldColumnName($field_storage, 'value');
+
+ // Get all records where the field data does not match the default.
+ $query = \Drupal::database()->select($field_table);
+ $query->addField($field_table, 'entity_id');
+ $query->addField($field_table, 'revision_id');
+ $query->addField($field_table, 'langcode');
+ $query->addField($field_table, $field_value_field);
+ $query->condition('bundle', $bundle, '=');
+ $result = $query->execute();
+ $records = $result->fetchAll();
+
+ if (empty($records)) {
+ continue;
+ }
+
+ // Fill in all the sandbox information so we can batch the individual
+ // record comparing and updating.
+ $sandbox['fields'][$field_counter]['field_table'] = $field_table;
+ $sandbox['fields'][$field_counter]['field_value_field'] = $field_value_field;
+ $sandbox['fields'][$field_counter]['records'] = $records;
+
+ $sandbox['total_records'] += count($sandbox['fields'][$field_counter]['records'] = $records);
+ $field_counter++;
+ }
+ }
+ }
+
+ if ($sandbox['total_records'] == 0) {
+ // No partially overridden fields so we can skip the whole batch process.
+ $sandbox['#finished'] = 1;
+ }
+ else {
+ // Begin the batch processing of individual field records.
+ $max_per_batch = 10;
+ $counter = 1;
+
+ $current_field = $sandbox['current_field'];
+ $current_field_records = $sandbox['fields'][$current_field]['records'];
+ $current_record = $sandbox['current_record'];
+
+ $field_table = $sandbox['fields'][$current_field]['field_table'];
+ $field_value_field = $sandbox['fields'][$current_field]['field_value_field'];
+
+ // Loop through the field(s) and update the mask_icon values if necessary.
+ while ($counter <= $max_per_batch && isset($current_field_records[$current_record])) {
+ $record = $current_field_records[$current_record];
+
+ // Strip any empty tags or ones matching the field's defaults and leave
+ // only the overridden tags in $new_tags.
+ $tags = unserialize($record->$field_value_field);
+ if (isset($tags['google_plus_author'])) {
+ $tags['author'] = $tags['google_plus_author'];
+ $tags_string = serialize($tags);
+ \Drupal::database()->update($field_table)
+ ->fields([
+ $field_value_field => $tags_string,
+ ])
+ ->condition('entity_id', $record->entity_id)
+ ->condition('revision_id', $record->revision_id)
+ ->condition('langcode', $record->langcode)
+ ->execute();
+ }
+ $counter++;
+ $current_record++;
+ }
+
+ // We ran out of records for the field so start the next batch out with the
+ // next field.
+ if (!isset($current_field_records[$current_record])) {
+ $current_field++;
+ $current_record = 0;
+ }
+
+ // We have finished all the fields. All done.
+ if (!isset($sandbox['fields'][$current_field])) {
+ $sandbox['records_processed'] += $counter - 1;
+ $sandbox['#finished'] = 1;
+ }
+ // Update the sandbox values to prepare for the next round.
+ else {
+ $sandbox['current_field'] = $current_field;
+ $sandbox['current_record'] = $current_record;
+ $sandbox['records_processed'] += $counter - 1;
+ $sandbox['#finished'] = $sandbox['records_processed'] / $sandbox['total_records'];
+ }
+ }
+
+ if ($sandbox['total_records'] > 0) {
+ return (string) t('Processed @processed of @total overridden Metatag records.', [
+ '@processed' => $sandbox['records_processed'],
+ '@total' => $sandbox['total_records'],
+ ]);
+ }
+ else {
+ return (string) t("There were no overridden Metatag records.");
+ }
+}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag.services.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag.services.yml
index 81504131f..9a0c9cfcf 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag.services.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag.services.yml
@@ -13,7 +13,7 @@ services:
metatag.manager:
class: Drupal\metatag\MetatagManager
- arguments: ['@plugin.manager.metatag.group', '@plugin.manager.metatag.tag', '@metatag.token', '@logger.factory', '@entity_type.manager']
+ arguments: ['@plugin.manager.metatag.group', '@plugin.manager.metatag.tag', '@metatag.token', '@logger.factory', '@entity_type.manager', '@path.matcher', '@current_route_match', '@request_stack', '@language_manager']
metatag.trimmer:
class: Drupal\metatag\MetatagTrimmer
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag.tokens.inc b/frontend/drupal9/web/modules/contrib/metatag/metatag.tokens.inc
index 1ec124d4e..9ababdc29 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag.tokens.inc
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag.tokens.inc
@@ -208,7 +208,7 @@ function metatag_tokens($type, $tokens, array $data, array $options, BubbleableM
// For [metatag:tag_name:0], [metatag:tag_name:0:value] and
// [metatag:tag_name:value] tokens.
else {
- list($tag_name, $delta) = explode(':', $name, 2);
+ [$tag_name, $delta] = explode(':', $name, 2);
if (!is_numeric($delta)) {
unset($delta);
}
@@ -227,7 +227,7 @@ function metatag_tokens($type, $tokens, array $data, array $options, BubbleableM
}
else {
if (is_array($processed_tags[$tag_name])) {
- $replacements[$original] = implode(',', $processed_tags[$tag_name]);
+ $replacements[$original] = implode(',', array_filter($processed_tags[$tag_name]));
}
else {
$replacements[$original] = $processed_tags[$tag_name];
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_app_links/metatag_app_links.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_app_links/metatag_app_links.info.yml
index 6e726838f..5b973e1a8 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_app_links/metatag_app_links.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_app_links/metatag_app_links.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_dc/config/schema/metatag_dc.metatag_tag.schema.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_dc/config/schema/metatag_dc.metatag_tag.schema.yml
index afda126fb..a6e1255e0 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_dc/config/schema/metatag_dc.metatag_tag.schema.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_dc/config/schema/metatag_dc.metatag_tag.schema.yml
@@ -42,7 +42,7 @@ metatag.metatag_tag.dcterms_subject:
type: label
label: 'Dublin Core: Subject'
metatag.metatag_tag.dcterms_title:
- type: label
+ type: text
label: 'Dublin Core: Title'
metatag.metatag_tag.dcterms_type:
type: label
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_dc/metatag_dc.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_dc/metatag_dc.info.yml
index af56ed981..4239455f5 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_dc/metatag_dc.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_dc/metatag_dc.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_dc_advanced/metatag_dc_advanced.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_dc_advanced/metatag_dc_advanced.info.yml
index ffdc46d5a..90f6bc055 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_dc_advanced/metatag_dc_advanced.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_dc_advanced/metatag_dc_advanced.info.yml
@@ -7,7 +7,7 @@ dependencies:
- metatag:metatag
- metatag:metatag_dc
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_extended_perms/metatag_extended_perms.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_extended_perms/metatag_extended_perms.info.yml
index be84dd8a0..3ddc228e5 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_extended_perms/metatag_extended_perms.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_extended_perms/metatag_extended_perms.info.yml
@@ -4,9 +4,9 @@ description: "Adds individual permissions for each meta tag, allowing for fine-g
core_version_requirement: '^9'
package: SEO
dependencies:
- - metatag
+ - metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_extended_perms/tests/src/Functional/PermissionsTest.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_extended_perms/tests/src/Functional/PermissionsTest.php
index 153a112ed..1380fc710 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_extended_perms/tests/src/Functional/PermissionsTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_extended_perms/tests/src/Functional/PermissionsTest.php
@@ -70,11 +70,13 @@ class PermissionsTest extends BrowserTestBase {
'revisit_after' => 'Revisit After',
'rights' => 'Rights',
// This one is more complicated, so skip it.
+ // @code
// 'robots' => 'Robots',
+ // @endcode
'set_cookie' => 'Set cookie',
'shortlink' => 'Shortlink URL',
'standout' => 'Standout',
- ]
+ ],
];
/**
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_facebook/metatag_facebook.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_facebook/metatag_facebook.info.yml
index 147b8b8ed..146253402 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_facebook/metatag_facebook.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_facebook/metatag_facebook.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/metatag_favicons.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/metatag_favicons.info.yml
index a2b7651d1..c0229bf46 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/metatag_favicons.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/metatag_favicons.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/metatag_favicons.module b/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/metatag_favicons.module
index c816e8e9a..25035109a 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/metatag_favicons.module
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/metatag_favicons.module
@@ -34,10 +34,11 @@ function metatag_favicons_page_attachments_alter(array &$attachments) {
}
// Remove the default shortcut icon if one was set by Metatag.
+ $valid_meta_tags = ['shortcut icon', 'shortcut_icon', 'icon'];
foreach ($attachments['#attached']['html_head'] as $element) {
- if (isset($element[1]) && in_array($element[1], ['shortcut_icon', 'icon'])) {
+ if (isset($element[1]) && in_array($element[1], $valid_meta_tags)) {
foreach ($attachments['#attached']['html_head_link'] as $key => $value) {
- if (isset($value[0]['rel']) && in_array($value[0]['rel'], ['shortcut_icon', 'icon'])) {
+ if (isset($value[0]['rel']) && in_array($value[0]['rel'], $valid_meta_tags)) {
unset($attachments['#attached']['html_head_link'][$key]);
}
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/src/Plugin/metatag/Tag/MaskIcon.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/src/Plugin/metatag/Tag/MaskIcon.php
index d8f6785f3..630b83cdb 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/src/Plugin/metatag/Tag/MaskIcon.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_favicons/src/Plugin/metatag/Tag/MaskIcon.php
@@ -41,9 +41,9 @@ class MaskIcon extends LinkRelBase {
$form['href'] = [
'#type' => 'textfield',
'#title' => $this->label(),
- '#default_value' => isset($defaults['href']) ? $defaults['href'] : '',
+ '#default_value' => $defaults['href'] ?? '',
'#maxlength' => 255,
- '#required' => isset($element['#required']) ? $element['#required'] : FALSE,
+ '#required' => $element['#required'] ?? FALSE,
'#description' => $this->description(),
'#element_validate' => [[get_class($this), 'validateTag']],
];
@@ -52,7 +52,7 @@ class MaskIcon extends LinkRelBase {
$form['color'] = [
'#type' => 'textfield',
'#title' => $this->t('Mask icon color'),
- '#default_value' => isset($defaults['color']) ? $defaults['color'] : '',
+ '#default_value' => $defaults['color'] ?? '',
'#required' => FALSE,
'#description' => $this->t("Color attribute for SVG (mask) icon in hexadecimal format, e.g. '#0000ff'. Setting it will break HTML validation. If not set macOS Safari ignores the Mask Icon entirely, making the Icon: SVG completely useless."),
];
@@ -81,4 +81,12 @@ class MaskIcon extends LinkRelBase {
return $element;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function setValue($value) {
+ // Do not store array with empty values.
+ $this->value = is_array($value) && empty(array_filter($value)) ? NULL : $value;
+ }
+
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_google_cse/metatag_google_cse.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_google_cse/metatag_google_cse.info.yml
index d30f1aaf6..41a532710 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_google_cse/metatag_google_cse.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_google_cse/metatag_google_cse.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_google_plus/metatag_google_plus.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_google_plus/metatag_google_plus.info.yml
index 27380b9be..689b5de53 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_google_plus/metatag_google_plus.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_google_plus/metatag_google_plus.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_google_plus/src/Plugin/metatag/Tag/Author.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_google_plus/src/Plugin/metatag/Tag/Author.php
index 2cbfa3ada..4fb9b6cf3 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_google_plus/src/Plugin/metatag/Tag/Author.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_google_plus/src/Plugin/metatag/Tag/Author.php
@@ -10,7 +10,7 @@ use Drupal\metatag\Plugin\metatag\Tag\LinkRelBase;
* @MetatagTag(
* id = "google_plus_author",
* label = @Translation("Author"),
- * description = @Translation("Used by some search engines to confirm authorship of the content on a page. Should be either the full URL for the author's Google+ profile page or a local page with information about the author."),
+ * description = @Translation("DEPRECATED, use Advanced-Author instead."),
* name = "author",
* group = "google_plus",
* weight = 4,
@@ -18,6 +18,10 @@ use Drupal\metatag\Plugin\metatag\Tag\LinkRelBase;
* secure = FALSE,
* multiple = FALSE
* )
+ *
+ * @deprecated in metatag:8.x-1.20 and is removed from metatag:2.0.0. No replacement is provided.
+ *
+ * @see https://www.drupal.org/project/metatag/issues/3284464
*/
class Author extends LinkRelBase {
// Nothing here yet. Just a placeholder class for a plugin.
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_hreflang/metatag_hreflang.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_hreflang/metatag_hreflang.info.yml
index 85eb1f0ae..30abb7ac4 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_hreflang/metatag_hreflang.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_hreflang/metatag_hreflang.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_hreflang/metatag_hreflang.module b/frontend/drupal9/web/modules/contrib/metatag/metatag_hreflang/metatag_hreflang.module
index dcb75d0f2..fe3a46bf0 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_hreflang/metatag_hreflang.module
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_hreflang/metatag_hreflang.module
@@ -37,7 +37,7 @@ function metatag_hreflang_page_attachments_alter(array &$attachments) {
foreach ($attachments['#attached']['html_head'] as $element) {
// Check for Metatag's identifier "hreflang_per_language".
if (!empty($element[1])) {
- if (strpos($element[1], 'hreflang_per_language') !== false && isset($element[0]['#attributes']['hreflang'])) {
+ if (strpos($element[1], 'hreflang_per_language') !== FALSE && isset($element[0]['#attributes']['hreflang'])) {
$hreflang_per_language[] = $element[0]['#attributes']['hreflang'];
}
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_mobile/config/schema/metatag_mobile.metatag_tag.schema.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_mobile/config/schema/metatag_mobile.metatag_tag.schema.yml
index ef95ca6ea..a5bd38dd3 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_mobile/config/schema/metatag_mobile.metatag_tag.schema.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_mobile/config/schema/metatag_mobile.metatag_tag.schema.yml
@@ -21,7 +21,7 @@ metatag.metatag_tag.apple_mobile_web_app_status_bar_style:
type: label
label: 'Apple Mobile: Web App Status bar color'
metatag.metatag_tag.apple_mobile_web_app_title:
- type: label
+ type: text
label: 'Apple Mobile: Web App Title'
metatag.metatag_tag.application_name:
type: label
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_mobile/metatag_mobile.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_mobile/metatag_mobile.info.yml
index b2f1a67fd..83651c22c 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_mobile/metatag_mobile.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_mobile/metatag_mobile.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/config/schema/metatag_open_graph.metatag_tag.schema.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/config/schema/metatag_open_graph.metatag_tag.schema.yml
index 68bdff47f..6481f98e1 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/config/schema/metatag_open_graph.metatag_tag.schema.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/config/schema/metatag_open_graph.metatag_tag.schema.yml
@@ -114,7 +114,7 @@ metatag.metatag_tag.og_street_address:
type: label
label: 'Open Graph: Street address'
metatag.metatag_tag.og_title:
- type: label
+ type: text
label: 'Open Graph: Title'
metatag.metatag_tag.og_type:
type: label
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/metatag_open_graph.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/metatag_open_graph.info.yml
index 82982f516..2ea6da8e8 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/metatag_open_graph.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/metatag_open_graph.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/metatag_open_graph.install b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/metatag_open_graph.install
index a2856db16..f128ee50e 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/metatag_open_graph.install
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph/metatag_open_graph.install
@@ -16,7 +16,7 @@ use Drupal\metatag\Entity\MetatagDefaults;
* The "article:tags" meta tag was renamed to the correct "article:tag".
*/
function metatag_open_graph_update_8101() {
- /** @var $configs Drupal\metatag\Entity\MetatagDefaults */
+ /** @var Drupal\metatag\Entity\MetatagDefaults $configs */
$configs = MetatagDefaults::loadMultiple();
foreach ($configs as $config) {
@@ -72,7 +72,7 @@ function metatag_open_graph_update_8102(&$sandbox) {
foreach ($sandbox['todo'] as $entity_type => $fields) {
- /** @var $def Drupal\Core\Entity\ContentEntityType */
+ /** @var Drupal\Core\Entity\ContentEntityType $def */
$def = Drupal::entityTypeManager()->getDefinition($entity_type);
// Grab the primary key field for this entity type
@@ -95,7 +95,7 @@ function metatag_open_graph_update_8102(&$sandbox) {
$entities = $etm->getStorage($entity_type)->loadMultiple($res);
foreach ($entities as $entity) {
- /** @var $entity ContentEntityBase */
+ /** @var \Drupal\Core\Entity\ContentEntityBase $entity */
if ($entity instanceof ContentEntityBase) {
if ($entity->hasField($field_name)) {
/** @var LanguageInterface $langcode */
@@ -105,7 +105,7 @@ function metatag_open_graph_update_8102(&$sandbox) {
$tags_serialized = $trans->get($field_name)->value;
if ($tags_serialized) {
// Change key from article_tags to article_tag.
- $tags = unserialize($tags_serialized);
+ $tags = unserialize($tags_serialized, ['allowed_classes' => FALSE]);
if (array_key_exists("article_tags", $tags)) {
$tags['article_tag'] = $tags['article_tags'];
unset($tags['article_tags']);
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/metatag_open_graph_products.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/metatag_open_graph_products.info.yml
index a7e4a30bc..72c0bfc38 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/metatag_open_graph_products.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/metatag_open_graph_products.info.yml
@@ -7,7 +7,7 @@ dependencies:
- metatag:metatag
- metatag:metatag_open_graph
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductAvailability.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductAvailability.php
index 272720caa..f6ea6d9ea 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductAvailability.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductAvailability.php
@@ -22,5 +22,3 @@ use Drupal\metatag\Plugin\metatag\Tag\MetaPropertyBase;
class ProductAvailability extends MetaPropertyBase {
// Nothing here yet. Just a placeholder class for a plugin.
}
-
-
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductCondition.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductCondition.php
index d1e19d50f..ec5d626e7 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductCondition.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductCondition.php
@@ -22,5 +22,3 @@ use Drupal\metatag\Plugin\metatag\Tag\MetaPropertyBase;
class ProductCondition extends MetaPropertyBase {
// Nothing here yet. Just a placeholder class for a plugin.
}
-
-
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductRetailerItemId.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductRetailerItemId.php
index ee08bce65..90ad105f7 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductRetailerItemId.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_open_graph_products/src/Plugin/metatag/Tag/ProductRetailerItemId.php
@@ -22,4 +22,3 @@ use Drupal\metatag\Plugin\metatag\Tag\MetaPropertyBase;
class ProductRetailerItemId extends MetaPropertyBase {
// Nothing here yet. Just a placeholder class for a plugin.
}
-
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_page_manager/metatag_page_manager.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_page_manager/metatag_page_manager.info.yml
index 967166a36..e60d99335 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_page_manager/metatag_page_manager.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_page_manager/metatag_page_manager.info.yml
@@ -7,7 +7,7 @@ dependencies:
- page_manager:page_manager
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_page_manager/tests/src/Functional/MetatagPageManagerTest.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_page_manager/tests/src/Functional/MetatagPageManagerTest.txt
similarity index 99%
rename from frontend/drupal9/web/modules/contrib/metatag/metatag_page_manager/tests/src/Functional/MetatagPageManagerTest.php
rename to frontend/drupal9/web/modules/contrib/metatag/metatag_page_manager/tests/src/Functional/MetatagPageManagerTest.txt
index 02c464ca6..fa35a9411 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_page_manager/tests/src/Functional/MetatagPageManagerTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_page_manager/tests/src/Functional/MetatagPageManagerTest.txt
@@ -40,7 +40,7 @@ class MetatagPageManagerTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
- public function setUp() {
+ public function setUp(): void {
parent::setUp();
$this->assertSession = $this->assertSession();
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/metatag_pinterest.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/metatag_pinterest.info.yml
index 8eb46e1b5..67c1f0308 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/metatag_pinterest.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/metatag_pinterest.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNohover.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNohover.php
index f725e441a..1d7b29a0e 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNohover.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNohover.php
@@ -30,7 +30,7 @@ class PinterestNohover extends MetaNameBase {
'#title' => $this->label(),
'#description' => $this->description(),
'#default_value' => ($this->value === 'nohover') ?: '',
- '#required' => isset($element['#required']) ? $element['#required'] : FALSE,
+ '#required' => $element['#required'] ?? FALSE,
'#element_validate' => [[get_class($this), 'validateTag']],
'#return_value' => 'nohover',
];
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNopin.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNopin.php
index 5e0265340..362eb69d8 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNopin.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNopin.php
@@ -30,7 +30,7 @@ class PinterestNopin extends MetaNameBase {
'#title' => $this->label(),
'#description' => $this->description(),
'#default_value' => ($this->value === 'nopin') ?: '',
- '#required' => isset($element['#required']) ? $element['#required'] : FALSE,
+ '#required' => $element['#required'] ?? FALSE,
'#element_validate' => [[get_class($this), 'validateTag']],
'#return_value' => 'nopin',
];
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNosearch.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNosearch.php
index 9c0c9437b..714ed6881 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNosearch.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_pinterest/src/Plugin/metatag/Tag/PinterestNosearch.php
@@ -30,7 +30,7 @@ class PinterestNosearch extends MetaNameBase {
'#title' => $this->label(),
'#description' => $this->description(),
'#default_value' => ($this->value === 'nosearch') ?: '',
- '#required' => isset($element['#required']) ? $element['#required'] : FALSE,
+ '#required' => $element['#required'] ?? FALSE,
'#element_validate' => [[get_class($this), 'validateTag']],
'#return_value' => 'nosearch',
];
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/README.md b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/README.md
new file mode 100644
index 000000000..8181a453e
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/README.md
@@ -0,0 +1,25 @@
+# Metatag Routes
+
+The Metatag Routes module allows a user to configure metatags for custom
+controllers generated by code.
+
+It uses the metatags entity to store a configuration for any route using the
+metatags administration.
+
+The module adds a button in the default metatag dashboard page giving the user
+the option to enter the route path and validates if the path has a defined
+route, the route is not administrative and the route is "metatag-able".
+
+## Configuration
+
+1. Navigate to Administration > Extend and enable the module.
+2. Navigate to Administration > Configuration > Search and Metadata >
+ Metatag to configure metatags.
+3. Select "Add meta tag for custom route" and enter the path for which you
+ want to add the metatags.
+4. Submit.
+
+## Credits / contact
+
+Written by [Walter Velasquez (waldomero)](https://www.drupal.org/u/waldomero)
+and sponsored by [Globant](https://www.drupal.org/globant).
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.info.yml
new file mode 100644
index 000000000..9945fea8e
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.info.yml
@@ -0,0 +1,11 @@
+name: 'Metatag Custom Routes (Paths)'
+type: module
+description: Allows assigning meta tags to be used on custom routes, equivalent to customn paths.
+core_version_requirement: ^9
+dependencies:
+ - metatag:metatag
+
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
+project: 'metatag'
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.links.action.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.links.action.yml
new file mode 100644
index 000000000..99b259f3a
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.links.action.yml
@@ -0,0 +1,6 @@
+metatag_routes.create_custom_metatag.action:
+ route_name: metatag_routes.create
+ title: 'Add meta tag for custom route'
+ weight: 1
+ appears_on:
+ - entity.metatag_defaults.collection
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.module b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.module
new file mode 100644
index 000000000..6cf44ff86
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.module
@@ -0,0 +1,46 @@
+' . t('About') . '';
+ $output .= '' . t('Enables metatags for custom routes') . '
';
+ return $output;
+
+ default:
+ }
+}
+
+/**
+ * Implements hook_metatags_alter().
+ */
+function metatag_routes_metatags_alter(array &$metatags, array $context) {
+ // Ignore some system routes that are not approrpriate for meta tags.
+ if (metatag_is_current_route_supported()) {
+ // Look to see if a configuration was assigned for this route.
+ $current_route = \Drupal::routeMatch()->getRouteName();
+ if (!empty($current_route)) {
+ $defaults = \Drupal::entityTypeManager()
+ ->getStorage('metatag_defaults')
+ ->load($current_route);
+ if (!empty($defaults)) {
+ $tags = $defaults->get('tags');
+
+ // Replace the new values and keep on the global values.
+ $metatags = array_merge($metatags, $tags);
+ }
+ }
+ }
+}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.routing.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.routing.yml
new file mode 100644
index 000000000..13b8898de
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/metatag_routes.routing.yml
@@ -0,0 +1,9 @@
+metatag_routes.create:
+ path: '/admin/config/search/metatag/custom/create'
+ defaults:
+ _form: '\Drupal\metatag_routes\Form\MetatagCustomCreateForm'
+ _title: 'Add custom metatag'
+ requirements:
+ _permission: 'administer meta tags'
+ options:
+ _admin_route: TRUE
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/src/Form/MetatagCustomCreateForm.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/src/Form/MetatagCustomCreateForm.php
new file mode 100644
index 000000000..6ab77f597
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_routes/src/Form/MetatagCustomCreateForm.php
@@ -0,0 +1,194 @@
+entityTypeManager = $entity_type_manager;
+ $this->routeProvider = $route_provider;
+ $this->pathValidator = $path_validator;
+ $this->adminContext = $admin_context;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ return new static(
+ $container->get('entity_type.manager'),
+ $container->get('router.route_provider'),
+ $container->get('path.validator'),
+ $container->get('router.admin_context')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormId() {
+ return 'metatag_custom_create_form';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, FormStateInterface $form_state) {
+ $form['metatag_url'] = [
+ '#type' => 'textfield',
+ '#title' => $this->t('Route / Path'),
+ '#description' => $this->t('Enter the route (path) for this new configuration, starting with a leading slash.
Note: this must already exist as a path in Drupal.'),
+ '#maxlength' => 200,
+ '#required' => TRUE,
+ ];
+
+ $form['route_name'] = [
+ '#type' => 'hidden',
+ ];
+
+ $form['submit'] = [
+ '#type' => 'submit',
+ '#value' => $this->t('Submit'),
+ ];
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function validateForm(array &$form, FormStateInterface $form_state) {
+ parent::validateForm($form, $form_state);
+
+ // Get the path given by the user.
+ $url = trim($form_state->getValue('metatag_url'));
+
+ // Validate the url format.
+ if (strpos($url, '/') === FALSE) {
+ $form_state->setErrorByName('metatag_url', $this->t('The path must begin with /'));
+ return FALSE;
+ }
+
+ // Get route name from path.
+ $url_object = $this->pathValidator->getUrlIfValid($url);
+ if ($url_object) {
+ $route_name = $url_object->getRouteName();
+ $route_object = $this->routeProvider->getrouteByName($route_name);
+ // Avoid administrative routes to have metatags.
+ if ($this->adminContext->isAdminRoute($route_object)) {
+ $form_state->setErrorByName('metatag_url',
+ $this->t('The admin routes should not have metatags.'));
+ return FALSE;
+ }
+
+ // Avoid including entity routes.
+ $params = $url_object->getRouteParameters();
+ $entity_type = !empty($params) ? key($params) : NULL;
+ $entity_types = ['node', 'taxonomy_term', 'user'];
+ if (isset($entity_type) && in_array($entity_type, $entity_types)) {
+ $form_state->setErrorByName('metatag_url',
+ $this->t('The entities routes metatags must be added by fields. @entity_type - @id', [
+ '@entity_type' => $entity_type,
+ '@id' => $params[$entity_type],
+ ]));
+ return FALSE;
+ }
+
+ // Validate that the route doesn't have metatags created already.
+ $ids = $this->entityTypeManager->getStorage('metatag_defaults')->getQuery()->condition('id', $route_name)->execute();
+ if ($ids) {
+ $form_state->setErrorByName('metatag_url',
+ $this->t('There are already metatags created for this route.'));
+ return FALSE;
+ }
+ $form_state->setValue('route_name', $route_name);
+ }
+ else {
+ $form_state->setErrorByName('metatag_url', $this->t('The path does not exist as an internal Drupal route.'));
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, FormStateInterface $form_state) {
+ // Get values for form submission.
+ $route_name = $form_state->getValue('route_name');
+ $url = $form_state->getValue('metatag_url');
+ if ($route_name && $url) {
+ // Create the new metatag entity.
+ $entity = $this->entityTypeManager->getStorage('metatag_defaults')->create([
+ 'id' => $route_name,
+ 'label' => $url,
+ ]);
+ $entity->save();
+ $this->messenger()->addStatus($this->t('Created metatags for the path: @url. Internal route: @route.', [
+ '@url' => $url,
+ '@route' => $route_name,
+ ]));
+
+ // Redirect to metatag edit page.
+ $form_state->setRedirect('entity.metatag_defaults.edit_form', [
+ 'metatag_defaults' => $route_name,
+ ]);
+ }
+ else {
+ $this->messenger()->addError($this->t('The metatags could not be created for the path: @url.', [
+ '@url' => $url,
+ ]));
+
+ // Redirect to metatag edit page.
+ $form_state->setRedirect('entity.metatag_defaults.collection');
+ }
+ }
+
+}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/config/schema/metatag_twitter_cards.metatag_tag.schema.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/config/schema/metatag_twitter_cards.metatag_tag.schema.yml
index 78ce79f2f..19b3e68ac 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/config/schema/metatag_twitter_cards.metatag_tag.schema.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/config/schema/metatag_twitter_cards.metatag_tag.schema.yml
@@ -105,7 +105,7 @@ metatag.metatag_tag.twitter_cards_site_id:
type: label
label: "Twitter Cards: Site's Twitter account ID"
metatag.metatag_tag.twitter_cards_title:
- type: label
+ type: text
label: 'Twitter Cards: Title'
metatag.metatag_tag.twitter_cards_type:
type: label
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/metatag_twitter_cards.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/metatag_twitter_cards.info.yml
index 79185f0a0..414bdf90e 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/metatag_twitter_cards.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/metatag_twitter_cards.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/src/Plugin/metatag/Tag/TwitterCardsType.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/src/Plugin/metatag/Tag/TwitterCardsType.php
index eeeac57f1..34e128d59 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/src/Plugin/metatag/Tag/TwitterCardsType.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_twitter_cards/src/Plugin/metatag/Tag/TwitterCardsType.php
@@ -44,7 +44,7 @@ class TwitterCardsType extends MetaNameBase {
'#empty_option' => $this->t('- None -'),
'#empty_value' => '',
'#default_value' => $this->value(),
- '#required' => isset($element['#required']) ? $element['#required'] : FALSE,
+ '#required' => $element['#required'] ?? FALSE,
'#element_validate' => [[get_class($this), 'validateTag']],
];
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/config/schema/metatag_verification.metatag_tag.schema.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/config/schema/metatag_verification.metatag_tag.schema.yml
index 177592d88..711f8fe71 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/config/schema/metatag_verification.metatag_tag.schema.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/config/schema/metatag_verification.metatag_tag.schema.yml
@@ -14,7 +14,7 @@ metatag.metatag_tag.bing:
metatag.metatag_tag.facebook_domain_verification:
type: label
label: 'Site validation: Facebook'
-metatag.metatag_tag.google:
+metatag.metatag_tag.google_site_verification:
type: label
label: 'Site validation: Google'
metatag.metatag_tag.norton_safe_web:
@@ -26,6 +26,9 @@ metatag.metatag_tag.pinterest:
metatag.metatag_tag.pocket:
type: label
label: 'Site validation: Pocket'
+metatag.metatag_tag.siwecos:
+ type: label
+ label: 'Site validation: SIWECOS'
metatag.metatag_tag.yahoo:
type: label
label: 'Site validation: Yahoo'
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/metatag_verification.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/metatag_verification.info.yml
index e67e6a41c..a8fdffc7e 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/metatag_verification.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/metatag_verification.info.yml
@@ -6,7 +6,7 @@ package: SEO
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/src/Plugin/metatag/Tag/Google.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/src/Plugin/metatag/Tag/Google.php
index c57152d3a..6154dbe78 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/src/Plugin/metatag/Tag/Google.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/src/Plugin/metatag/Tag/Google.php
@@ -8,8 +8,8 @@ use Drupal\metatag\Plugin\metatag\Tag\MetaNameBase;
* Provides a plugin for the 'google-site-verification' meta tag.
*
* @MetatagTag(
- * id = "google",
- * label = @Translation("Google"),
+ * id = "google_site_verification",
+ * label = @Translation("Google Site Verification"),
* description = @Translation("A string provided by Google, full details are available from the Google online help.", arguments = { ":google" = "https://www.google.com/", ":verify_url" = "https://support.google.com/webmasters/answer/35179?hl=en" }),
* name = "google-site-verification",
* group = "site_verification",
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/src/Plugin/metatag/Tag/Siwecos.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/src/Plugin/metatag/Tag/Siwecos.php
new file mode 100644
index 000000000..bcf3181f7
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/src/Plugin/metatag/Tag/Siwecos.php
@@ -0,0 +1,23 @@
+SIWECOS, the free website security scanner.", arguments = {":siwecos" = "https://siwecos.de/"}),
+ * name = "siwecostoken",
+ * group = "site_verification",
+ * weight = 7,
+ * type = "label",
+ * secure = FALSE,
+ * multiple = FALSE
+ * )
+ */
+class Siwecos extends MetaNameBase {
+}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/tests/src/Functional/MetatagVerificationTagsTest.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/tests/src/Functional/MetatagVerificationTagsTest.php
index 9e01deb5d..fe823c56b 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/tests/src/Functional/MetatagVerificationTagsTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_verification/tests/src/Functional/MetatagVerificationTagsTest.php
@@ -25,10 +25,11 @@ class MetatagVerificationTagsTest extends MetatagTagsTestBase {
'baidu',
'bing',
'facebook_domain_verification',
- 'google',
+ 'google_site_verification',
'norton_safe_web',
'pinterest',
'pocket',
+ 'siwecos',
'yandex',
'zoom_domain_verification',
];
@@ -46,7 +47,7 @@ class MetatagVerificationTagsTest extends MetatagTagsTestBase {
elseif ($tag_name == 'facebook_domain_verification') {
$tag_name = 'facebook-domain-verification';
}
- elseif ($tag_name == 'google') {
+ elseif ($tag_name == 'google_site_verification') {
$tag_name = 'google-site-verification';
}
elseif ($tag_name == 'norton_safe_web') {
@@ -58,6 +59,9 @@ class MetatagVerificationTagsTest extends MetatagTagsTestBase {
elseif ($tag_name == 'pocket') {
$tag_name = 'pocket-site-verification';
}
+ elseif ($tag_name == 'siwecos') {
+ $tag_name = 'siwecostoken';
+ }
elseif ($tag_name == 'yandex') {
$tag_name = 'yandex-verification';
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/config/schema/metatag_views.views.schema.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/config/schema/metatag_views.views.schema.yml
index b98db8cad..e4e3eb23e 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/config/schema/metatag_views.views.schema.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/config/schema/metatag_views.views.schema.yml
@@ -6,3 +6,6 @@ views.display_extender.metatag_display_extender:
label: 'Metatags'
sequence:
type: metatag.metatag_tag.[%key]
+ tokenize:
+ type: boolean
+ label: 'Should replacement tokens be used from the first row'
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/metatag_views.info.yml b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/metatag_views.info.yml
index 5b692a10a..d15b68c2a 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/metatag_views.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/metatag_views.info.yml
@@ -7,7 +7,7 @@ dependencies:
- metatag:metatag
- drupal:views
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/metatag_views.module b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/metatag_views.module
index ca09116be..3f293c62e 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/metatag_views.module
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/metatag_views.module
@@ -5,7 +5,6 @@
* Contains hook implementations for the metatag_views module.
*/
-use Drupal\Core\Cache\Cache;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\metatag_views\MetatagViewsCacheWrapper;
use Drupal\metatag_views\Plugin\views\display_extender\MetatagDisplayExtender;
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Controller/MetatagViewsController.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Controller/MetatagViewsController.php
index 2ddf0b824..d67cfc376 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Controller/MetatagViewsController.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Controller/MetatagViewsController.php
@@ -10,7 +10,7 @@ use Drupal\views\Views;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
- * Class MetatagViewsController.
+ * Controller for managing the Views integration.
*
* @package Drupal\metatag_views\Controller
*/
@@ -101,7 +101,7 @@ class MetatagViewsController extends ControllerBase {
foreach ($tagged_views as $view_id => $displays) {
$elements[$view_id] = [
'#type' => 'details',
- '#title' => $this->t($this->viewLabels[$view_id]['#label']),
+ '#title' => $this->t(':label', [':label' => $this->viewLabels[$view_id]['#label']]),
'details' => $this->buildViewDetails($view_id, $displays),
];
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Controller/MetatagViewsTranslationController.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Controller/MetatagViewsTranslationController.php
index cf2314278..d1f8670b9 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Controller/MetatagViewsTranslationController.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Controller/MetatagViewsTranslationController.php
@@ -36,7 +36,7 @@ class MetatagViewsTranslationController extends ControllerBase {
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
-
+
/**
* The request stack.
*
@@ -161,9 +161,9 @@ class MetatagViewsTranslationController extends ControllerBase {
'#links' => $operations,
// Even if the mapper contains multiple language codes, the source
// configuration can still be edited.
- // {@code}
+ // @code
// '#access' => ($langcode == $original_langcode) || $operations_access,
- // {@endcode}
+ // @endcode
];
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Form/MetatagViewsAddForm.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Form/MetatagViewsAddForm.php
index 476293df9..b46d93b0d 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Form/MetatagViewsAddForm.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Form/MetatagViewsAddForm.php
@@ -7,7 +7,7 @@ use Drupal\metatag_views\Controller\MetatagViewsController;
use Drupal\views\Views;
/**
- * Class MetatagViewsAddForm.
+ * The add form for the Metatag field, which extends the edit form.
*
* @package Drupal\metatag_views\Form
*/
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Form/MetatagViewsEditForm.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Form/MetatagViewsEditForm.php
index 59ddb01dc..d78dfba68 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Form/MetatagViewsEditForm.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Form/MetatagViewsEditForm.php
@@ -10,7 +10,7 @@ use Drupal\metatag_views\MetatagViewsValuesCleanerTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
- * Class MetatagViewsEditForm.
+ * The edit form for the Metatag field.
*
* @package Drupal\metatag_views\Form
*/
@@ -139,7 +139,7 @@ class MetatagViewsEditForm extends FormBase {
$tag = $this->tagPluginManager->createInstance($tag_id);
// Set the value to the stored value, if any.
- $tag_value = isset($values[$tag_id]) ? $values[$tag_id] : NULL;
+ $tag_value = $values[$tag_id] ?? NULL;
$tag->setValue($tag_value);
// Create the bit of form for this tag.
@@ -158,7 +158,7 @@ class MetatagViewsEditForm extends FormBase {
public function submitForm(array &$form, FormStateInterface $form_state) {
// Get the submitted form values.
$view_name = $form_state->getValue('view');
- list($view_id, $display_id) = explode(':', $view_name);
+ [$view_id, $display_id] = explode(':', $view_name);
$metatags = $form_state->getValues();
unset($metatags['view']);
@@ -178,6 +178,9 @@ class MetatagViewsEditForm extends FormBase {
$configuration->clear($config_path);
}
else {
+ // Sort the values prior to saving. so that they are easier to manage.
+ ksort($metatags);
+
$configuration->set($config_path, $metatags);
}
$configuration->save();
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/MetatagViewsCachePluginManager.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/MetatagViewsCachePluginManager.php
index 8e0187c09..418cae7af 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/MetatagViewsCachePluginManager.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/MetatagViewsCachePluginManager.php
@@ -8,9 +8,14 @@ use Drupal\Core\Cache\CacheableDependencyInterface;
use Drupal\views\Plugin\views\cache\CachePluginBase;
use Drupal\views\Plugin\ViewsPluginManager;
+/**
+ * Custom cache plugin system for Views.
+ */
class MetatagViewsCachePluginManager implements PluginManagerInterface, CachedDiscoveryInterface, CacheableDependencyInterface {
/**
+ * {@inheritdoc}
+ *
* @var \Drupal\views\Plugin\ViewsPluginManager
*/
protected $viewsPluginManager;
@@ -19,15 +24,20 @@ class MetatagViewsCachePluginManager implements PluginManagerInterface, CachedDi
* MetatagViewsCachePluginManager constructor.
*
* @param \Drupal\views\Plugin\ViewsPluginManager $views_plugin_manager
+ * The ViewsPluginManager as argument.
*/
public function __construct(ViewsPluginManager $views_plugin_manager) {
$this->viewsPluginManager = $views_plugin_manager;
}
/**
+ * {@inheritdoc}
+ *
* @param \Drupal\views\Plugin\views\cache\CachePluginBase $plugin
+ * The CachePluginBase as argument.
*
* @return \Drupal\metatag_views\MetatagViewsCacheWrapper
+ * Return new MetatagViewsCacheWrapper
*/
protected function wrap(CachePluginBase $plugin) {
return new MetatagViewsCacheWrapper($plugin);
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/MetatagViewsCacheWrapper.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/MetatagViewsCacheWrapper.php
index 526ce3b2f..040894b06 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/MetatagViewsCacheWrapper.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/MetatagViewsCacheWrapper.php
@@ -25,6 +25,8 @@ class MetatagViewsCacheWrapper extends CachePluginBase {
const RESULTS = 'results';
/**
+ * {@inheritdoc}
+ *
* @var \Drupal\views\Plugin\views\cache\CachePluginBase
*/
protected $plugin;
@@ -72,7 +74,7 @@ class MetatagViewsCacheWrapper extends CachePluginBase {
$view = $plugin->view;
$data = [
'result' => $plugin->prepareViewResult($view->result),
- 'total_rows' => isset($view->total_rows) ? $view->total_rows : 0,
+ 'total_rows' => $view->total_rows ?? 0,
'current_page' => $view->getCurrentPage(),
'first_row_tokens' => MetatagDisplayExtender::getFirstRowTokensFromStylePlugin($view),
];
@@ -100,7 +102,7 @@ class MetatagViewsCacheWrapper extends CachePluginBase {
$view->execute_time = 0;
$extenders = $view->getDisplay()->getExtenders();
if (isset($extenders['metatag_display_extender'])) {
- $extenders['metatag_display_extender']->setFirstRowTokens($cache->data['first_row_tokens']);
+ $extenders['metatag_display_extender']->setFirstRowTokens($cache->data['first_row_tokens'] ?? []);
}
return TRUE;
}
@@ -295,8 +297,7 @@ class MetatagViewsCacheWrapper extends CachePluginBase {
/**
* {@inheritdoc}
*/
- public function getAvailableGlobalTokens($prepared = FALSE, array $types = [
- ]) {
+ public function getAvailableGlobalTokens($prepared = FALSE, array $types = []) {
return $this->plugin->getAvailableGlobalTokens($prepared, $types);
}
@@ -384,20 +385,6 @@ class MetatagViewsCacheWrapper extends CachePluginBase {
return $this->plugin->setStringTranslation($translation);
}
- /**
- * {@inheritdoc}
- */
- public function __sleep() {
- return $this->plugin->__sleep();
- }
-
- /**
- * {@inheritdoc}
- */
- public function __wakeup() {
- $this->plugin->__wakeup();
- }
-
/**
* {@inheritdoc}
*/
@@ -412,13 +399,18 @@ class MetatagViewsCacheWrapper extends CachePluginBase {
$this->plugin->messenger();
}
+ /**
+ * {@inheritdoc}
+ */
public function __get($name) {
return $this->plugin->$name;
}
+ /**
+ * {@inheritdoc}
+ */
public function __set($name, $value) {
$this->plugin->$name = $value;
}
-
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Plugin/views/display_extender/MetatagDisplayExtender.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Plugin/views/display_extender/MetatagDisplayExtender.php
index 4a2e06365..592be74ea 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Plugin/views/display_extender/MetatagDisplayExtender.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/src/Plugin/views/display_extender/MetatagDisplayExtender.php
@@ -59,6 +59,9 @@ class MetatagDisplayExtender extends DisplayExtenderPluginBase {
return $instance;
}
+ /**
+ * {@inheritdoc}
+ */
protected function defineOptions() {
$options = parent::defineOptions();
@@ -68,7 +71,6 @@ class MetatagDisplayExtender extends DisplayExtenderPluginBase {
return $options;
}
-
/**
* Provide a form to edit options for this plugin.
*/
@@ -260,8 +262,8 @@ class MetatagDisplayExtender extends DisplayExtenderPluginBase {
/**
* Store first row tokens on the class.
*
- * metatag_views_metatag_route_entity() loads the View fresh, to avoid
- * rebuilding and re-rendering it, preserve the first row tokens.
+ * The function metatag_views_metatag_route_entity() loads the View fresh, to
+ * avoid rebuilding and re-rendering it, preserve the first row tokens.
*/
public function setFirstRowTokens(array $first_row_tokens) {
self::$firstRowTokens = $first_row_tokens;
@@ -285,6 +287,7 @@ class MetatagDisplayExtender extends DisplayExtenderPluginBase {
*
* @param \Drupal\views\ViewExecutable $view
* The view.
+ *
* @return array
* The first row tokens.
*/
@@ -294,9 +297,13 @@ class MetatagDisplayExtender extends DisplayExtenderPluginBase {
}
/**
+ * Get the first row tokens for this Views object iteration.
+ *
* @param \Drupal\views\Plugin\views\style\StylePluginBase $style
+ * The style plugin used for this request.
*
* @return \ReflectionProperty
+ * The rawTokens property.
*/
protected static function getFirstRowTokensReflection(StylePluginBase $style): \ReflectionProperty {
$r = new \ReflectionObject($style);
diff --git a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/tests/src/Functional/MetatagViewsTokenTest.php b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/tests/src/Functional/MetatagViewsTokenTest.php
index 1268ab195..5715fd428 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/metatag_views/tests/src/Functional/MetatagViewsTokenTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/metatag_views/tests/src/Functional/MetatagViewsTokenTest.php
@@ -50,6 +50,8 @@ class MetatagViewsTokenTest extends BrowserTestBase {
$this->loginUser1();
$page_path = $this->randomMachineName();
$this->drupalGet('/admin/structure/views/add');
+ // @todo Also verify the form loads correctly.
+ $this->assertSession()->statusCodeEquals(200);
$edit = [
'label' => $this->randomString(),
'id' => 'test',
@@ -62,12 +64,18 @@ class MetatagViewsTokenTest extends BrowserTestBase {
$node_title = $this->randomString();
$this->createContentTypeNode($node_title);
$this->drupalGet("/$page_path");
+ $this->assertSession()->statusCodeEquals(200);
$this->assertSession()->titleEquals("$title_prefix $node_title");
+
// Test caching by asserting a change of the View changes the page as well.
$title_prefix = $this->updateView();
$this->drupalGet("/$page_path");
+ $this->assertSession()->statusCodeEquals(200);
$this->assertSession()->titleEquals("$title_prefix $node_title");
+
+ // Reload the page and confirm the values persist.
$this->drupalGet("/$page_path");
+ $this->assertSession()->statusCodeEquals(200);
$this->assertSession()->titleEquals("$title_prefix $node_title");
}
@@ -78,6 +86,7 @@ class MetatagViewsTokenTest extends BrowserTestBase {
* Also assert the Views UI behaves correctly.
*
* @return string
+ * The title with its full prefix.
*/
protected function updateView(bool $assert_ui = FALSE): string {
$title_prefix = $this->randomMachineName();
@@ -87,11 +96,16 @@ class MetatagViewsTokenTest extends BrowserTestBase {
];
$metatag_settings_path = '/admin/structure/views/nojs/display/test/page_1/metatags';
$this->drupalGet($metatag_settings_path);
+ $this->assertSession()->statusCodeEquals(200);
$this->submitForm($edit, 'Apply');
+ // @todo Also verify the page contains the correct response.
+ $this->assertSession()->statusCodeEquals(200);
+
// Make sure the UI does not tokenize away {{ title }}.
if ($assert_ui) {
- // Reload the form
+ // Reload the form.
$this->drupalGet($metatag_settings_path);
+ $this->assertSession()->statusCodeEquals(200);
$actual = $this->getSession()
->getPage()
->find('css', '#edit-title')
@@ -99,7 +113,12 @@ class MetatagViewsTokenTest extends BrowserTestBase {
$this->assertSame($edit['title'], $actual);
}
$this->drupalGet('/admin/structure/views/view/test');
+ // @todo Also verify the page contains the correct response.
+ $this->assertSession()->statusCodeEquals(200);
$this->submitForm([], 'Save');
+ // @todo Also verify the page contains the correct response.
+ $this->assertSession()->statusCodeEquals(200);
+
return $title_prefix;
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Controller/MetatagController.php b/frontend/drupal9/web/modules/contrib/metatag/src/Controller/MetatagController.php
index 897697330..b3cc732e3 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Controller/MetatagController.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Controller/MetatagController.php
@@ -61,7 +61,10 @@ class MetatagController extends ControllerBase {
public function reportPlugins() {
// Get tags.
$tag_definitions = $this->tagManager->getDefinitions();
- uasort($tag_definitions, ['Drupal\Component\Utility\SortArray', 'sortByWeightElement']);
+ uasort($tag_definitions, [
+ 'Drupal\Component\Utility\SortArray',
+ 'sortByWeightElement',
+ ]);
$tags = [];
foreach ($tag_definitions as $tag_name => $tag_definition) {
$tags[$tag_definition['group']][$tag_name] = $tag_definition;
@@ -69,7 +72,10 @@ class MetatagController extends ControllerBase {
// Get groups.
$group_definitions = $this->groupManager->getDefinitions();
- uasort($group_definitions, ['Drupal\Component\Utility\SortArray', 'sortByWeightElement']);
+ uasort($group_definitions, [
+ 'Drupal\Component\Utility\SortArray',
+ 'sortByWeightElement',
+ ]);
// Build plugin by group.
$build = [];
@@ -83,7 +89,7 @@ class MetatagController extends ControllerBase {
];
// Group description.
$build[$group_name]['description'] = [
- '#markup' => $group_definition['description'],
+ '#markup' => $group_definition['description'] ?? '',
'#prefix' => '',
'#suffix' => '
',
];
@@ -115,7 +121,7 @@ class MetatagController extends ControllerBase {
$row = [];
$row['description'] = [
'data' => [
- '#markup' => $definition['description'],
+ '#markup' => $definition['description'] ?? '',
],
'colspan' => 8,
];
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Form/MetatagDefaultsForm.php b/frontend/drupal9/web/modules/contrib/metatag/src/Form/MetatagDefaultsForm.php
index e1f802857..7ac696db8 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Form/MetatagDefaultsForm.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Form/MetatagDefaultsForm.php
@@ -17,7 +17,7 @@ use Drupal\page_manager\Entity\PageVariant;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
- * Class MetatagDefaultsForm.
+ * Form handler for the Metatag Defaults entity type.
*
* @package Drupal\metatag\Form
*/
@@ -157,16 +157,15 @@ class MetatagDefaultsForm extends EntityForm {
$entity_type_groups = $settings->get('entity_type_groups');
// Find the current entity type and bundle.
- $metatag_defaults_id = $metatag_defaults->id();
- $type_parts = explode('__', $metatag_defaults_id);
- $entity_type = $type_parts[0];
- $entity_bundle = isset($type_parts[1]) ? $type_parts[1] : NULL;
+ if ($metatag_defaults_id = $metatag_defaults->id()) {
+ $type_parts = explode('__', $metatag_defaults_id);
+ $entity_type = $type_parts[0];
+ $entity_bundle = $type_parts[1] ?? NULL;
+ }
// See if there are requested groups for this entity type and bundle.
- $groups = !empty($entity_type_groups[$entity_type]) && !empty($entity_type_groups[$entity_type][$entity_bundle]) ? $entity_type_groups[$entity_type][$entity_bundle] : [];
- // Limit the form to requested groups, if any.
- if (!empty($groups)) {
- $form = $this->metatagManager->form($values, $form, [$entity_type], $groups, NULL, TRUE);
+ if (isset($entity_type) && !empty($entity_type_groups[$entity_type]) && !empty($entity_type_groups[$entity_type][$entity_bundle])) {
+ $form = $this->metatagManager->form($values, $form, [$entity_type], $entity_type_groups[$entity_type][$entity_bundle], NULL, TRUE);
}
// Otherwise, display all groups.
else {
@@ -240,7 +239,7 @@ class MetatagDefaultsForm extends EntityForm {
$type_parts = explode('__', $metatag_defaults_id);
$entity_type = $type_parts[0];
- $entity_bundle = isset($type_parts[1]) ? $type_parts[1] : NULL;
+ $entity_bundle = $type_parts[1] ?? NULL;
// Get the entity label.
$entity_info = $this->entityTypeManager->getDefinitions();
@@ -283,6 +282,10 @@ class MetatagDefaultsForm extends EntityForm {
}
}
}
+
+ // Sort the values prior to saving. so that they are easier to manage.
+ ksort($tag_values);
+
$metatag_defaults->set('tags', $tag_values);
$status = $metatag_defaults->save();
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Form/MetatagSettingsForm.php b/frontend/drupal9/web/modules/contrib/metatag/src/Form/MetatagSettingsForm.php
index 1fa2354c6..1f61f8796 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Form/MetatagSettingsForm.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Form/MetatagSettingsForm.php
@@ -126,14 +126,16 @@ class MetatagSettingsForm extends ConfigFormBase {
'#tree' => TRUE,
];
- foreach ($metatags as $metatag_name => $metatag_info) {
+ // Name the variable "metatag_id" to avoid confusing this with the "name"
+ // value from the meta tag plugin as it's actually the plugin ID.
+ foreach ($metatags as $metatag_id => $metatag_info) {
if (!empty($metatag_info['trimmable'])) {
- $form['tag_trim']['maxlength']['metatag_maxlength_' . $metatag_name] = [
- '#title' => $this->t('Meta Tags:') . ' ' . $metatag_name . ' ' . $this->t('length'),
+ $form['tag_trim']['maxlength']['metatag_maxlength_' . $metatag_id] = [
+ '#title' => $this->t('Meta Tags:') . ' ' . $metatag_id . ' ' . $this->t('length'),
'#type' => 'number',
'#required' => FALSE,
- '#default_value' => $trimSettingsMaxlength['metatag_maxlength_' . $metatag_name] ?? NULL,
+ '#default_value' => $trimSettingsMaxlength['metatag_maxlength_' . $metatag_id] ?? NULL,
'#min' => 0,
'#step' => 1,
];
@@ -151,6 +153,24 @@ class MetatagSettingsForm extends ConfigFormBase {
'beforeValue' => $this->t('Trim the Meta Tag before the word on the given value'),
],
];
+
+ $scrollheight = $this->config('metatag.settings')->get('tag_scroll_max_height');
+
+ $form['firehose_widget'] = [
+ '#title' => $this->t('Metatag widget options'),
+ '#type' => 'details',
+ '#tree' => TRUE,
+ '#open' => TRUE,
+ '#description' => $this->t("Various options for the field widget used on entity forms, e.g. on content type forms."),
+ ];
+
+ $form['firehose_widget']['tag_scroll_max_height'] = [
+ '#title' => $this->t('Scroll maximum height'),
+ '#type' => 'textfield',
+ '#default_value' => $scrollheight,
+ '#placeholder' => $this->t('eg 500px or 8rem'),
+ '#description' => $this->t("To enable scrolling please enter a value and its units, e.g. 500px, 8rem, etc. Removing this value will remove the scroll."),
+ ];
return parent::buildForm($form, $form_state);
}
@@ -176,6 +196,10 @@ class MetatagSettingsForm extends ConfigFormBase {
$trimmingValues = $form_state->getValue(['tag_trim', 'maxlength']);
$settings->set('tag_trim_maxlength', $trimmingValues);
+ // Widget settings.
+ $scrollheightvalue = $form_state->getValue(['firehose_widget', 'tag_scroll_max_height']);
+ $settings->set('tag_scroll_max_height', $scrollheightvalue);
+
$settings->save();
parent::submitForm($form, $form_state);
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/MetatagDefaultsListBuilder.php b/frontend/drupal9/web/modules/contrib/metatag/src/MetatagDefaultsListBuilder.php
index b68d456f8..ed86df823 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/MetatagDefaultsListBuilder.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/MetatagDefaultsListBuilder.php
@@ -125,7 +125,7 @@ class MetatagDefaultsListBuilder extends ConfigEntityListBuilder {
';
foreach ($tags as $tag_id => $tag_value) {
if (is_array($tag_value)) {
- $tag_value = implode(', ', $tag_value);
+ $tag_value = implode(', ', array_filter($tag_value));
}
$output .= '' . $tag_id . ': | ' . $tag_value . ' |
';
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/MetatagManager.php b/frontend/drupal9/web/modules/contrib/metatag/src/MetatagManager.php
index 4035cc8eb..3e1c6a256 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/MetatagManager.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/MetatagManager.php
@@ -10,9 +10,13 @@ use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\views\ViewEntityInterface;
+use Drupal\Core\Path\PathMatcherInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Drupal\Core\Language\LanguageManagerInterface;
/**
- * Class MetatagManager.
+ * Primary logic for the Metatag module.
*
* @package Drupal\metatag
*/
@@ -55,6 +59,34 @@ class MetatagManager implements MetatagManagerInterface {
*/
protected $logger;
+ /**
+ * The path matcher.
+ *
+ * @var \Drupal\Core\Path\PathMatcherInterface
+ */
+ protected $pathMatcher;
+
+ /**
+ * The route match.
+ *
+ * @var \Drupal\Core\Routing\RouteMatchInterface
+ */
+ protected $routeMatch;
+
+ /**
+ * The request stack.
+ *
+ * @var \Symfony\Component\HttpFoundation\RequestStack
+ */
+ protected $requestStack;
+
+ /**
+ * The language manager.
+ *
+ * @var \Drupal\Core\Language\LanguageManagerInterface
+ */
+ protected $languageManager;
+
/**
* Caches processed strings, keyed by tag name.
*
@@ -68,32 +100,48 @@ class MetatagManager implements MetatagManagerInterface {
* @param \Drupal\metatag\MetatagGroupPluginManager $groupPluginManager
* The MetatagGroupPluginManager object.
* @param \Drupal\metatag\MetatagTagPluginManager $tagPluginManager
- * The MetatagTagPluginMÏ€anager object.
+ * The MetatagTagPluginManager object.
* @param \Drupal\metatag\MetatagToken $token
* The MetatagToken object.
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $channelFactory
* The LoggerChannelFactoryInterface object.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The EntityTypeManagerInterface object.
+ * @param \Drupal\Core\Path\PathMatcherInterface $pathMatcher
+ * The path matcher.
+ * @param \Drupal\Core\Routing\RouteMatchInterface $routeMatch
+ * The route match.
+ * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
+ * The request stack.
+ * @param \Drupal\Core\Language\LanguageManagerInterface $languageManager
+ * The language manager.
*/
public function __construct(MetatagGroupPluginManager $groupPluginManager,
MetatagTagPluginManager $tagPluginManager,
MetatagToken $token,
LoggerChannelFactoryInterface $channelFactory,
- EntityTypeManagerInterface $entityTypeManager
+ EntityTypeManagerInterface $entityTypeManager,
+ PathMatcherInterface $pathMatcher,
+ RouteMatchInterface $routeMatch,
+ RequestStack $requestStack,
+ LanguageManagerInterface $languageManager
) {
$this->groupPluginManager = $groupPluginManager;
$this->tagPluginManager = $tagPluginManager;
$this->tokenService = $token;
$this->logger = $channelFactory->get('metatag');
$this->metatagDefaults = $entityTypeManager->getStorage('metatag_defaults');
+ $this->pathMatcher = $pathMatcher;
+ $this->routeMatch = $routeMatch;
+ $this->requestStack = $requestStack;
+ $this->languageManager = $languageManager;
}
/**
* Returns the list of protected defaults.
*
* @return array
- * Th protected defaults.
+ * The protected defaults.
*/
public static function protectedDefaults() {
return [
@@ -186,7 +234,7 @@ class MetatagManager implements MetatagManagerInterface {
foreach ($metatag_groups as $group_name => $group_info) {
$groups[$group_name]['id'] = $group_info['id'];
$groups[$group_name]['label'] = $group_info['label']->render();
- $groups[$group_name]['description'] = $group_info['description'];
+ $groups[$group_name]['description'] = $group_info['description'] ?? '';
$groups[$group_name]['weight'] = $group_info['weight'];
}
@@ -243,7 +291,10 @@ class MetatagManager implements MetatagManagerInterface {
if (!isset($groups[$tag_group])) {
// If the tag is claiming a group that has no matching plugin, log an
// error and force it to the basic group.
- $this->logger->error("Undefined group '%group' on tag '%tag'", ['%group' => $tag_group, '%tag' => $tag_name]);
+ $this->logger->error("Undefined group '%group' on tag '%tag'", [
+ '%group' => $tag_group,
+ '%tag' => $tag_name,
+ ]);
$tag['group'] = 'basic';
$tag_group = 'basic';
}
@@ -280,7 +331,7 @@ class MetatagManager implements MetatagManagerInterface {
// Create the fieldset.
$element[$group_name]['#type'] = 'details';
$element[$group_name]['#title'] = $group['label'];
- $element[$group_name]['#description'] = $group['description'];
+ $element[$group_name]['#description'] = $group['description'] ?? '';
$element[$group_name]['#open'] = FALSE;
foreach ($group['tags'] as $tag_name => $tag) {
@@ -290,7 +341,7 @@ class MetatagManager implements MetatagManagerInterface {
$tag = $this->tagPluginManager->createInstance($tag_name);
// Set the value to the stored value, if any.
- $tag_value = isset($values[$tag_name]) ? $values[$tag_name] : NULL;
+ $tag_value = $values[$tag_name] ?? NULL;
$tag->setValue($tag_value);
// Open any groups that have non-empty values.
@@ -359,7 +410,7 @@ class MetatagManager implements MetatagManagerInterface {
// Get serialized value and break it into an array of tags with values.
$serialized_value = $item->get('value')->getValue();
if (!empty($serialized_value)) {
- $tags += unserialize($serialized_value);
+ $tags += unserialize($serialized_value, ['allowed_classes' => FALSE]);
}
}
@@ -380,7 +431,7 @@ class MetatagManager implements MetatagManagerInterface {
$metatags = $this->getGlobalMetatags();
// If that is empty something went wrong.
if (!$metatags) {
- return;
+ return [];
}
// Check if this is a special page.
@@ -430,13 +481,13 @@ class MetatagManager implements MetatagManagerInterface {
public function getSpecialMetatags() {
$metatags = NULL;
- if (\Drupal::service('path.matcher')->isFrontPage()) {
+ if ($this->pathMatcher->isFrontPage()) {
$metatags = $this->metatagDefaults->load('front');
}
- elseif (\Drupal::service('current_route_match')->getRouteName() == 'system.403') {
+ elseif ($this->routeMatch->getRouteName() == 'system.403') {
$metatags = $this->metatagDefaults->load('403');
}
- elseif (\Drupal::service('current_route_match')->getRouteName() == 'system.404') {
+ elseif ($this->routeMatch->getRouteName() == 'system.404') {
$metatags = $this->metatagDefaults->load('404');
}
@@ -519,7 +570,7 @@ class MetatagManager implements MetatagManagerInterface {
*/
public function generateRawElements(array $tags, $entity = NULL, BubbleableMetadata $cache = NULL) {
// Ignore the update.php path.
- $request = \Drupal::request();
+ $request = $this->requestStack->getCurrentRequest();
if ($request->getBaseUrl() == '/update.php') {
return [];
}
@@ -527,6 +578,7 @@ class MetatagManager implements MetatagManagerInterface {
// Prepare any tokens that might exist.
$token_replacements = [];
if ($entity) {
+
// @todo This needs a better way of discovering the context.
if ($entity instanceof ViewEntityInterface) {
// Views tokens require the ViewExecutable, not the config entity.
@@ -537,16 +589,15 @@ class MetatagManager implements MetatagManagerInterface {
$token_replacements = [$entity->getEntityTypeId() => $entity];
}
}
-
- // Get the current language code.
- $langcode = \Drupal::languageManager()
- ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
- ->getId();
-
$rawTags = [];
-
$metatag_tags = $this->tagPluginManager->getDefinitions();
+ // Use the entity's language code, if one is defined.
+ $langcode = NULL;
+ if ($entity) {
+ $langcode = $entity->language()->getId();
+ }
+
// Order metatags based on the group and weight.
$group = array_column($metatag_tags, 'group');
$weight = array_column($metatag_tags, 'weight');
@@ -567,24 +618,8 @@ class MetatagManager implements MetatagManagerInterface {
// Get an instance of the plugin.
$tag = $this->tagPluginManager->createInstance($tag_name);
- // Set the value as sometimes the data needs massaging, such as when
- // field defaults are used for the Robots field, which come as an array
- // that needs to be filtered and converted to a string.
- // @see Robots::setValue()
- $tag->setValue($value);
-
- // Obtain the processed value. Some meta tags will store this as a
- // string, so support that option.
- $value = $tag->value();
- if (is_array($value)) {
- $processed_value = [];
- foreach ($value as $key => $value_item) {
- $processed_value[$key] = htmlspecialchars_decode($this->tokenService->replace($value_item, $token_replacements, ['langcode' => $langcode]));
- }
- }
- else {
- $processed_value = htmlspecialchars_decode($this->tokenService->replace($value, $token_replacements, ['langcode' => $langcode]));
- }
+ // Prepare value.
+ $processed_value = $this->processTagValue($tag, $value, $token_replacements, FALSE, $langcode);
// Now store the value with processed tokens back into the plugin.
$tag->setValue($processed_value);
@@ -625,14 +660,20 @@ class MetatagManager implements MetatagManagerInterface {
*/
public function generateTokenValues(array $tags, $entity = NULL) {
// Ignore the update.php path.
- $request = \Drupal::request();
+ $request = $this->requestStack->getCurrentRequest();
if ($request->getBaseUrl() == '/update.php') {
return [];
}
$entity_identifier = '_none';
if ($entity) {
- $entity_identifier = $entity->getEntityTypeId() . ':' . ($entity->uuid() ?: $entity->id());
+ $entity_identifier = $entity->getEntityTypeId() . ':' . ($entity->uuid() ?? $entity->id());
+ }
+
+ // Use the entity's language code, if one is defined.
+ $langcode = NULL;
+ if ($entity) {
+ $langcode = $entity->language()->getId();
}
if (!isset($this->processedTokenCache[$entity_identifier])) {
@@ -659,15 +700,8 @@ class MetatagManager implements MetatagManagerInterface {
$token_replacements = [$entity->getEntityTypeId() => $entity];
}
}
-
- // Set the value as sometimes the data needs massaging, such as when
- // field defaults are used for the Robots field, which come as an
- // array that needs to be filtered and converted to a string.
- // @see Robots::setValue()
- $tag->setValue($value);
- $langcode = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
- $value = PlainTextOutput::renderFromHtml(htmlspecialchars_decode($this->tokenService->replace($value, $token_replacements, ['langcode' => $langcode])));
- $this->processedTokenCache[$entity_identifier][$tag_name] = $tag->multiple() ? explode(',', $value) : $value;
+ $processed_value = $this->processTagValue($tag, $value, $token_replacements, TRUE);
+ $this->processedTokenCache[$entity_identifier][$tag_name] = $tag->multiple() ? explode(',', $processed_value) : $processed_value;
}
}
}
@@ -687,4 +721,66 @@ class MetatagManager implements MetatagManagerInterface {
return ['metatag'];
}
+ /**
+ * Sets tag value and returns sanitized value with token replaced.
+ *
+ * @param \Drupal\metatag\Plugin\metatag\Tag\MetaNameBase|object $tag
+ * Metatag object.
+ * @param array|string $value
+ * Value to process.
+ * @param array $token_replacements
+ * Arguments for token->replace().
+ * @param bool $plain_text
+ * (optional) If TRUE, value will be formatted as a plain text. Defaults to
+ * FALSE.
+ * @param string $langcode
+ * (optional) The language code to use for replacements; if not provided the
+ * current interface language code will be used.
+ *
+ * @return array|string
+ * Processed value.
+ */
+ protected function processTagValue($tag, $value, array $token_replacements, bool $plain_text = FALSE, $langcode = FALSE) {
+ // Set the value as sometimes the data needs massaging, such as when
+ // field defaults are used for the Robots field, which come as an array
+ // that needs to be filtered and converted to a string.
+ // @see Robots::setValue()
+ $tag->setValue($value);
+
+ // Obtain the processed value. Some meta tags will store this as a
+ // string, so support that option.
+ // @todo Is there a better way of doing this? It seems unclean.
+ $value = $tag->value();
+
+ // Make sure the value is always handled as an array, but track whether it
+ // was actually passed in as an array.
+ $is_array = is_array($value);
+ if (!$is_array) {
+ $value = [$value];
+ }
+
+ // If a langcode was not specified, use the current interface language.
+ if (empty($langcode)) {
+ $langcode = $this->languageManager
+ ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
+ ->getId();
+ }
+
+ // Loop over each item in the array.
+ foreach ($value as $key => $value_item) {
+ // Process the tokens in this value and decode any HTML characters that
+ // might be found.
+ $value[$key] = htmlspecialchars_decode($this->tokenService->replace($value_item, $token_replacements, ['langcode' => $langcode]));
+
+ // If requested, run the value through the render system.
+ if ($plain_text) {
+ $value[$key] = PlainTextOutput::renderFromHtml($value[$key]);
+ }
+ }
+
+ // If the original value was passed as an array return the whole value,
+ // otherwise return the first item from the array.
+ return $is_array ? $value : reset($value);
+ }
+
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/MetatagTrimmer.php b/frontend/drupal9/web/modules/contrib/metatag/src/MetatagTrimmer.php
index bf1aebf18..6fe035ba4 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/MetatagTrimmer.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/MetatagTrimmer.php
@@ -21,11 +21,17 @@ class MetatagTrimmer {
* The trimmed string.
*/
public function trimAfterValue($string, $maxlength) {
- $spacePos = strpos($string, ' ', $maxlength - 1);
+ // If the string is shorter than the max length then skip the rest of the
+ // logic.
+ if ($maxlength > mb_strlen($string)) {
+ return $string;
+ }
+
+ $spacePos = mb_strpos($string, ' ', $maxlength - 1);
if (FALSE === $spacePos) {
return $string;
}
- $subString = substr($string, 0, $spacePos);
+ $subString = mb_substr($string, 0, $spacePos);
return trim($subString);
}
@@ -42,15 +48,21 @@ class MetatagTrimmer {
* The trimmed string.
*/
public function trimBeforeValue($string, $maxlength) {
- $subString = substr($string, 0, $maxlength + 1);
- if (' ' === substr($subString, -1)) {
+ // If the string is shorter than the max length then skip the rest of the
+ // logic.
+ if ($maxlength > mb_strlen($string)) {
+ return $string;
+ }
+
+ $subString = mb_substr($string, 0, $maxlength + 1);
+ if (' ' === mb_substr($subString, -1)) {
return trim($subString);
}
- $spacePos = strrpos($subString, ' ', 0);
+ $spacePos = mb_strrpos($subString, ' ', 0);
if (FALSE === $spacePos) {
return $string;
}
- $returnedString = substr($string, 0, $spacePos);
+ $returnedString = mb_substr($string, 0, $spacePos);
return trim($returnedString);
}
@@ -76,7 +88,7 @@ class MetatagTrimmer {
return $this->trimAfterValue($value, $maxlength);
case 'onValue':
- return trim(substr($value, 0, $maxlength));
+ return trim(mb_substr($value, 0, $maxlength));
case 'beforeValue':
return $this->trimBeforeValue($value, $maxlength);
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/FieldType/MetatagFieldItem.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/FieldType/MetatagFieldItem.php
index 32584acf2..2c2612801 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/FieldType/MetatagFieldItem.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/FieldType/MetatagFieldItem.php
@@ -70,7 +70,7 @@ class MetatagFieldItem extends FieldItemBase {
$current_value = $this->value;
// Only unserialize if still serialized string.
if (is_string($current_value)) {
- $current_tags = unserialize($current_value);
+ $current_tags = unserialize($current_value, ['allowed_classes' => FALSE]);
}
else {
$current_tags = $current_value;
@@ -85,6 +85,9 @@ class MetatagFieldItem extends FieldItemBase {
}
}
+ // Sort the values prior to saving. so that they are easier to manage.
+ ksort($tags_to_save);
+
// Update the value to only save overridden tags.
$this->value = serialize($tags_to_save);
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/FieldWidget/MetatagFirehose.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/FieldWidget/MetatagFirehose.php
index 94b55f6fc..b5709c98d 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/FieldWidget/MetatagFirehose.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/FieldWidget/MetatagFirehose.php
@@ -141,7 +141,14 @@ class MetatagFirehose extends WidgetBase implements ContainerFactoryPluginInterf
// Retrieve the values for each metatag from the serialized array.
$values = [];
if (!empty($item->value)) {
- $values = unserialize($item->value);
+ $values = unserialize($item->value, ['allowed_classes' => FALSE]);
+ }
+
+ // Make sure that this variable is always an array to avoid problems when
+ // unserializing didn't work correctly and it as returned as FALSE.
+ // @see https://www.php.net/unserialize
+ if (!is_array($values)) {
+ $values = [];
}
// Populate fields which have not been overridden in the entity.
@@ -193,6 +200,15 @@ class MetatagFirehose extends WidgetBase implements ContainerFactoryPluginInterf
$element['#type'] = 'container';
}
+ // Scroll height configuration.
+ $scroll_height = $settings->get('tag_scroll_max_height');
+ if (!empty($scrollheight)) {
+ $form['#attached']['drupalSettings']['metatag']['max_height'] = $scroll_height;
+ $form['#attached']['library'][] = 'metatag/firehose_widget';
+ $element['#attributes']['class'][] = 'metatags';
+ $element['#attributes']['style'][] = 'max-height:' . $scroll_height . ';';
+ }
+
return $element;
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/MetatagEntityFieldItemList.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/MetatagEntityFieldItemList.php
index f48c90dd6..bdc6a3e71 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/MetatagEntityFieldItemList.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/Field/MetatagEntityFieldItemList.php
@@ -22,5 +22,4 @@ class MetatagEntityFieldItemList extends FieldItemList {
return NULL;
}
-
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Group/GroupBase.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Group/GroupBase.php
index 0c2770ce8..eac73d587 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Group/GroupBase.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Group/GroupBase.php
@@ -42,7 +42,7 @@ abstract class GroupBase extends PluginBase {
// @todo Should we have setProperty() methods for each of these?
$this->id = $plugin_definition['id'];
$this->label = $plugin_definition['label'];
- $this->description = $plugin_definition['description'];
+ $this->description = $plugin_definition['description'] ?? '';
}
/**
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Author.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Author.php
new file mode 100644
index 000000000..3c9084614
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Author.php
@@ -0,0 +1,23 @@
+ $this->label(),
'#default_value' => $this->value(),
'#maxlength' => 1024,
- '#required' => isset($element['#required']) ? $element['#required'] : FALSE,
+ '#required' => $element['#required'] ?? FALSE,
'#description' => $this->description(),
'#element_validate' => [[get_class($this), 'validateTag']],
];
@@ -482,7 +482,7 @@ abstract class MetaNameBase extends PluginBase {
}
$currentMaxValue = 0;
foreach ($trimMaxlengthArray as $metaTagName => $maxValue) {
- if ($metaTagName == 'metatag_maxlength_' . $this->name) {
+ if ($metaTagName == 'metatag_maxlength_' . $this->id) {
$currentMaxValue = $maxValue;
}
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Referrer.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Referrer.php
index def080a51..48869b9c7 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Referrer.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Referrer.php
@@ -44,7 +44,7 @@ class Referrer extends MetaNameBase {
'#empty_option' => $this->t('- None -'),
'#empty_value' => '',
'#default_value' => $this->value(),
- '#required' => isset($element['#required']) ? $element['#required'] : FALSE,
+ '#required' => $element['#required'] ?? FALSE,
'#element_validate' => [[get_class($this), 'validateTag']],
];
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Robots.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Robots.php
index 492546a67..e2dd377be 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Robots.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Robots.php
@@ -103,7 +103,7 @@ class Robots extends MetaNameBase {
],
],
'#default_value' => $default_value,
- '#required' => isset($element['#required']) ? $element['#required'] : FALSE,
+ '#required' => $element['#required'] ?? FALSE,
'#element_validate' => [[get_class($this), 'validateTag']],
];
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Title.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Title.php
index 61fad6ed7..f2a4f2ec4 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Title.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/metatag/Tag/Title.php
@@ -19,28 +19,5 @@ namespace Drupal\metatag\Plugin\metatag\Tag;
* )
*/
class Title extends MetaNameBase {
-
- /**
- * Override the output of this tag so it's an actual TITLE tag.
- *
- * @todo Override the existing title tag X-)
- */
- // {@code}
- // public function output() {
- // if (empty($this->value)) {
- // // If there is no value, we don't want a tag output.
- // $element = '';
- // }
- // else {
- // $element = [
- // '#theme' => 'hidden',
- // // '#tag' => 'title',
- // '#value' => $this->value(),
- // ];
- // }
- //
- // return $element;
- // }
- // {@endcode}
-
+ // Nothing here yet. Just a placeholder class for a plugin.
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/process/d6/NodewordsEntities.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/process/d6/NodewordsEntities.php
index b6544d1b5..1e0a8ca7f 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/process/d6/NodewordsEntities.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/process/d6/NodewordsEntities.php
@@ -38,7 +38,7 @@ class NodewordsEntities extends ProcessPluginBase {
// Re-shape D6 entries into for D8 entries.
$old_tags = array_map(static function ($value) {
- return unserialize($value);
+ return unserialize($value, ['allowed_classes' => FALSE]);
}, $value);
foreach ($old_tags as $d6_metatag_name => $metatag_value) {
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/process/d7/MetatagEntities.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/process/d7/MetatagEntities.php
index 74231e3d9..f5a1e11bc 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/process/d7/MetatagEntities.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/process/d7/MetatagEntities.php
@@ -28,7 +28,7 @@ class MetatagEntities extends ProcessPluginBase {
}
// Re-shape D7 entries into for D8 entries.
- $old_tags = unserialize($value);
+ $old_tags = unserialize($value, ['allowed_classes' => FALSE]);
// This is expected to be an array, if it isn't then something went wrong.
if (!is_array($old_tags)) {
@@ -75,6 +75,9 @@ class MetatagEntities extends ProcessPluginBase {
$metatags[$d8_metatag_name] = $metatag_value;
}
+ // Sort the meta tags alphabetically to make testing easier.
+ ksort($metatags);
+
return serialize($metatags);
}
@@ -429,8 +432,8 @@ class MetatagEntities extends ProcessPluginBase {
// From metatag_verification.metatag.inc:
'baidu-site-verification' => 'baidu',
'facebook-domain-verification' => 'facebook_domain_verification',
- 'google-site-verification' => 'bing',
- 'msvalidate.01' => 'google',
+ 'google-site-verification' => 'google_site_verification',
+ 'msvalidate.01' => 'bing',
'norton-safeweb-site-verification' => 'norton_safe_web',
'p:domain_verify' => 'pinterest',
// @todo '' => 'pocket',
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d6/NodewordsField.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d6/NodewordsField.php
index 00a1c7f89..e03225d23 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d6/NodewordsField.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d6/NodewordsField.php
@@ -30,17 +30,23 @@ class NodewordsField extends DrupalSqlBase {
$instances = [];
foreach (parent::initializeIterator() as $instance) {
switch ($instance['type']) {
+ // @code
// define('NODEWORDS_TYPE_NODE', 5);
+ // @endcode
case 5:
$instance['entity_type'] = 'node';
break;
+ // @code
// define('NODEWORDS_TYPE_TERM', 6);
+ // @endcode
case 6:
$instance['entity_type'] = 'taxonomy_term';
break;
+ // @code
// define('NODEWORDS_TYPE_USER', 8);
+ // @endcode
case 8:
$instance['entity_type'] = 'user';
break;
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d6/NodewordsFieldInstance.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d6/NodewordsFieldInstance.php
index ec60b69b6..d56085e92 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d6/NodewordsFieldInstance.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d6/NodewordsFieldInstance.php
@@ -71,18 +71,24 @@ class NodewordsFieldInstance extends DrupalSqlBase {
foreach (parent::initializeIterator() as $instance) {
$entity_type = NULL;
switch ($instance['type']) {
+ // @code
+ // define('NODEWORDS_TYPE_NODE', 5);
+ // @endcode
case 5:
- // define('NODEWORDS_TYPE_NODE', 5);
$entity_type = 'node';
break;
+ // @code
+ // define('NODEWORDS_TYPE_TERM', 6);
+ // @endcode
case 6:
- // define('NODEWORDS_TYPE_TERM', 6);
$entity_type = 'taxonomy_term';
break;
+ // @code
+ // define('NODEWORDS_TYPE_USER', 8);
+ // @endcode
case 8:
- // define('NODEWORDS_TYPE_USER', 8);
$entity_type = 'user';
break;
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldDeriver.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldDeriver.php
index 294dc2b47..1f4c0be00 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldDeriver.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldDeriver.php
@@ -4,18 +4,16 @@ namespace Drupal\metatag\Plugin\migrate\source\d7;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\migrate\Exception\RequirementsException;
use Drupal\migrate\Plugin\MigrationDeriverTrait;
use Drupal\migrate_drupal\MigrationConfigurationTrait;
-use Drupal\migrate_drupal\NodeMigrateType;
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
- * @todo.
+ * Creates field plugins for each entity type.
*/
class MetatagFieldDeriver extends DeriverBase implements ContainerDeriverInterface {
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldInstance.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldInstance.php
index 69bec1872..eb1beaf3f 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldInstance.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldInstance.php
@@ -60,8 +60,8 @@ class MetatagFieldInstance extends DrupalSqlBase {
$bundle = $this->configuration['bundle'];
switch ($entity_type_id) {
case 'node':
- // We want to get a per-node-type metatag migration. So we inner join
- // the base query on node table based on the parsed node ID.
+ // We want to get a per-node-type metatag migration. So we inner
+ // join the base query on node table based on the parsed node ID.
$base_query->join('node', 'n', "n.nid = m.entity_id");
$base_query->condition('n.type', $bundle);
$base_query->addField('n', 'type', 'bundle');
diff --git a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldInstanceDeriver.php b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldInstanceDeriver.php
index 832559232..8c49395c0 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldInstanceDeriver.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/src/Plugin/migrate/source/d7/MetatagFieldInstanceDeriver.php
@@ -13,7 +13,10 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
- * Deriver for d7_metatag_field_instance and d7_metatag_field_instance_widget_settings.
+ * Deriver for Metatag-D7 field instances.
+ *
+ * Covers d7_metatag_field_instance and
+ * d7_metatag_field_instance_widget_settings.
*/
class MetatagFieldInstanceDeriver extends DeriverBase implements ContainerDeriverInterface {
@@ -170,6 +173,7 @@ class MetatagFieldInstanceDeriver extends DeriverBase implements ContainerDerive
case 'node':
$this->derivatives[$derivative_id]['migration_dependencies']['required'][] = "d7_node_type:$bundle_id";
break;
+
case 'taxonomy_term':
$this->derivatives[$derivative_id]['migration_dependencies']['required'][] = "d7_taxonomy_vocabulary:$bundle_id";
break;
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_custom_route/metatag_test_custom_route.info.yml b/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_custom_route/metatag_test_custom_route.info.yml
index 6f1922643..88dbbb85a 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_custom_route/metatag_test_custom_route.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_custom_route/metatag_test_custom_route.info.yml
@@ -6,7 +6,7 @@ package: Testing
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_integration/metatag_test_integration.info.yml b/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_integration/metatag_test_integration.info.yml
index 8d5a0504a..374b3ef55 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_integration/metatag_test_integration.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_integration/metatag_test_integration.info.yml
@@ -5,7 +5,7 @@ package: Testing
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_tag/metatag_test_tag.info.yml b/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_tag/metatag_test_tag.info.yml
index 11929a8a9..5a4fe794f 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_tag/metatag_test_tag.info.yml
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/modules/metatag_test_tag/metatag_test_tag.info.yml
@@ -6,7 +6,7 @@ package: Testing
dependencies:
- metatag:metatag
-# Information added by Drupal.org packaging script on 2022-01-06
-version: '8.x-1.19'
+# Information added by Drupal.org packaging script on 2022-07-12
+version: '8.x-1.20'
project: 'metatag'
-datestamp: 1641496016
+datestamp: 1657649279
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/DefaultTags.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/DefaultTags.php
index fb52570c1..485c8ddbe 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/DefaultTags.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/DefaultTags.php
@@ -133,7 +133,7 @@ class DefaultTags extends BrowserTestBase {
* Test the default values for the user login page, etc.
*/
public function testUserLoginPages() {
- $front_url = $this->buildUrl('', ['absolute' => TRUE]);;
+ $front_url = $this->buildUrl('', ['absolute' => TRUE]);
// A list of paths to examine.
$routes = [
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/LanguageHandlingTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/LanguageHandlingTest.php
new file mode 100644
index 000000000..28e5b2031
--- /dev/null
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/LanguageHandlingTest.php
@@ -0,0 +1,116 @@
+drupalCreateContentType(['type' => 'article']);
+
+ // Setup admin user.
+ $this->adminAccount = $this->drupalCreateUser([
+ 'access administration pages',
+ 'access content',
+ 'administer languages',
+ 'administer url aliases',
+ 'create article content',
+ 'edit any article content',
+ 'edit own article content',
+ ]);
+
+ $this->drupalLogin($this->adminAccount);
+
+ // Add the German language.
+ $this->drupalGet('admin/config/regional/language/add');
+ $this->submitForm(['predefined_langcode' => 'de'], 'Add language');
+ $this->assertSession()->pageTextContains('The language German has been created and can now be used.');
+
+ // Set admin user language to German.
+ $this->adminAccount->set('preferred_langcode', 'de')->save();
+
+ // Set up detection and selection to not use URL detection.
+ $this->drupalGet('admin/config/regional/language/detection');
+ $this->submitForm([
+ 'language_interface[enabled][language-url]' => 0,
+ 'language_interface[enabled][language-user]' => 1,
+ ], 'Save settings');
+
+ $this->assertSession()->pageTextContains('Language detection configuration saved.');
+
+ $this->drupalLogout();
+ }
+
+ /**
+ * Tests URL aliases work.
+ */
+ public function testPathAlias() {
+ // Login as admin with German as site language.
+ $this->drupalLogin($this->adminAccount);
+
+ // Create article with alias in sites default language (English).
+ $this->drupalGet('node/add/article');
+ $this->assertSession()->statusCodeEquals(200);
+ $alias = '/test-content';
+ $edit = [
+ 'path[0][alias]' => $alias,
+ 'title[0][value]' => 'Test content',
+ ];
+ $this->submitForm($edit, 'Save');
+
+ // Check that article was created and check address.
+ $this->assertSession()->statusCodeEquals(200);
+ $this->assertSession()->addressEquals($alias);
+
+ // Test that the canonical link is the same as address.
+ $xpath = $this->assertSession()->buildXPathQuery("//link[@rel=:rel and contains(@href, :href)]", [
+ ':href' => $alias,
+ ':rel' => 'canonical',
+ ]);
+ $links = $this->getSession()->getPage()->findAll('xpath', $xpath);
+
+ $this->assertNotEmpty($links);
+ }
+
+}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagAdminTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagAdminTest.php
index 7cdef7d9c..2c09268e8 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagAdminTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagAdminTest.php
@@ -521,7 +521,7 @@ class MetatagAdminTest extends BrowserTestBase {
$session->pageTextNotContains('Meta Tags: robots length');
// Test if option for a trimmable metatag exists:
$session->pageTextContains('Meta Tags: description length');
- // Test if the the title,abstract and description header gets trimmed:
+ // Test if the title,abstract and description header gets trimmed:
// Change description abstract and title on the front page:
$this->drupalGet('/admin/config/search/metatag/front');
$page->fillField('edit-title', 'my wonderful drupal test site');
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFieldTestBase.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFieldTestBase.php
index 2a73978e9..9002fac04 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFieldTestBase.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFieldTestBase.php
@@ -281,7 +281,7 @@ abstract class MetatagFieldTestBase extends BrowserTestBase {
*
* When there is no field for overriding the defaults.
*
- * @todo
+ * @todo Write this.
*/
public function testBundleDefaultsInheritance() {
}
@@ -353,7 +353,7 @@ abstract class MetatagFieldTestBase extends BrowserTestBase {
}
// Create a new entity object.
- $this->submitForm($edit, $this->t($this->entitySaveButtonLabel));
+ $this->submitForm($edit, $this->entitySaveButtonLabel);
$entities = \Drupal::entityTypeManager()
->getStorage($this->entityType)
->loadByProperties([$this->entityTitleField => $title]);
@@ -436,7 +436,7 @@ abstract class MetatagFieldTestBase extends BrowserTestBase {
}
// Create a new entity object.
- $this->submitForm($edit, $this->t($this->entitySaveButtonLabel));
+ $this->submitForm($edit, $this->entitySaveButtonLabel);
$entities = \Drupal::entityTypeManager()
->getStorage($this->entityType)
->loadByProperties([$this->entityTitleField => $title]);
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFieldUserTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFieldUserTest.php
index baa76318a..5ffda1b7e 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFieldUserTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFieldUserTest.php
@@ -95,14 +95,14 @@ class MetatagFieldUserTest extends MetatagFieldTestBase {
/**
* Confirm the metatag field can be shown on a user registration page.
*
- * @todo
+ * @todo Write this.
*/
public function testFieldsOnUserRegistrationForm() {}
/**
* Confirm the metatag field can be shown on a normal user's own edit form.
*
- * @todo
+ * @todo Write this.
*/
public function testFieldsOnUserEditForm() {}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagForumTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagForumTest.php
index 74d662302..1a2b9dae9 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagForumTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagForumTest.php
@@ -56,7 +56,10 @@ class MetatagForumTest extends BrowserTestBase {
$this->drupalLogin($this->adminUser);
// Create content type.
- $this->drupalCreateContentType(['type' => 'page', 'display_submitted' => FALSE]);
+ $this->drupalCreateContentType([
+ 'type' => 'page',
+ 'display_submitted' => FALSE,
+ ]);
$this->nodeId = $this->drupalCreateNode(
[
'title' => $this->randomMachineName(8),
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFrontpageTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFrontpageTest.php
index a5339a60c..9f729f856 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFrontpageTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagFrontpageTest.php
@@ -48,14 +48,19 @@ class MetatagFrontpageTest extends BrowserTestBase {
$this->loginUser1();
// Create content type.
- $this->drupalCreateContentType(['type' => 'page', 'display_submitted' => FALSE]);
+ $this->drupalCreateContentType([
+ 'type' => 'page',
+ 'display_submitted' => FALSE,
+ ]);
$this->nodeId = $this->drupalCreateNode(
[
'title' => $this->randomMachineName(8),
'promote' => 1,
])->id();
- $this->config('system.site')->set('page.front', '/node/' . $this->nodeId)->save();
+ $this->config('system.site')
+ ->set('page.front', '/node/' . $this->nodeId)
+ ->save();
}
/**
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagStringTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagStringTest.php
index af65b2cb8..d1471a289 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagStringTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagStringTest.php
@@ -63,7 +63,10 @@ class MetatagStringTest extends BrowserTestBase {
$this->adminUser = $this->drupalCreateUser($this->permissions);
$this->drupalLogin($this->adminUser);
- $this->drupalCreateContentType(['type' => 'page', 'display_submitted' => FALSE]);
+ $this->drupalCreateContentType([
+ 'type' => 'page',
+ 'display_submitted' => FALSE,
+ ]);
// Add a Metatag field to the content type.
$this->drupalGet('admin/structure/types');
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagTypesTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagTypesTest.php
index ae0c4ff71..2d11b2df1 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagTypesTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagTypesTest.php
@@ -92,7 +92,8 @@ class MetatagTagTypesTest extends BrowserTestBase {
];
$this->submitForm($edit, $this->t('Save and continue'));
$this->submitForm([], $this->t('Save field settings'));
- $this->container->get('entity_field.manager')->clearCachedFieldDefinitions();
+ $this->container->get('entity_field.manager')
+ ->clearCachedFieldDefinitions();
}
/**
@@ -173,7 +174,7 @@ class MetatagTagTypesTest extends BrowserTestBase {
* @todo Finish.
*/
public function todoTestUrl() {
- // {@code}
+ // @code
// $save_label = (floatval(\Drupal::VERSION) <= 8.3) ? $this->t('Save and publish') : $this->t('Save');
// // Tests meta tags with URLs work.
// $this->drupalGet($this->entity_add_path);
@@ -194,7 +195,7 @@ class MetatagTagTypesTest extends BrowserTestBase {
// $elements = $this->cssSelect("meta[name='original-source']");
// $this->assertTrue(count($elements) === 1, 'Found original source metatag from defaults');
// $this->assertEquals($edit['field_metatag[0][advanced][original_source]'], (string) $elements[0]['content']);
- // {@endcode}
+ // @endcode
}
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagsTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagsTest.php
index 09b31628d..25f1aafcf 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagsTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagsTest.php
@@ -14,6 +14,7 @@ class MetatagTagsTest extends MetatagTagsTestBase {
*/
protected $tags = [
'abstract',
+ 'author',
'cache_control',
'canonical_url',
'content_language',
@@ -84,20 +85,6 @@ class MetatagTagsTest extends MetatagTagsTestBase {
return "//textarea[@name='abstract']";
}
- /**
- * Implements {tag_name}TestNameAttribute() for 'author'.
- */
- protected function authorTestOutputXpath() {
- return "//link[@rel='author']";
- }
-
- /**
- * Implements {tag_name}TestValueAttribute() for 'author'.
- */
- protected function authorTestValueAttribute() {
- return 'href';
- }
-
/**
* Implements {tag_name}TestNameAttribute() for 'canonical_url'.
*/
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagsTestBase.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagsTestBase.php
index 289611b5d..b2a57d6eb 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagsTestBase.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTagsTestBase.php
@@ -195,9 +195,9 @@ abstract class MetatagTagsTestBase extends BrowserTestBase {
// Look for a custom method named "{$tag_name}TestOutputXpath", if
// found use that method to get the xpath definition for this meta tag,
// otherwise it defaults to just looking for a meta tag matching:
- // {@code}
+ // @code
// <$testTag $testNameAttribute=$tag_name $testValueAttribute=$value />
- // {@endcode}
+ // @endcode
$method = $this->getMethodFromTagCallback($tag_name, 'TestOutputXpath');
if (method_exists($this, $method)) {
$xpath_string = $this->$method();
@@ -253,7 +253,11 @@ abstract class MetatagTagsTestBase extends BrowserTestBase {
// Extract the meta tag from the HTML.
$xpath = $this->xpath($xpath_string);
- $this->assertCount(1, $xpath, new FormattableMarkup('One @tag tag found using @xpath.', ['@tag' => $tag_name, '@xpath' => $xpath_string]));
+ $message = new FormattableMarkup('One @tag tag found using @xpath.', [
+ '@tag' => $tag_name,
+ '@xpath' => $xpath_string,
+ ]);
+ $this->assertCount(1, $xpath, $message);
if (count($xpath) !== 1) {
$this->verbose($xpath, $tag_name . ': ' . $xpath_string);
}
@@ -278,7 +282,11 @@ abstract class MetatagTagsTestBase extends BrowserTestBase {
else {
$this->verbose($xpath, $tag_name . ': ' . $xpath_string);
$this->assertTrue((string) $xpath[0]);
- $this->assertEquals((string) $xpath[0], $all_values[$tag_name], new FormattableMarkup("The '@tag' tag was found with the expected value '@value'.", ['@tag' => $tag_name, '@value' => $all_values[$tag_name]]));
+ $message = new FormattableMarkup("The '@tag' tag was found with the expected value '@value'.", [
+ '@tag' => $tag_name,
+ '@value' => $all_values[$tag_name],
+ ]);
+ $this->assertEquals((string) $xpath[0], $all_values[$tag_name], $message);
}
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTokenStatus.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTokenStatus.php
index 892a8ec23..0b2ea8ab7 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTokenStatus.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTokenStatus.php
@@ -10,8 +10,7 @@ use Drupal\Tests\BrowserTestBase;
*
* @group metatag
*/
-class MetatagTokenStatus extends BrowserTestBase
-{
+class MetatagTokenStatus extends BrowserTestBase {
/**
* {@inheritdoc}
@@ -28,8 +27,7 @@ class MetatagTokenStatus extends BrowserTestBase
*
* @see token_get_token_problems
*/
- function testStatusReportTypesWarning()
- {
+ public function testStatusReportTypesWarning() {
$this->drupalLogin($this->rootUser);
$this->drupalGet(Url::fromRoute('system.status'));
@@ -41,8 +39,7 @@ class MetatagTokenStatus extends BrowserTestBase
*
* @see token_get_token_problems
*/
- function testStatusReportTokensWarning()
- {
+ public function testStatusReportTokensWarning() {
$this->drupalLogin($this->rootUser);
$this->drupalGet(Url::fromRoute('system.status'));
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTokenTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTokenTest.php
index 85af494fe..112a8e92a 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTokenTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagTokenTest.php
@@ -27,6 +27,7 @@ class MetatagTokenTest extends BrowserTestBase {
'token_module_test',
'metatag',
'metatag_open_graph',
+ 'metatag_favicons',
];
/**
@@ -95,6 +96,7 @@ class MetatagTokenTest extends BrowserTestBase {
'field_metatags[0][basic][abstract]' => 'My abstract',
'field_metatags[0][open_graph][og_title]' => 'My OG Title',
'field_metatags[0][open_graph][og_image]' => 'Image 1,Image 2',
+ 'field_metatags[0][favicons][mask_icon][href]' => 'mask_icon.svg',
], 'Save');
$tokens = [
@@ -110,6 +112,8 @@ class MetatagTokenTest extends BrowserTestBase {
'[user:field_metatags:og_image]' => 'Image 1,Image 2',
'[user:field_metatags:og_image:0]' => 'Image 1',
'[user:field_metatags:og_image:1]' => 'Image 2',
+ // Test metatags that store value as an array.
+ '[user:field_metatags:mask_icon]' => 'mask_icon.svg',
];
$this->assertPageTokens($user->toUrl(), $tokens, ['user' => $user]);
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagXssTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagXssTest.php
index e50990c17..588d8f8c0 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagXssTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Functional/MetatagXssTest.php
@@ -101,7 +101,10 @@ class MetatagXssTest extends BrowserTestBase {
$this->drupalLogin($this->adminUser);
// Set up a content type.
- $this->drupalCreateContentType(['type' => 'metatag_node', 'name' => 'Test Content Type']);
+ $this->drupalCreateContentType([
+ 'type' => 'metatag_node',
+ 'name' => 'Test Content Type',
+ ]);
// Add a metatag field to the content type.
$this->drupalGet('admin/structure/types/manage/metatag_node/fields/add-field');
@@ -215,9 +218,9 @@ class MetatagXssTest extends BrowserTestBase {
$this->submitForm($edit, 'Save');
// Check the body text.
- // {@code}
+ // @code
// $this->assertNoTitle($this->xssTitleString);
- // {@endcode}
+ // @endcode
$session->responseNotContains($this->xssTitleString);
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/FunctionalJavascript/MetatagAvailableTokensTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/FunctionalJavascript/MetatagAvailableTokensTest.php
index 0b27bd120..2f2da019b 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/FunctionalJavascript/MetatagAvailableTokensTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/FunctionalJavascript/MetatagAvailableTokensTest.php
@@ -25,7 +25,7 @@ class MetatagAvailableTokensTest extends WebDriverTestBase {
/**
* Test the node metatag defaults page.
*/
- function testNodeMetatagDefaultsPage() {
+ public function testNodeMetatagDefaultsPage() {
$this->drupalLogin($this->rootUser);
$this->drupalGet(Url::fromRoute('entity.metatag_defaults.edit_form', ['metatag_defaults' => 'node']));
$page = $this->getSession()->getPage();
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/MetatagManagerTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/MetatagManagerTest.php
index 9d0dffe25..413df26f8 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/MetatagManagerTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/MetatagManagerTest.php
@@ -52,7 +52,14 @@ class MetatagManagerTest extends KernelTestBase {
$this->entityTypeManager = $this->container->get('entity_type.manager');
$this->metatagManager = $this->container->get('metatag.manager');
- $this->installConfig(['system', 'field', 'text', 'user', 'metatag', 'metatag_open_graph']);
+ $this->installConfig([
+ 'system',
+ 'field',
+ 'text',
+ 'user',
+ 'metatag',
+ 'metatag_open_graph',
+ ]);
$this->installEntitySchema('user');
$this->installSchema('user', ['users_data']);
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Migrate/d7/MetatagEntitiesTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Migrate/d7/MetatagEntitiesTest.php
index 5e5b491f0..b19d186d6 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Migrate/d7/MetatagEntitiesTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Migrate/d7/MetatagEntitiesTest.php
@@ -123,8 +123,8 @@ class MetatagEntitiesTest extends MigrateDrupal7TestBase {
// This should have the "current revision" keywords value, indicating it is
// the current revision.
$expected = [
- 'keywords' => 'current revision',
'canonical_url' => 'the-node',
+ 'keywords' => 'current revision',
'robots' => 'noindex, nofollow',
];
$this->assertSame(serialize($expected), $node->field_metatag->value);
@@ -135,8 +135,8 @@ class MetatagEntitiesTest extends MigrateDrupal7TestBase {
// This should have the "old revision" keywords value, indicating it is
// a non-current revision.
$expected = [
- 'keywords' => 'old revision',
'canonical_url' => 'the-node',
+ 'keywords' => 'old revision',
'robots' => 'noindex, nofollow',
];
$this->assertSame(serialize($expected), $node->field_metatag->value);
@@ -147,9 +147,9 @@ class MetatagEntitiesTest extends MigrateDrupal7TestBase {
$this->assertTrue($user->hasField('field_metatag'));
// This should have the Utf8 converted description value.
$expected = [
- 'keywords' => 'a user',
'canonical_url' => 'the-user',
'description' => 'Drupalâ„¢ user',
+ 'keywords' => 'a user',
];
$this->assertSame(serialize($expected), $user->field_metatag->value);
@@ -158,8 +158,8 @@ class MetatagEntitiesTest extends MigrateDrupal7TestBase {
$this->assertInstanceOf(TermInterface::class, $term);
$this->assertTrue($term->hasField('field_metatag'));
$expected = [
- 'keywords' => 'a taxonomy',
'canonical_url' => 'the-term',
+ 'keywords' => 'a taxonomy',
];
$this->assertSame(serialize($expected), $term->field_metatag->value);
}
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Plugin/migrate/source/d6/NodewordsFieldInstanceTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Plugin/migrate/source/d6/NodewordsFieldInstanceTest.php
index 553216fda..db89401ec 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Plugin/migrate/source/d6/NodewordsFieldInstanceTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Plugin/migrate/source/d6/NodewordsFieldInstanceTest.php
@@ -39,7 +39,10 @@ class NodewordsFieldInstanceTest extends MigrateSqlSourceTestBase {
'metatag',
];
- public function setUp() {
+ /**
+ * {@inheritdoc}
+ */
+ public function setUp(): void {
parent::setUp();
$this->installEntitySchema('node');
$this->installEntitySchema('taxonomy_term');
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Plugin/migrate/source/d7/MetatagFieldInstanceTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Plugin/migrate/source/d7/MetatagFieldInstanceTest.php
index df9be4c1a..7f00292c1 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Plugin/migrate/source/d7/MetatagFieldInstanceTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Kernel/Plugin/migrate/source/d7/MetatagFieldInstanceTest.php
@@ -36,7 +36,10 @@ class MetatagFieldInstanceTest extends MigrateSqlSourceTestBase {
'metatag',
];
- public function setUp() {
+ /**
+ * {@inheritdoc}
+ */
+ public function setUp(): void {
parent::setUp();
$this->installEntitySchema('node');
$this->installEntitySchema('taxonomy_term');
@@ -54,8 +57,10 @@ class MetatagFieldInstanceTest extends MigrateSqlSourceTestBase {
]);
$node_type->save();
}
+ // @code
// ['taxonomy_term', ['test_vocabulary' => 'test_vocabulary']],
// Vocabulary::create(['name' => 'test_vocabulary']);
+ // @endcode
// Setup vocabulary.
Vocabulary::create([
'vid' => 'test_vocabulary',
@@ -63,7 +68,7 @@ class MetatagFieldInstanceTest extends MigrateSqlSourceTestBase {
])->save();
// Create a term and a comment.
- $term = Term::create([
+ Term::create([
'vid' => 'test_vocabulary',
'name' => 'term',
])->save();
diff --git a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Unit/MetatagTrimmerTest.php b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Unit/MetatagTrimmerTest.php
index 98ef3b2d4..ec56551d2 100644
--- a/frontend/drupal9/web/modules/contrib/metatag/tests/src/Unit/MetatagTrimmerTest.php
+++ b/frontend/drupal9/web/modules/contrib/metatag/tests/src/Unit/MetatagTrimmerTest.php
@@ -40,6 +40,8 @@ class MetatagTrimmerTest extends UnitTestCase {
$this->assertEquals('Test', $trimResult3);
$trimResult4 = $this->metatagTrimmer->trimBeforeValue('Test 123 123', 10);
$this->assertEquals('Test 123', $trimResult4);
+ $trimResult5 = $this->metatagTrimmer->trimBeforeValue('Test 123 123', 20);
+ $this->assertEquals('Test 123 123', $trimResult5);
}
/**
@@ -54,6 +56,8 @@ class MetatagTrimmerTest extends UnitTestCase {
$this->assertEquals($trimResult3, 'Test');
$trimResult4 = $this->metatagTrimmer->trimAfterValue('Test 123 123', 10);
$this->assertEquals('Test 123 123', $trimResult4);
+ $trimResult5 = $this->metatagTrimmer->trimAfterValue('Test 123 123', 20);
+ $this->assertEquals('Test 123 123', $trimResult5);
}
/**