Update to Drupal 8.0.0-beta15. For more information, see: https://www.drupal.org/node/2563023

This commit is contained in:
Pantheon Automation 2015-09-04 13:20:09 -07:00 committed by Greg Anderson
parent 2720a9ec4b
commit f3791f1da3
1898 changed files with 54300 additions and 11481 deletions

View file

@ -0,0 +1,24 @@
id: d7_search_settings
label: Drupal 7 search configuration
migration_tags:
- Drupal 7
source:
plugin: variable
constants:
status: true
variables:
- minimum_word_size
- overlap_cjk
- search_cron_limit
- search_tag_weights
- search_and_or_limit
process:
'index/minimum_word_size': minimum_word_size
'index/overlap_cjk': overlap_cjk
'index/cron_limit': search_cron_limit
'index/tag_weights': search_tag_weights
and_or_limit: search_and_or_limit
logging: 'constants/status'
destination:
plugin: config
config_name: search.settings

View file

@ -5,7 +5,6 @@
* Enables site-wide keyword searching.
*/
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Cache\Cache;
@ -618,7 +617,8 @@ function search_mark_for_reindex($type = NULL, $sid = NULL, $langcode = NULL) {
/**
* Returns snippets from a piece of text, with search keywords highlighted.
*
* Used for formatting search results.
* Used for formatting search results. All HTML tags will be stripped from
* $text.
*
* @param string $keys
* A string containing a search query.
@ -627,8 +627,8 @@ function search_mark_for_reindex($type = NULL, $sid = NULL, $langcode = NULL) {
* @param string|null $langcode
* Language code for the language of $text, if known.
*
* @return string
* A string containing HTML for the excerpt.
* @return array
* A render array containing HTML for the excerpt.
*/
function search_excerpt($keys, $text, $langcode = NULL) {
// We highlight around non-indexable or CJK characters.
@ -721,7 +721,9 @@ function search_excerpt($keys, $text, $langcode = NULL) {
// We didn't find any keyword matches, so just return the first part of the
// text. We also need to re-encode any HTML special characters that we
// entity-decoded above.
return SafeMarkup::checkPlain(Unicode::truncate($text, 256, TRUE, TRUE));
return [
'#plain_text' => Unicode::truncate($text, 256, TRUE, TRUE),
];
}
// Sort the text ranges by starting position.
@ -762,12 +764,15 @@ function search_excerpt($keys, $text, $langcode = NULL) {
// translated. Let translators have the … separator text as one chunk.
$ellipses = explode('!excerpt', t('… !excerpt … !excerpt …'));
$text = (isset($new_ranges[0]) ? '' : $ellipses[0]) . implode($ellipses[1], $out) . (($max_end < strlen($text) - 1) ? $ellipses[2] : '');
$text = SafeMarkup::checkPlain($text);
$text = Html::escape($text);
// Highlight keywords. Must be done at once to prevent conflicts ('strong'
// and '<strong>').
$text = trim(preg_replace('/' . $boundary . '(?:' . implode('|', $keys) . ')' . $boundary . '/iu', '<strong>\0</strong>', ' ' . $text . ' '));
return SafeMarkup::xssFilter($text, ['strong']);
return [
'#markup' => $text,
'#allowed_tags' => ['strong']
];
}
/**

View file

@ -5,7 +5,7 @@
* User page callbacks for the Search module.
*/
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Language\LanguageInterface;
/**
@ -35,8 +35,8 @@ function template_preprocess_search_result(&$variables) {
$language_interface = \Drupal::languageManager()->getCurrentLanguage();
$result = $variables['result'];
$variables['url'] = check_url($result['link']);
$variables['title'] = SafeMarkup::checkPlain($result['title']);
$variables['url'] = UrlHelper::stripDangerousProtocols($result['link']);
$variables['title'] = $result['title'];
if (isset($result['language']) && $result['language'] != $language_interface->getId() && $result['language'] != LanguageInterface::LANGCODE_NOT_SPECIFIED) {
$variables['title_attributes']['lang'] = $result['language'];
$variables['content_attributes']['lang'] = $result['language'];
@ -44,7 +44,7 @@ function template_preprocess_search_result(&$variables) {
$info = array();
if (!empty($result['plugin_id'])) {
$info['plugin_id'] = SafeMarkup::checkPlain($result['plugin_id']);
$info['plugin_id'] = $result['plugin_id'];
}
if (!empty($result['user'])) {
$info['user'] = $result['user'];

View file

@ -93,10 +93,11 @@ class Search extends ArgumentPluginBase {
$join = Views::pluginManager('join')->createInstance('standard', $definition);
$search_total = $this->query->addRelationship('search_total', $join, $search_index);
// Add the search score field to the query.
$this->search_score = $this->query->addField('', "$search_index.score * $search_total.count", 'score', array('function' => 'sum'));
// Add the conditions set up by the search query to the views query.
$search_condition->condition("$search_index.type", $this->searchType);
$search_dataset = $this->query->addTable('node_search_dataset');
$conditions = $this->searchQuery->conditions();
$condition_conditions =& $conditions->conditions();
@ -110,6 +111,16 @@ class Search extends ArgumentPluginBase {
$search_conditions =& $search_condition->conditions();
$search_conditions = array_merge($search_conditions, $condition_conditions);
// Add the keyword conditions, as is done in
// SearchQuery::prepareAndNormalize(), but simplified because we are
// only concerned with relevance ranking so we do not need to normalize.
$or = db_or();
foreach ($words as $word) {
$or->condition("$search_index.word", $word);
}
$search_condition->condition($or);
// Add the GROUP BY and HAVING expressions to the query.
$this->query->addWhere(0, $search_condition);
$this->query->addGroupBy("$search_index.sid");
$matches = $this->searchQuery->matches();

View file

@ -166,11 +166,12 @@ class Search extends FilterPluginBase {
'left_field' => 'word',
);
$join = Views::pluginManager('join')->createInstance('standard', $definition);
$search_total = $this->query->addRelationship('search_total', $join, $search_index);
// Add the search score field to the query.
$this->search_score = $this->query->addField('', "$search_index.score * $search_total.count", 'score', array('function' => 'sum'));
// Add the conditions set up by the search query to the views query.
$search_condition->condition("$search_index.type", $this->searchType);
$search_dataset = $this->query->addTable('node_search_dataset');
$conditions = $this->searchQuery->conditions();
@ -185,7 +186,18 @@ class Search extends FilterPluginBase {
$search_conditions =& $search_condition->conditions();
$search_conditions = array_merge($search_conditions, $condition_conditions);
// Add the keyword conditions, as is done in
// SearchQuery::prepareAndNormalize(), but simplified because we are
// only concerned with relevance ranking so we do not need to normalize.
$or = db_or();
foreach ($words as $word) {
$or->condition("$search_index.word", $word);
}
$search_condition->condition($or);
$this->query->addWhere($this->options['group'], $search_condition);
// Add the GROUP BY and HAVING expressions to the query.
$this->query->addGroupBy("$search_index.sid");
$matches = $this->searchQuery->matches();
$placeholder = $this->placeholder();

View file

@ -121,7 +121,7 @@ class SearchPageListBuilder extends DraggableListBuilder implements FormInterfac
*/
public function buildRow(EntityInterface $entity) {
/** @var $entity \Drupal\search\SearchPageInterface */
$row['label'] = $this->getLabel($entity);
$row['label'] = $entity->label();
$row['url']['#markup'] = 'search/' . $entity->getPath();
// If the search page is active, link to it.
if ($entity->status()) {

View file

@ -14,7 +14,7 @@ use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* Upgrade search rank settings to search.page.*.yml.
*
* @group search
* @group migrate_drupal_6
*/
class MigrateSearchPageTest extends MigrateDrupal6TestBase {
@ -30,7 +30,6 @@ class MigrateSearchPageTest extends MigrateDrupal6TestBase {
*/
protected function setUp() {
parent::setUp();
$this->loadDumps(['Variable.php']);
$this->executeMigration('d6_search_page');
}

View file

@ -0,0 +1,49 @@
<?php
/**
* @file
* Contains \Drupal\search\Tests\Migrate\d6\MigrateSearchSettingsTest.
*/
namespace Drupal\search\Tests\Migrate\d6;
use Drupal\config\Tests\SchemaCheckTestTrait;
use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase;
/**
* Upgrade variables to search.settings.yml.
*
* @group migrate_drupal_6
*/
class MigrateSearchSettingsTest extends MigrateDrupal6TestBase {
use SchemaCheckTestTrait;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('search');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d6_search_settings');
}
/**
* Tests migration of search variables to search.settings.yml.
*/
public function testSearchSettings() {
$config = $this->config('search.settings');
$this->assertIdentical(3, $config->get('index.minimum_word_size'));
$this->assertIdentical(TRUE, $config->get('index.overlap_cjk'));
$this->assertIdentical(100, $config->get('index.cron_limit'));
$this->assertIdentical(TRUE, $config->get('logging'));
$this->assertConfigSchema(\Drupal::service('config.typed'), 'search.settings', $config->get());
}
}

View file

@ -0,0 +1,53 @@
<?php
/**
* @file
* Contains \Drupal\search\Tests\Migrate\d7\MigrateSearchSettingsTest.
*/
namespace Drupal\search\Tests\Migrate\d7;
use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
/**
* Tests migration of Search variables to configuration.
*
* @group search
*/
class MigrateSearchSettingsTest extends MigrateDrupal7TestBase {
public static $modules = ['search'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->executeMigration('d7_search_settings');
}
/**
* Tests the migration of Search's variables to configuration.
*/
public function testSearchSettings() {
$config = $this->config('search.settings');
$this->assertIdentical(4, $config->get('index.minimum_word_size'));
$this->assertTrue($config->get('index.overlap_cjk'));
$this->assertIdentical(100, $config->get('index.cron_limit'));
$this->assertIdentical(7, $config->get('and_or_limit'));
$this->assertIdentical(25, $config->get('index.tag_weights.h1'));
$this->assertIdentical(18, $config->get('index.tag_weights.h2'));
$this->assertIdentical(15, $config->get('index.tag_weights.h3'));
$this->assertIdentical(12, $config->get('index.tag_weights.h4'));
$this->assertIdentical(9, $config->get('index.tag_weights.h5'));
$this->assertIdentical(6, $config->get('index.tag_weights.h6'));
$this->assertIdentical(3, $config->get('index.tag_weights.u'));
$this->assertIdentical(3, $config->get('index.tag_weights.b'));
$this->assertIdentical(3, $config->get('index.tag_weights.i'));
$this->assertIdentical(3, $config->get('index.tag_weights.strong'));
$this->assertIdentical(3, $config->get('index.tag_weights.em'));
$this->assertIdentical(10, $config->get('index.tag_weights.a'));
$this->assertTrue($config->get('logging'));
}
}

View file

@ -126,6 +126,23 @@ class SearchCommentTest extends SearchTestBase {
$edit_comment['comment_body[0][format]'] = $full_html_format_id;
$this->drupalPostForm('comment/reply/node/' . $node->id() .'/comment', $edit_comment, t('Save'));
// Post a comment with an evil script tag in the comment subject and a
// script tag nearby a keyword in the comment body. Use the 'FULL HTML' text
// format so the script tag stored.
$edit_comment2 = array();
$edit_comment2['subject[0][value]'] = "<script>alert('subjectkeyword');</script>";
$edit_comment2['comment_body[0][value]'] = "nearbykeyword<script>alert('somethinggeneric');</script>";
$edit_comment2['comment_body[0][format]'] = $full_html_format_id;
$this->drupalPostForm('comment/reply/node/' . $node->id() . '/comment', $edit_comment2, t('Save'));
// Post a comment with a keyword inside an evil script tag in the comment
// body. Use the 'FULL HTML' text format so the script tag is stored.
$edit_comment3 = array();
$edit_comment3['subject[0][value]'] = 'asubject';
$edit_comment3['comment_body[0][value]'] = "<script>alert('insidekeyword');</script>";
$edit_comment3['comment_body[0][format]'] = $full_html_format_id;
$this->drupalPostForm('comment/reply/node/' . $node->id() . '/comment', $edit_comment3, t('Save'));
// Invoke search index update.
$this->drupalLogout();
$this->cronRun();
@ -152,6 +169,39 @@ class SearchCommentTest extends SearchTestBase {
$this->assertNoRaw(t('n/a'), 'HTML in comment body is not hidden.');
$this->assertNoEscaped($edit_comment['comment_body[0][value]'], 'HTML in comment body is not escaped.');
// Search for the evil script comment subject.
$edit = array(
'keys' => 'subjectkeyword',
);
$this->drupalPostForm('search/node', $edit, t('Search'));
// Verify the evil comment subject is escaped in search results.
$this->assertRaw('&lt;script&gt;alert(&#039;<strong>subjectkeyword</strong>&#039;);');
$this->assertNoRaw('<script>');
// Search for the keyword near the evil script tag in the comment body.
$edit = [
'keys' => 'nearbykeyword',
];
$this->drupalPostForm('search/node', $edit, t('Search'));
// Verify that nearby script tag in the evil comment body is stripped from
// search results.
$this->assertRaw('<strong>nearbykeyword</strong>');
$this->assertNoRaw('<script>');
// Search for contents inside the evil script tag in the comment body.
$edit = [
'keys' => 'insidekeyword',
];
$this->drupalPostForm('search/node', $edit, t('Search'));
// @todo Verify the actual search results.
// https://www.drupal.org/node/2551135
// Verify there is no script tag in search results.
$this->assertNoRaw('<script>');
// Hide comments.
$this->drupalLogin($this->adminUser);
$node->set('comment', CommentItemInterface::HIDDEN);

View file

@ -58,6 +58,7 @@ class SearchConfigSettingsFormTest extends SearchTestBase {
// Enable the search block.
$this->drupalPlaceBlock('search_form_block');
$this->drupalPlaceBlock('local_tasks_block');
}
/**

View file

@ -7,14 +7,14 @@
namespace Drupal\search\Tests;
use Drupal\simpletest\WebTestBase;
use Drupal\simpletest\KernelTestBase;
/**
* Tests the search_excerpt() function.
*
* @group search
*/
class SearchExcerptTest extends WebTestBase {
class SearchExcerptTest extends KernelTestBase {
/**
* Modules to enable.
@ -38,39 +38,39 @@ class SearchExcerptTest extends WebTestBase {
// Note: The search_excerpt() function adds some extra spaces -- not
// important for HTML formatting. Remove these for comparison.
$expected = 'The quick brown fox &amp; jumps over the lazy dog';
$result = preg_replace('| +|', ' ', search_excerpt('nothing', $text));
$this->assertEqual(preg_replace('| +|', ' ', $result), $expected, 'Entire string is returned when keyword is not found in short string');
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('nothing', $text));
$this->assertEqual(preg_replace('| +|', ' ', $result), $expected, 'Entire string, stripped of HTML tags, is returned when keyword is not found in short string');
$result = preg_replace('| +|', ' ', search_excerpt('fox', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('fox', $text));
$this->assertEqual($result, 'The quick brown <strong>fox</strong> &amp; jumps over the lazy dog', 'Found keyword is highlighted');
$expected = '<strong>The</strong> quick brown fox &amp; jumps over <strong>the</strong> lazy dog';
$result = preg_replace('| +|', ' ', search_excerpt('The', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('The', $text));
$this->assertEqual(preg_replace('| +|', ' ', $result), $expected, 'Keyword is highlighted at beginning of short string');
$expected = 'The quick brown fox &amp; jumps over the lazy <strong>dog</strong>';
$result = preg_replace('| +|', ' ', search_excerpt('dog', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('dog', $text));
$this->assertEqual(preg_replace('| +|', ' ', $result), $expected, 'Keyword is highlighted at end of short string');
$longtext = str_repeat(str_replace('brown', 'silver', $text) . ' ', 10) . $text . str_repeat(' ' . str_replace('brown', 'pink', $text), 10);
$result = preg_replace('| +|', ' ', search_excerpt('brown', $longtext));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('brown', $longtext));
$expected = '… silver fox &amp; jumps over the lazy dog The quick <strong>brown</strong> fox &amp; jumps over the lazy dog The quick …';
$this->assertEqual($result, $expected, 'Snippet around keyword in long text is correctly capped');
$longtext = str_repeat($text . ' ', 10);
$result = preg_replace('| +|', ' ', search_excerpt('nothing', $longtext));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('nothing', $longtext));
$expected = 'The quick brown fox &amp; jumps over the lazy dog';
$this->assertTrue(strpos($result, $expected) === 0, 'When keyword is not found in long string, return value starts as expected');
$entities = str_repeat('k&eacute;sz&iacute;t&eacute;se ', 20);
$result = preg_replace('| +|', ' ', search_excerpt('nothing', $entities));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('nothing', $entities));
$this->assertFalse(strpos($result, '&'), 'Entities are not present in excerpt');
$this->assertTrue(strpos($result, 'í') > 0, 'Entities are converted in excerpt');
// The node body that will produce this rendered $text is:
// 123456789 HTMLTest +123456789+&lsquo; +&lsquo; +&lsquo; +&lsquo; +12345678 &nbsp;&nbsp; +&lsquo; +&lsquo; +&lsquo; &lsquo;
$text = "<div class=\"field field-name-body field-type-text-with-summary field-label-hidden\"><div class=\"field-items\"><div class=\"field-item even\" property=\"content:encoded\"><p>123456789 HTMLTest +123456789+ + + + +12345678    + + + </p>\n</div></div></div> ";
$result = search_excerpt('HTMLTest', $text);
$text = "<div class=\"field field--name-body field--type-text-with-summary field--label-hidden\"><div class=\"field__items\"><div class=\"field__item even\" property=\"content:encoded\"><p>123456789 HTMLTest +123456789+ + + + +12345678    + + + </p>\n</div></div></div> ";
$result = $this->doSearchExcerpt('HTMLTest', $text);
$this->assertFalse(empty($result), 'Rendered Multi-byte HTML encodings are not corrupted in search excerpts');
}
@ -89,37 +89,37 @@ class SearchExcerptTest extends WebTestBase {
$text = $lorem1 . ' Number: 123456.7890 Hyphenated: one-two abc,def ' . $lorem2;
// Note: The search_excerpt() function adds some extra spaces -- not
// important for HTML formatting. Remove these for comparison.
$result = preg_replace('| +|', ' ', search_excerpt('123456.7890', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('123456.7890', $text));
$this->assertTrue(strpos($result, 'Number: <strong>123456.7890</strong>') !== FALSE, 'Numeric keyword is highlighted with exact match');
$result = preg_replace('| +|', ' ', search_excerpt('1234567890', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('1234567890', $text));
$this->assertTrue(strpos($result, 'Number: <strong>123456.7890</strong>') !== FALSE, 'Numeric keyword is highlighted with simplified match');
$result = preg_replace('| +|', ' ', search_excerpt('Number 1234567890', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('Number 1234567890', $text));
$this->assertTrue(strpos($result, '<strong>Number</strong>: <strong>123456.7890</strong>') !== FALSE, 'Punctuated and numeric keyword is highlighted with simplified match');
$result = preg_replace('| +|', ' ', search_excerpt('"Number 1234567890"', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('"Number 1234567890"', $text));
$this->assertTrue(strpos($result, '<strong>Number: 123456.7890</strong>') !== FALSE, 'Phrase with punctuated and numeric keyword is highlighted with simplified match');
$result = preg_replace('| +|', ' ', search_excerpt('"Hyphenated onetwo"', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('"Hyphenated onetwo"', $text));
$this->assertTrue(strpos($result, '<strong>Hyphenated: one-two</strong>') !== FALSE, 'Phrase with punctuated and hyphenated keyword is highlighted with simplified match');
$result = preg_replace('| +|', ' ', search_excerpt('"abc def"', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('"abc def"', $text));
$this->assertTrue(strpos($result, '<strong>abc,def</strong>') !== FALSE, 'Phrase with keyword simplified into two separate words is highlighted with simplified match');
// Test phrases with characters which are being truncated.
$result = preg_replace('| +|', ' ', search_excerpt('"ipsum _"', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('"ipsum _"', $text));
$this->assertTrue(strpos($result, '<strong>ipsum</strong>') !== FALSE, 'Only valid part of the phrase is highlighted and invalid part containing "_" is ignored.');
$result = preg_replace('| +|', ' ', search_excerpt('"ipsum 0000"', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('"ipsum 0000"', $text));
$this->assertTrue(strpos($result, '<strong>ipsum</strong>') !== FALSE, 'Only valid part of the phrase is highlighted and invalid part "0000" is ignored.');
// Test combination of the valid keyword and keyword containing only
// characters which are being truncated during simplification.
$result = preg_replace('| +|', ' ', search_excerpt('ipsum _', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('ipsum _', $text));
$this->assertTrue(strpos($result, '<strong>ipsum</strong>') !== FALSE, 'Only valid keyword is highlighted and invalid keyword "_" is ignored.');
$result = preg_replace('| +|', ' ', search_excerpt('ipsum 0000', $text));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('ipsum 0000', $text));
$this->assertTrue(strpos($result, '<strong>ipsum</strong>') !== FALSE, 'Only valid keyword is highlighted and invalid keyword "0000" is ignored.');
// Test using the hook_search_preprocess() from the test module.
@ -127,37 +127,55 @@ class SearchExcerptTest extends WebTestBase {
// So, if we search for "find" or "finds" or "finding", we should
// highlight "finding".
$text = "this tests finding a string";
$result = preg_replace('| +|', ' ', search_excerpt('finds', $text, 'ex'));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('finds', $text, 'ex'));
$this->assertTrue(strpos($result, '<strong>finding</strong>') !== FALSE, 'Search excerpt works with preprocess hook, search for finds');
$result = preg_replace('| +|', ' ', search_excerpt('find', $text, 'ex'));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('find', $text, 'ex'));
$this->assertTrue(strpos($result, '<strong>finding</strong>') !== FALSE, 'Search excerpt works with preprocess hook, search for find');
// Just to be sure, test with the replacement at the beginning and end.
$text = "finding at the beginning";
$result = preg_replace('| +|', ' ', search_excerpt('finds', $text, 'ex'));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('finds', $text, 'ex'));
$this->assertTrue(strpos($result, '<strong>finding</strong>') !== FALSE, 'Search excerpt works with preprocess hook, text at start');
$text = "at the end finding";
$result = preg_replace('| +|', ' ', search_excerpt('finds', $text, 'ex'));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('finds', $text, 'ex'));
$this->assertTrue(strpos($result, '<strong>finding</strong>') !== FALSE, 'Search excerpt works with preprocess hook, text at end');
// Testing with a one-to-many replacement: the test module replaces DIC
// with Dependency Injection Container.
$text = "something about the DIC is happening";
$result = preg_replace('| +|', ' ', search_excerpt('Dependency', $text, 'ex'));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('Dependency', $text, 'ex'));
$this->assertTrue(strpos($result, '<strong>DIC</strong>') !== FALSE, 'Search excerpt works with preprocess hook, acronym first word');
$result = preg_replace('| +|', ' ', search_excerpt('Injection', $text, 'ex'));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('Injection', $text, 'ex'));
$this->assertTrue(strpos($result, '<strong>DIC</strong>') !== FALSE, 'Search excerpt works with preprocess hook, acronym second word');
$result = preg_replace('| +|', ' ', search_excerpt('Container', $text, 'ex'));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('Container', $text, 'ex'));
$this->assertTrue(strpos($result, '<strong>DIC</strong>') !== FALSE, 'Search excerpt works with preprocess hook, acronym third word');
// Testing with a many-to-one replacement: the test module replaces
// hypertext markup language with HTML.
$text = "we always use hypertext markup language to describe things";
$result = preg_replace('| +|', ' ', search_excerpt('html', $text, 'ex'));
$result = preg_replace('| +|', ' ', $this->doSearchExcerpt('html', $text, 'ex'));
$this->assertTrue(strpos($result, '<strong>hypertext markup language</strong>') !== FALSE, 'Search excerpt works with preprocess hook, acronym many to one');
}
/**
* Calls search_excerpt() and renders output.
*
* @param string $keys
* A string containing a search query.
* @param string $render_array
* The text to extract fragments from.
* @param string|null $langcode
* Language code for the language of $text, if known.
*
* @return string
* A string containing HTML for the excerpt.
*/
protected function doSearchExcerpt($keys, $render_array, $langcode = NULL) {
$render_array = search_excerpt($keys, $render_array, $langcode);
return \Drupal::service('renderer')->renderPlain($render_array);
}
}

View file

@ -7,7 +7,7 @@
namespace Drupal\search\Tests;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;
/**
* Verify the search without keywords set and extra conditions.
@ -61,6 +61,6 @@ class SearchKeywordsConditionsTest extends SearchTestBase {
$keys = 'moving drop ' . $this->randomMachineName();
$this->drupalGet("search/dummy_path", array('query' => array('keys' => 'bike', 'search_conditions' => $keys)));
$this->assertText("Dummy search snippet to display.");
$this->assertRaw(SafeMarkup::checkPlain(print_r(array('keys' => 'bike', 'search_conditions' => $keys), TRUE)));
$this->assertRaw(Html::escape(print_r(array('keys' => 'bike', 'search_conditions' => $keys), TRUE)));
}
}

View file

@ -8,6 +8,7 @@
namespace Drupal\search\Tests;
use Drupal\Core\Language\LanguageInterface;
use Drupal\simpletest\KernelTestBase;
// The search index can contain different types of content. Typically the type
// is 'node'. Here we test with _test_ and _test2_ as the type.
@ -20,7 +21,24 @@ const SEARCH_TYPE_JPN = '_test3_';
*
* @group search
*/
class SearchMatchTest extends SearchTestBase {
class SearchMatchTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['search'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installSchema('search', ['search_index', 'search_dataset', 'search_total']);
$this->installConfig(['search']);
}
/**
* Test search indexing.
*/

View file

@ -23,11 +23,22 @@ class SearchPageTextTest extends SearchTestBase {
*/
protected $searchingUser;
/**
* Modules to enable.
*
* @var string[]
*/
public static $modules = ['block'];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
// Create user.
$this->searchingUser = $this->drupalCreateUser(array('search content', 'access user profiles', 'use advanced search'));
$this->drupalPlaceBlock('local_tasks_block');
}
/**

View file

@ -69,8 +69,10 @@ class ViewsSearchQuery extends SearchQuery {
* The searched value.
* @param string $replace
* The value which replaces the search value.
* @param \Drupal\Core\Database\Query\Condition $condition
* The query condition in which the string is replaced.
* @param array $condition
* The query conditions array in which the string is replaced. This is an
* item from a \Drupal\Core\Database\Query\Condition::conditions array,
* which must have a 'field' element.
*/
function conditionReplaceString($search, $replace, &$condition) {
if ($condition['field'] instanceof Condition) {

View file

@ -9,12 +9,10 @@
* individual product (node) listed in the search results.
*/
use Drupal\Component\Utility\SafeMarkup;
/**
* Adds the test form to search results.
*/
function search_embedded_form_preprocess_search_result(&$variables) {
$form = \Drupal::formBuilder()->getForm('Drupal\search_embedded_form\Form\SearchEmbeddedForm');
$variables['snippet'] = ['#markup' => SafeMarkup::escape($variables['snippet']), $form];
$variables['snippet'] = array_merge($variables['snippet'], $form);
}