Commit 2dd7bfd9 authored by WalkingDexter's avatar WalkingDexter Committed by WalkingDexter
Browse files

Issue #3143229 by WalkingDexter, beloa: Support wildcards in the view path

parent 625fa3a7
......@@ -127,8 +127,13 @@ class ViewsUrlGenerator extends EntityUrlGeneratorBase {
'view_id' => $view->id(),
'display_id' => $view->current_display,
];
$extender = $this->sitemapViews->getDisplayExtender($view);
// View path without arguments.
$data_sets[] = $base_data_set + ['arguments' => NULL];
if (!$extender->hasRequiredArguments()) {
$data_sets[] = $base_data_set + ['arguments' => NULL];
}
// Process indexed arguments.
if ($args_ids = $this->sitemapViews->getIndexableArguments($view, $this->sitemapVariant)) {
......
......@@ -104,6 +104,7 @@ class SimpleSitemapDisplayExtender extends DisplayExtenderPluginBase {
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
if ($this->hasSitemapSettings() && $form_state->get('section') == 'simple_sitemap') {
$has_required_arguments = $this->hasRequiredArguments();
$arguments_options = $this->getArgumentsOptions();
$form['variants'] = [
......@@ -166,6 +167,11 @@ class SimpleSitemapDisplayExtender extends DisplayExtenderPluginBase {
'#states' => $states,
];
// Required arguments are always indexed.
foreach ($this->getRequiredArguments() as $argument_id) {
$variant_form['arguments'][$argument_id]['#disabled'] = TRUE;
}
// Max links with arguments.
$variant_form['max_links'] = [
'#type' => 'number',
......@@ -173,7 +179,7 @@ class SimpleSitemapDisplayExtender extends DisplayExtenderPluginBase {
'#description' => $this->t('The maximum number of link variations to be indexed for this display. If left blank, each argument will create link variations for this display. Use with caution, as a large number of argument values​can significantly increase the number of sitemap links.'),
'#default_value' => $settings['max_links'],
'#min' => 1,
'#access' => !empty($arguments_options),
'#access' => !empty($arguments_options) || $has_required_arguments,
'#states' => $states,
];
}
......@@ -188,8 +194,11 @@ class SimpleSitemapDisplayExtender extends DisplayExtenderPluginBase {
*/
public function validateOptionsForm(&$form, FormStateInterface $form_state) {
if ($this->hasSitemapSettings() && $form_state->get('section') == 'simple_sitemap') {
$required_arguments = $this->getRequiredArguments();
foreach (array_keys($this->variants) as $variant) {
$arguments = $form_state->getValue(['variants', $variant, 'arguments'], []);
$arguments = &$form_state->getValue(['variants', $variant, 'arguments'], []);
$arguments = array_merge($arguments, $required_arguments);
$errors = $this->validateIndexedArguments($arguments);
foreach ($errors as $message) {
......@@ -287,6 +296,14 @@ class SimpleSitemapDisplayExtender extends DisplayExtenderPluginBase {
if (isset($this->options['variants'][$variant])) {
$settings = $this->options['variants'][$variant] + $settings;
}
if (empty($this->displayHandler->getHandlers('argument'))) {
$settings['arguments'] = [];
}
else {
$required_arguments = $this->getRequiredArguments();
$settings['arguments'] = array_merge($settings['arguments'], $required_arguments);
}
return $settings;
}
......@@ -300,6 +317,50 @@ class SimpleSitemapDisplayExtender extends DisplayExtenderPluginBase {
return $this->displayHandler instanceof DisplayRouterInterface;
}
/**
* Gets required view arguments (presented in the path).
*
* @return array
* View arguments IDs.
*/
public function getRequiredArguments() {
$arguments = $this->displayHandler->getHandlers('argument');
if (!empty($arguments)) {
$bits = explode('/', $this->displayHandler->getPath());
$arg_counter = 0;
foreach ($bits as $bit) {
if ($bit == '%' || strpos($bit, '%') === 0) {
$arg_counter++;
}
}
if ($arg_counter > 0) {
$arguments = array_slice(array_keys($arguments), 0, $arg_counter);
return array_combine($arguments, $arguments);
}
}
return [];
}
/**
* Determines if the view path contains required arguments.
*
* @return bool
* TRUE if the path contains required arguments, FALSE if not.
*/
public function hasRequiredArguments() {
$bits = explode('/', $this->displayHandler->getPath());
foreach ($bits as $bit) {
if ($bit == '%' || strpos($bit, '%') === 0) {
return TRUE;
}
}
return FALSE;
}
/**
* Returns available view arguments options.
*
......
......@@ -137,19 +137,17 @@ class SimpleSitemapViews {
}
/**
* Gets the sitemap settings for view display.
* Gets the display extender.
*
* @param \Drupal\views\ViewExecutable $view
* A view executable instance.
* @param string $variant
* The name of the sitemap variant.
* @param string|null $display_id
* The display id. If empty uses the current display.
*
* @return array|null
* The sitemap settings if the display is indexed, NULL otherwise.
* @return \Drupal\simple_sitemap_views\Plugin\views\display_extender\SimpleSitemapDisplayExtender|null
* The display extender.
*/
public function getSitemapSettings(ViewExecutable $view, $variant, $display_id = NULL) {
public function getDisplayExtender(ViewExecutable $view, $display_id = NULL) {
// Ensure the display was correctly set.
if (!$view->setDisplay($display_id)) {
return NULL;
......@@ -158,8 +156,30 @@ class SimpleSitemapViews {
$extenders = $view->display_handler->getExtenders();
$extender = isset($extenders[self::PLUGIN_ID]) ? $extenders[self::PLUGIN_ID] : NULL;
if ($extender instanceof SimpleSitemapDisplayExtender) {
return $extender;
}
return NULL;
}
/**
* Gets the sitemap settings for view display.
*
* @param \Drupal\views\ViewExecutable $view
* A view executable instance.
* @param string $variant
* The name of the sitemap variant.
* @param string|null $display_id
* The display id. If empty uses the current display.
*
* @return array|null
* The sitemap settings if the display is indexed, NULL otherwise.
*/
public function getSitemapSettings(ViewExecutable $view, $variant, $display_id = NULL) {
$extender = $this->getDisplayExtender($view, $display_id);
// Retrieve the sitemap settings from the extender.
if ($extender instanceof SimpleSitemapDisplayExtender && $extender->hasSitemapSettings()) {
if ($extender && $extender->hasSitemapSettings()) {
$settings = $extender->getSitemapSettings($variant);
if ($settings['index']) {
......@@ -187,14 +207,31 @@ class SimpleSitemapViews {
$indexable_arguments = [];
// Find indexable arguments.
if ($settings && !empty($settings['arguments'])) {
if ($settings) {
$arguments = array_keys($view->display_handler->getHandlers('argument'));
$bits = explode('/', $view->getPath());
$arg_index = 0;
// Required arguments.
foreach ($bits as $bit) {
if ($bit == '%' || strpos($bit, '%') === 0) {
$indexable_arguments[] = isset($arguments[$arg_index]) ? $arguments[$arg_index] : $bit;
$arg_index++;
}
}
if (!empty($settings['arguments'])) {
if ($arg_index > 0) {
$arguments = array_slice($arguments, $arg_index);
}
foreach ($arguments as $argument_id) {
if (empty($settings['arguments'][$argument_id])) {
break;
// Optional arguments.
foreach ($arguments as $argument_id) {
if (empty($settings['arguments'][$argument_id])) {
break;
}
$indexable_arguments[] = $argument_id;
}
$indexable_arguments[] = $argument_id;
}
}
return $indexable_arguments;
......
......@@ -281,3 +281,72 @@ display:
- 'user.node_grants:view'
- user.permissions
tags: { }
page_2:
display_plugin: page
id: page_2
display_title: 'Page 2'
position: 2
display_options:
display_extenders:
simple_sitemap_display_extender:
variants:
default:
index: true
priority: '0.5'
changefreq: ''
arguments: { }
max_links: 2
path: simple-sitemap-views-test-view-2/%node_type/%
rendering_language: en
arguments:
type:
id: type
table: node_field_data
field: type
relationship: none
group_type: group
admin_label: ''
default_action: ignore
exception:
value: all
title_enable: false
title: All
title_enable: false
title: ''
default_argument_type: fixed
default_argument_options:
argument: ''
default_argument_skip_url: false
summary_options:
base_path: ''
count: true
items_per_page: 25
override: false
summary:
sort_order: asc
number_of_records: 0
format: default_summary
specify_validation: false
validate:
type: none
fail: 'not found'
validate_options: { }
glossary: false
limit: 0
case: none
path_case: none
transform_dash: false
break_phrase: false
entity_type: node
entity_field: type
plugin_id: node_type
defaults:
arguments: false
cache_metadata:
max-age: -1
contexts:
- 'languages:language_interface'
- url
- 'user.node_grants:view'
- user.permissions
tags: { }
......@@ -46,6 +46,11 @@ class SimpleSitemapViewsTest extends SimpleSitemapViewsTestBase {
$this->assertContains('type', $indexable_arguments);
$this->assertContains('title', $indexable_arguments);
$this->assertNotContains('nid', $indexable_arguments);
// Check the indexing status of the required arguments.
$indexable_arguments = $this->sitemapViews->getIndexableArguments($this->testView2, $this->sitemapVariant);
$this->assertContains('type', $indexable_arguments);
$this->assertContains('%', $indexable_arguments);
}
/**
......@@ -77,6 +82,10 @@ class SimpleSitemapViewsTest extends SimpleSitemapViewsTestBase {
$args = ['page', $this->node2->getTitle()];
$this->sitemapViews->addArgumentsToIndex($this->testView, $args);
$this->assertIndexSize(2);
// Required arguments must be indexed.
$this->sitemapViews->addArgumentsToIndex($this->testView2, ['page', 1]);
$this->assertIndexSize(3);
}
/**
......@@ -89,14 +98,22 @@ class SimpleSitemapViewsTest extends SimpleSitemapViewsTestBase {
$title = $this->node->getTitle();
$this->sitemapViews->addArgumentsToIndex($this->testView, ['page']);
$this->sitemapViews->addArgumentsToIndex($this->testView, ['page', $title]);
$this->sitemapViews->addArgumentsToIndex($this->testView2, ['page', 1]);
$this->generator->generateSitemap('backend');
$url1 = $this->testView->getUrl()->toString();
$url2 = $this->testView->getUrl(['page', NULL, NULL])->toString();
$url3 = $this->testView->getUrl(['page', $title, NULL])->toString();
$url4 = $this->testView2->getUrl()->toString();
$url5 = $this->testView2->getUrl(['page', 1])->toString();
// Check that the sitemap contains view display URLs.
$this->drupalGet($this->defaultSitemapUrl);
$test_view_url = $this->testView->getUrl()->toString();
$this->assertSession()->responseContains($test_view_url);
$this->assertSession()->responseContains("$test_view_url/page");
$this->assertSession()->responseContains("$test_view_url/page/$title");
$this->assertSession()->responseContains($url1);
$this->assertSession()->responseContains($url2);
$this->assertSession()->responseContains($url3);
$this->assertSession()->responseNotContains($url4);
$this->assertSession()->responseContains($url5);
}
/**
......
......@@ -40,6 +40,13 @@ abstract class SimpleSitemapViewsTestBase extends SimplesitemapTestBase {
*/
protected $testView;
/**
* Test view 2.
*
* @var \Drupal\views\ViewExecutable
*/
protected $testView2;
/**
* The sitemap variant.
*
......@@ -59,6 +66,9 @@ abstract class SimpleSitemapViewsTestBase extends SimplesitemapTestBase {
$this->testView = Views::getView('simple_sitemap_views_test_view');
$this->testView->setDisplay('page_1');
$this->testView2 = Views::getView('simple_sitemap_views_test_view');
$this->testView2->setDisplay('page_2');
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment