diff --git a/core/modules/node/node.views.inc b/core/modules/node/node.views.inc index 136628faa8d746ad672aa959a7fc6d544940445a..742ec5054f5cbeb9b694ad8b737997c1165c22da 100644 --- a/core/modules/node/node.views.inc +++ b/core/modules/node/node.views.inc @@ -619,6 +619,81 @@ function node_views_data() { ), ); + // Add search table, fields, filters, etc., but only if a page using the + // node_search plugin is enabled. + if (\Drupal::moduleHandler()->moduleExists('search')) { + $enabled = FALSE; + $search_page_repository = \Drupal::service('search.search_page_repository'); + foreach ($search_page_repository->getActiveSearchpages() as $page) { + if ($page->getPlugin()->getPluginId() == 'node_search') { + $enabled = TRUE; + break; + } + } + + if ($enabled) { + $data['node_search_index']['table']['group'] = t('Search'); + + // Automatically join to the node table. Use a Views table alias to + // allow other modules to use this table too, if they use the search + // index. + $data['node_search_index']['table']['join'] = array( + 'node' => array( + 'left_field' => 'nid', + 'field' => 'sid', + 'table' => 'search_index', + 'extra' => "node_search_index.type = 'node_search'", + ) + ); + + $data['node_search_total']['table']['join'] = array( + 'node_search_index' => array( + 'left_field' => 'word', + 'field' => 'word', + ), + ); + + $data['node_search_dataset']['table']['join'] = array( + 'node_search_index' => array( + 'left_field' => 'sid', + 'field' => 'sid', + 'extra' => 'node_search_index.type = node_search_dataset.type', + 'type' => 'INNER', + ), + ); + + $data['node_search_index']['score'] = array( + 'title' => t('Score'), + 'help' => t('The score of the search item. This will not be used if the search filter is not also present.'), + 'field' => array( + 'id' => 'search_score', + 'float' => TRUE, + 'no group by' => TRUE, + ), + 'sort' => array( + 'id' => 'search_score', + 'no group by' => TRUE, + ), + ); + + $data['node_search_index']['keys'] = array( + 'title' => t('Search Keywords'), + 'help' => t('The keywords to search for.'), + 'filter' => array( + 'id' => 'search_keywords', + 'no group by' => TRUE, + 'search_type' => 'node_search', + ), + 'argument' => array( + 'id' => 'search', + 'no group by' => TRUE, + 'search_type' => 'node_search', + ), + ); + + } + } + return $data; } diff --git a/core/modules/search/lib/Drupal/search/Plugin/views/argument/Search.php b/core/modules/search/lib/Drupal/search/Plugin/views/argument/Search.php index f2dc58b31ba90dd5a3835640ab9cc62f2c9502e1..6dcb8cd0825b66117cec9fc3ddb6fbc4695b5ac0 100644 --- a/core/modules/search/lib/Drupal/search/Plugin/views/argument/Search.php +++ b/core/modules/search/lib/Drupal/search/Plugin/views/argument/Search.php @@ -8,9 +8,12 @@ namespace Drupal\search\Plugin\views\argument; use Drupal\views\Plugin\views\argument\ArgumentPluginBase; +use Drupal\views\Plugin\views\display\DisplayPluginBase; +use Drupal\views\ViewExecutable; +use Drupal\views\Views; /** - * Argument that accepts query keys for search. + * Argument handler for search keywords. * * @ingroup views_argument_handlers * @@ -19,30 +22,53 @@ class Search extends ArgumentPluginBase { /** - * Make sure that parseSearchExpression is run and everything is set up. + * A search query to use for parsing search keywords. * - * @param $input - * The search phrase which was input by the user. + * @var \Drupal\search\ViewsSearchQuery */ - function query_parse_search_expression($input) { - if (!isset($this->search_query)) { - $this->search_query = db_select('search_index', 'i', array('target' => 'slave'))->extend('Drupal\search\ViewsSearchQuery'); - $this->search_query->searchExpression($input, $this->view->base_table); - $this->search_query->publicParseSearchExpression(); + protected $searchQuery = NULL; + + /** + * The search type name (value of {search_index}.type in the database). + * + * @var string + */ + protected $searchType; + + /** + * {@inheritdoc} + */ + public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { + parent::init($view, $display, $options); + + $this->searchType = $this->definition['search_type']; + } + + /** + * Sets up and parses the search query. + * + * @param string $input + * The search keywords entered by the user. + */ + protected function queryParseSearchExpression($input) { + if (!isset($this->searchQuery)) { + $this->searchQuery = db_select('search_index', 'i', array('target' => 'slave'))->extend('Drupal\search\ViewsSearchQuery'); + $this->searchQuery->searchExpression($input, $this->searchType); + $this->searchQuery->publicParseSearchExpression(); } } /** - * Add this argument to the query. + * {@inheritdoc} */ public function query($group_by = FALSE) { $required = FALSE; - $this->query_parse_search_expression($this->argument); - if (!isset($this->search_query)) { + $this->queryParseSearchExpression($this->argument); + if (!isset($this->searchQuery)) { $required = TRUE; } else { - $words = $this->search_query->words(); + $words = $this->searchQuery->words(); if (empty($words)) { $required = TRUE; } @@ -64,28 +90,22 @@ public function query($group_by = FALSE) { 'left_table' => $search_index, 'left_field' => 'word', ); - $join = \Drupal::service()->get('plugin.manager.views.join')->createInstance('standard', $definition); + $join = Views::pluginManager('join')->createInstance('standard', $definition); $search_total = $this->query->addRelationship('search_total', $join, $search_index); $this->search_score = $this->query->addField('', "SUM($search_index.score * $search_total.count)", 'score', array('aggregate' => TRUE)); - if (empty($this->query->relationships[$this->relationship])) { - $base_table = $this->view->storage->get('base_table'); - } - else { - $base_table = $this->query->relationships[$this->relationship]['base']; - } - $search_condition->condition("$search_index.type", $base_table); + $search_condition->condition("$search_index.type", $this->searchType); - if (!$this->search_query->simple()) { + if (!$this->searchQuery->simple()) { $search_dataset = $this->query->addTable('search_dataset'); - $conditions = $this->search_query->conditions(); + $conditions = $this->searchQuery->conditions(); $condition_conditions =& $conditions->conditions(); foreach ($condition_conditions as $key => &$condition) { // Make sure we just look at real conditions. if (is_numeric($key)) { // Replace the conditions with the table alias of views. - $this->search_query->condition_replace_string('d.', "$search_dataset.", $condition); + $this->searchQuery->conditionReplaceString('d.', "$search_dataset.", $condition); } } $search_conditions =& $search_condition->conditions(); @@ -103,10 +123,14 @@ public function query($group_by = FALSE) { $this->query->addWhere(0, $search_condition); $this->query->addGroupBy("$search_index.sid"); - $matches = $this->search_query->matches(); + $matches = $this->searchQuery->matches(); $placeholder = $this->placeholder(); $this->query->addHavingExpression(0, "COUNT(*) >= $placeholder", array($placeholder => $matches)); } + + // Set to NULL to prevent PDO exception when views object is cached + // and to clear out memory. + $this->searchQuery = NULL; } } diff --git a/core/modules/search/lib/Drupal/search/Plugin/views/field/Score.php b/core/modules/search/lib/Drupal/search/Plugin/views/field/Score.php index 0fad572d188c08ffa9ea742950b9f3f4b5f2cd83..ceeb50023fbc13a989b556b61c034802d5ec1a4e 100644 --- a/core/modules/search/lib/Drupal/search/Plugin/views/field/Score.php +++ b/core/modules/search/lib/Drupal/search/Plugin/views/field/Score.php @@ -11,7 +11,7 @@ use Drupal\views\ResultRow; /** - * Field handler to provide simple renderer that allows linking to a node. + * Field handler for search score. * * @ingroup views_field_handlers * @@ -19,50 +19,16 @@ */ class Score extends Numeric { - protected function defineOptions() { - $options = parent::defineOptions(); - - $options['alternate_sort'] = array('default' => ''); - $options['alternate_order'] = array('default' => 'asc'); - - return $options; - } - - public function buildOptionsForm(&$form, &$form_state) { - $style_options = $this->view->display_handler->getOption('style_options'); - if (isset($style_options['default']) && $style_options['default'] == $this->options['id']) { - $handlers = $this->view->display_handler->getHandlers('field'); - $options = array('' => t('No alternate')); - foreach ($handlers as $id => $handler) { - $options[$id] = $handler->adminLabel(); - } - - $form['alternate_sort'] = array( - '#type' => 'select', - '#title' => t('Alternative sort'), - '#description' => t('Pick an alternative default table sort field to use when the search score field is unavailable.'), - '#options' => $options, - '#default_value' => $this->options['alternate_sort'], - ); - - $form['alternate_order'] = array( - '#type' => 'select', - '#title' => t('Alternate sort order'), - '#options' => array('asc' => t('Ascending'), 'desc' => t('Descending')), - '#default_value' => $this->options['alternate_order'], - ); - } - - parent::buildOptionsForm($form, $form_state); - } - + /** + * {@inheritdoc} + */ public function query() { // Check to see if the search filter added 'score' to the table. // Our filter stores it as $handler->search_score -- and we also // need to check its relationship to make sure that we're using the same // one or obviously this won't work. foreach ($this->view->filter as $handler) { - if (isset($handler->search_score) && $handler->relationship == $this->relationship) { + if (isset($handler->search_score) && ($handler->relationship == $this->relationship)) { $this->field_alias = $handler->search_score; $this->tableAlias = $handler->tableAlias; return; @@ -71,13 +37,6 @@ public function query() { // Hide this field if no search filter is in place. $this->options['exclude'] = TRUE; - if (!empty($this->options['alternate_sort'])) { - if (isset($this->view->style_plugin->options['default']) && $this->view->style_plugin->options['default'] == $this->options['id']) { - // Since the style handler initiates fields, we plug these values right into the active handler. - $this->view->style_plugin->options['default'] = $this->options['alternate_sort']; - $this->view->style_plugin->options['order'] = $this->options['alternate_order']; - } - } } /** @@ -89,5 +48,4 @@ public function render(ResultRow $values) { return parent::render($values); } } - } diff --git a/core/modules/search/lib/Drupal/search/Plugin/views/filter/Search.php b/core/modules/search/lib/Drupal/search/Plugin/views/filter/Search.php index 708595e76c3155e1e4b4bd8d22ed16b97f205c72..b65e746bd3397e103b057b3fb496631f92018774 100644 --- a/core/modules/search/lib/Drupal/search/Plugin/views/filter/Search.php +++ b/core/modules/search/lib/Drupal/search/Plugin/views/filter/Search.php @@ -7,35 +7,58 @@ namespace Drupal\search\Plugin\views\filter; -use Drupal\search\SearchQuery; use Drupal\views\Plugin\views\filter\FilterPluginBase; +use Drupal\views\Plugin\views\display\DisplayPluginBase; +use Drupal\views\ViewExecutable; +use Drupal\views\Views; /** - * Field handler to provide simple renderer that allows linking to a node. + * Filter handler for search keywords. * * @ingroup views_filter_handlers * - * @PluginID("search") + * @PluginID("search_keywords") */ class Search extends FilterPluginBase { + /** + * This filter is always considered multiple-valued. + * + * @var bool + */ protected $alwaysMultiple = TRUE; /** - * Stores an extended query extender from the search module. - * - * This value extends the query extender to be able to provide methods - * which returns the protected values. + * A search query to use for parsing search keywords. + * + * @var \Drupal\search\ViewsSearchQuery + */ + protected $searchQuery = NULL; + + /** + * TRUE if the search query has been parsed. + */ + protected $parsed = FALSE; + + /** + * The search type name (value of {search_index}.type in the database). * - * @var \Drupal\search\ViewsSearchQuery + * @var string */ - var $search_query = NULL; + protected $searchType; /** - * Checks if the search query has been parsed. + * {@inheritdoc} */ - var $parsed = FALSE; + public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { + parent::init($view, $display, $options); + $this->searchType = $this->definition['search_type']; + } + + /** + * {@inheritdoc} + */ protected function defineOptions() { $options = parent::defineOptions(); @@ -45,7 +68,7 @@ protected function defineOptions() { } /** - * Provide simple equality operator + * {@inheritdoc} */ protected function operatorForm(&$form, &$form_state) { $form['operator'] = array( @@ -53,27 +76,27 @@ protected function operatorForm(&$form, &$form_state) { '#title' => t('On empty input'), '#default_value' => $this->operator, '#options' => array( - 'optional' => t('Show All'), - 'required' => t('Show None'), + 'optional' => $this->t('Show All'), + 'required' => $this->t('Show None'), ), ); } /** - * Provide a simple textfield for equality + * {@inheritdoc} */ protected function valueForm(&$form, &$form_state) { $form['value'] = array( '#type' => 'textfield', '#size' => 15, '#default_value' => $this->value, - '#attributes' => array('title' => t('Enter the terms you wish to search for.')), - '#title' => empty($form_state['exposed']) ? t('Value') : '', + '#attributes' => array('title' => $this->t('Search keywords')), + '#title' => empty($form_state['exposed']) ? $this->t('Keywords') : '', ); } /** - * Validate the options form. + * {@inheritdoc} */ public function validateExposed(&$form, &$form_state) { if (!isset($this->options['expose']['identifier'])) { @@ -82,47 +105,43 @@ public function validateExposed(&$form, &$form_state) { $key = $this->options['expose']['identifier']; if (!empty($form_state['values'][$key])) { - $this->query_parse_search_expression($form_state['values'][$key]); - if (count($this->search_query->words()) == 0) { + $this->queryParseSearchExpression($form_state['values'][$key]); + if (count($this->searchQuery->words()) == 0) { form_set_error($key, $form_state, format_plural(\Drupal::config('search.settings')->get('index.minimum_word_size'), 'You must include at least one positive keyword with 1 character or more.', 'You must include at least one positive keyword with @count characters or more.')); } } } /** - * Make sure that parseSearchExpression is run and everything is set up. + * Sets up and parses the search query. * - * @param $input - * The search phrase which was input by the user. + * @param string $input + * The search keywords entered by the user. */ - function query_parse_search_expression($input) { - if (!isset($this->search_query)) { + protected function queryParseSearchExpression($input) { + if (!isset($this->searchQuery)) { $this->parsed = TRUE; - $this->search_query = db_select('search_index', 'i', array('target' => 'slave'))->extend('Drupal\search\ViewsSearchQuery'); - $this->search_query->searchExpression($input, $this->view->base_table); - $this->search_query->publicParseSearchExpression(); + $this->searchQuery = db_select('search_index', 'i', array('target' => 'slave'))->extend('Drupal\search\ViewsSearchQuery'); + $this->searchQuery->searchExpression($input, $this->searchType); + $this->searchQuery->publicParseSearchExpression(); } } /** - * Add this filter to the query. - * - * Due to the nature of fapi, the value and the operator have an unintended - * level of indirection. You will find them in $this->operator - * and $this->value respectively. + * {@inheritdoc} */ public function query() { // Since attachment views don't validate the exposed input, parse the search // expression if required. if (!$this->parsed) { - $this->query_parse_search_expression($this->value); + $this->queryParseSearchExpression($this->value); } $required = FALSE; - if (!isset($this->search_query)) { + if (!isset($this->searchQuery)) { $required = TRUE; } else { - $words = $this->search_query->words(); + $words = $this->searchQuery->words(); if (empty($words)) { $required = TRUE; } @@ -137,35 +156,30 @@ public function query() { $search_condition = db_and(); - // Create a new join to relate the 'serach_total' table to our current 'search_index' table. + // Create a new join to relate the 'search_total' table to our current + // 'search_index' table. $definition = array( 'table' => 'search_total', 'field' => 'word', 'left_table' => $search_index, 'left_field' => 'word', ); - $join = \Drupal::service()->get('plugin.manager.views.join')->createInstance('standard', $definition); + $join = Views::pluginManager('join')->createInstance('standard', $definition); $search_total = $this->query->addRelationship('search_total', $join, $search_index); $this->search_score = $this->query->addField('', "SUM($search_index.score * $search_total.count)", 'score', array('aggregate' => TRUE)); - if (empty($this->query->relationships[$this->relationship])) { - $base_table = $this->view->storage->get('base_table'); - } - else { - $base_table = $this->query->relationships[$this->relationship]['base']; - } - $search_condition->condition("$search_index.type", $base_table); - if (!$this->search_query->simple()) { + $search_condition->condition("$search_index.type", $this->searchType); + if (!$this->searchQuery->simple()) { $search_dataset = $this->query->addTable('search_dataset'); - $conditions = $this->search_query->conditions(); + $conditions = $this->searchQuery->conditions(); $condition_conditions =& $conditions->conditions(); foreach ($condition_conditions as $key => &$condition) { // Make sure we just look at real conditions. if (is_numeric($key)) { // Replace the conditions with the table alias of views. - $this->search_query->condition_replace_string('d.', "$search_dataset.", $condition); + $this->searchQuery->conditionReplaceString('d.', "$search_dataset.", $condition); } } $search_conditions =& $search_condition->conditions(); @@ -183,12 +197,12 @@ public function query() { $this->query->addWhere($this->options['group'], $search_condition); $this->query->addGroupBy("$search_index.sid"); - $matches = $this->search_query->matches(); + $matches = $this->searchQuery->matches(); $placeholder = $this->placeholder(); $this->query->addHavingExpression($this->options['group'], "COUNT(*) >= $placeholder", array($placeholder => $matches)); } // Set to NULL to prevent PDO exception when views object is cached. - $this->search_query = NULL; + $this->searchQuery = NULL; } } diff --git a/core/modules/search/lib/Drupal/search/Plugin/views/row/SearchRow.php b/core/modules/search/lib/Drupal/search/Plugin/views/row/SearchRow.php index ba388cb22b193a0315647c6c9a438bf6434ea74e..8c0709f71511c1c5d14ebfac0fccf3aae1b4531d 100644 --- a/core/modules/search/lib/Drupal/search/Plugin/views/row/SearchRow.php +++ b/core/modules/search/lib/Drupal/search/Plugin/views/row/SearchRow.php @@ -10,16 +10,19 @@ use Drupal\views\Plugin\views\row\RowPluginBase; /** - * Plugin which performs a node_view on the resulting object. + * Row handler plugin for displaying search results. * * @ViewsRow( * id = "search_view", - * title = @Translation("Search"), + * title = @Translation("Search results"), * help = @Translation("Provides a row plugin to display search results.") * ) */ class SearchRow extends RowPluginBase { + /** + * {@inheritdoc} + */ protected function defineOptions() { $options = parent::defineOptions(); @@ -28,6 +31,9 @@ protected function defineOptions() { return $options; } + /** + * {@inheritdoc} + */ public function buildOptionsForm(&$form, &$form_state) { $form['score'] = array( '#type' => 'checkbox', @@ -37,7 +43,7 @@ public function buildOptionsForm(&$form, &$form_state) { } /** - * Override the behavior of the render() function. + * {@inheritdoc} */ public function render($row) { return array( diff --git a/core/modules/search/lib/Drupal/search/Plugin/views/sort/Score.php b/core/modules/search/lib/Drupal/search/Plugin/views/sort/Score.php index 589d499a8f00f1963d9d679f2f0ce3796f090d7c..68fcd336b0ca2d49696f76969aebffd71740a735 100644 --- a/core/modules/search/lib/Drupal/search/Plugin/views/sort/Score.php +++ b/core/modules/search/lib/Drupal/search/Plugin/views/sort/Score.php @@ -10,7 +10,7 @@ use Drupal\views\Plugin\views\sort\SortPluginBase; /** - * Field handler to provide simple renderer that allows linking to a node. + * Sort handler for sorting by search score. * * @ingroup views_sort_handlers * @@ -18,6 +18,9 @@ */ class Score extends SortPluginBase { + /** + * {@inheritdoc} + */ public function query() { // Check to see if the search filter/argument added 'score' to the table. // Our filter stores it as $handler->search_score -- and we also @@ -33,8 +36,8 @@ public function query() { } } - // Do absolutely nothing if there is no filter/argument in place; there is no reason to - // sort on the raw scores with this handler. + // Do nothing if there is no filter/argument in place. There is no way + // to sort on scores. } } diff --git a/core/modules/search/lib/Drupal/search/ViewsSearchQuery.php b/core/modules/search/lib/Drupal/search/ViewsSearchQuery.php index 0690551c4235c14cce544c646d2f6ea8465f1500..f328d3aec62a0509f14cfd7853c181ac5f5584e7 100644 --- a/core/modules/search/lib/Drupal/search/ViewsSearchQuery.php +++ b/core/modules/search/lib/Drupal/search/ViewsSearchQuery.php @@ -10,7 +10,7 @@ use Drupal\Core\Database\Query\Condition; /** - * Extends the core SearchQuery to be able to gets it's protected values. + * Extends the core SearchQuery to be able to gets its protected values. */ class ViewsSearchQuery extends SearchQuery { @@ -67,14 +67,14 @@ public function publicParseSearchExpression() { * @param \Drupal\Core\Database\Query\Condition $condition * The query condition in which the string is replaced. */ - function condition_replace_string($search, $replace, &$condition) { + function conditionReplaceString($search, $replace, &$condition) { if ($condition['field'] instanceof Condition) { $conditions =& $condition['field']->conditions(); foreach ($conditions as $key => &$subcondition) { if (is_numeric($key)) { // As conditions can have subconditions, for example db_or(), the // function has to be called recursively. - $this->condition_replace_string($search, $replace, $subcondition); + $this->conditionReplaceString($search, $replace, $subcondition); } } } diff --git a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php index 31be4abafe684bf8896f182da695df29ae5d2a73..875679f9945e6809543b70540fffd191278b9aff 100644 --- a/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/DefaultViewsTest.php @@ -103,8 +103,6 @@ protected function setUp() { $node = $this->drupalCreateNode($values); - search_index($node->id(), 'node', $node->body->value, Language::LANGCODE_NOT_SPECIFIED); - $comment = array( 'uid' => $user->id(), 'status' => CommentInterface::PUBLISHED, diff --git a/core/modules/views/lib/Drupal/views/Tests/SearchIntegrationTest.php b/core/modules/views/lib/Drupal/views/Tests/SearchIntegrationTest.php new file mode 100644 index 0000000000000000000000000000000000000000..46d5b037a6e0b8d9fcebe1ffd27248b7133e28a5 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Tests/SearchIntegrationTest.php @@ -0,0 +1,83 @@ +<?php + +/** + * @file + * Contains \Drupal\views\Tests\SearchIntegrationTest. + */ + +namespace Drupal\views\Tests; + +/** + * Tests search integration filters. + */ +class SearchIntegrationTest extends ViewTestBase { + + /** + * Modules to enable. + * + * @var array + */ + public static $modules = array('node', 'search'); + + /** + * Views used by this test. + * + * @var array + */ + public static $testViews = array('test_search'); + + /** + * {inheritdoc} + */ + public static function getInfo() { + return array( + 'name' => 'Search integration tests', + 'description' => 'Tests search integration filters of views.', + 'group' => 'Views', + ); + } + + /** + * Tests search integration. + */ + public function testSearchIntegration() { + // Create a content type. + $type = $this->drupalCreateContentType(); + + // Add two nodes, one containing the word "pizza" and the other + // with the word "sandwich". Make the second node link to the first. + $node['title'] = 'pizza'; + $node['body'] = array(array('value' => 'pizza')); + $node['type'] = $type->type; + $this->drupalCreateNode($node); + + $this->drupalGet('node/1'); + $node_url = $this->getUrl(); + + $node['title'] = 'sandwich'; + $node['body'] = array(array('value' => 'sandwich with a <a href="' . $node_url . '">link to first node</a>')); + $this->drupalCreateNode($node); + + // Run cron so that the search index tables are updated. + $this->cronRun(); + + // Test the various views filters by visiting their pages. + // These are in the test view 'test_search', and they just display the + // titles of the nodes in the result, as links. + + // Page with a keyword filter of 'pizza'. + $this->drupalGet('test-filter'); + $this->assertLink('pizza', 0, 'Pizza page is on Filter page'); + $this->assertNoLink('sandwich', 'Sandwich page is not on Filter page'); + + // Page with a keyword argument. + $this->drupalGet('test-arg/pizza'); + $this->assertLink('pizza', 0, 'Pizza page is on argument page'); + $this->assertNoLink('sandwich', 'Sandwich page is not on argument page'); + + $this->drupalGet('test-arg/sandwich'); + $this->assertNoLink('pizza', 'Pizza page is not on argument page'); + $this->assertLink('sandwich', 0, 'Sandwich page is on argument page'); + } + +} diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_search.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_search.yml new file mode 100644 index 0000000000000000000000000000000000000000..71443c8a71a3004bbfd475b8dbdd605cf3cdfff0 --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_search.yml @@ -0,0 +1,248 @@ +base_field: nid +base_table: node +core: 8.x +description: 'Test view for Search integration' +status: true +display: + page_2: + display_plugin: page + id: page_2 + display_title: 'Arg Page' + position: 1 + display_options: + display_description: '' + filters: + status: + value: '1' + table: node_field_data + field: status + provider: node + id: status + expose: + operator: '' + group: '1' + defaults: + filters: false + filter_groups: false + arguments: false + title: false + filter_groups: + operator: AND + groups: + 1: AND + path: test-arg/% + arguments: + keys: + id: keys + table: node_search_index + field: keys + relationship: none + group_type: group + admin_label: '' + default_action: 'not found' + 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: '1' + items_per_page: '25' + separator: '' + override: 0 + inline: false + summary: + sort_order: asc + number_of_records: 0 + format: unformatted_summary + specify_validation: false + validate: + type: none + fail: 'not found' + validate_options: { } + plugin_id: search + provider: search + title: 'Arg Page' + default: + display_plugin: default + id: default + display_title: Master + position: 1 + display_options: + access: + type: perm + options: + perm: 'access content' + cache: + type: none + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + slave: false + query_comment: false + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: none + options: + items_per_page: '0' + offset: 0 + style: + type: default + options: + grouping: { } + row_class: '' + default_row_class: true + row_class_special: true + row: + type: fields + fields: + title: + id: title + table: node_field_data + field: title + provider: node + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + link_to_node: 1 + relationship: none + group_type: group + admin_label: '' + label: Title + exclude: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_alter_empty: true + filters: + status: + value: '1' + table: node_field_data + field: status + provider: node + id: status + expose: + operator: '' + group: '1' + sorts: + created: + id: created + table: node_field_data + field: created + order: DESC + relationship: none + group_type: group + admin_label: '' + exposed: false + expose: + label: '' + granularity: second + title: '' + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + page_1: + display_plugin: page + id: page_1 + display_title: 'Filter Page' + position: 1 + display_options: + display_description: '' + filters: + status: + value: '1' + table: node_field_data + field: status + provider: node + id: status + expose: + operator: '' + group: '1' + keys: + id: keys + table: node_search_index + field: keys + relationship: none + group_type: group + admin_label: '' + operator: optional + value: pizza + group: '1' + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: 0 + default_group: All + default_group_multiple: { } + group_items: { } + plugin_id: search_keywords + provider: search + defaults: + filters: false + filter_groups: false + title: false + filter_groups: + operator: AND + groups: + 1: AND + path: test-filter + title: 'Filter Page' +label: 'Search Test' +module: views +id: test_search +tag: '' +uuid: f19c4fd2-af74-4d70-8500-a1037ca434bb +langcode: en