updated core to 7.73
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
* the template.
|
||||
*
|
||||
* Default keys within $info_split:
|
||||
* - $info_split['type']: Node type (or item type string supplied by module).
|
||||
* - $info_split['module']: The module that implemented the search query.
|
||||
* - $info_split['user']: Author of the node linked to users profile. Depends
|
||||
* on permission.
|
||||
* - $info_split['date']: Last update of the node. Short formatted.
|
||||
|
||||
@@ -125,6 +125,16 @@ function search_admin_settings($form) {
|
||||
'#options' => $module_options,
|
||||
'#description' => t('Choose which search module is the default.')
|
||||
);
|
||||
$form['logging'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Logging')
|
||||
);
|
||||
$form['logging']['search_logging'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Log searches'),
|
||||
'#default_value' => variable_get('search_logging', 1),
|
||||
'#description' => t('If checked, all searches will be logged. Uncheck to skip logging. Logging may affect performance.'),
|
||||
);
|
||||
$form['#validate'][] = 'search_admin_settings_validate';
|
||||
$form['#submit'][] = 'search_admin_settings_submit';
|
||||
|
||||
|
||||
@@ -30,51 +30,26 @@
|
||||
*
|
||||
* @return
|
||||
* Array with optional keys:
|
||||
* - 'title': Title for the tab on the search page for this module. Defaults
|
||||
* to the module name if not given.
|
||||
* - 'path': Path component after 'search/' for searching with this module.
|
||||
* - title: Title for the tab on the search page for this module. Title must
|
||||
* be untranslated. Outside of this return array, pass the title through the
|
||||
* t() function to register it as a translatable string.
|
||||
* - path: Path component after 'search/' for searching with this module.
|
||||
* Defaults to the module name if not given.
|
||||
* - 'conditions_callback': Name of a callback function that is invoked by
|
||||
* search_view() to get an array of additional search conditions to pass to
|
||||
* search_data(). For example, a search module may get additional keywords,
|
||||
* filters, or modifiers for the search from the query string. Sample
|
||||
* callback function: sample_search_conditions_callback().
|
||||
* - conditions_callback: An implementation of callback_search_conditions().
|
||||
*
|
||||
* @ingroup search
|
||||
*/
|
||||
function hook_search_info() {
|
||||
// Make the title translatable.
|
||||
t('Content');
|
||||
|
||||
return array(
|
||||
'title' => 'Content',
|
||||
'path' => 'node',
|
||||
'conditions_callback' => 'sample_search_conditions_callback',
|
||||
'conditions_callback' => 'callback_search_conditions',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* An example conditions callback function for search.
|
||||
*
|
||||
* This example pulls additional search keywords out of the $_REQUEST variable,
|
||||
* (i.e. from the query string of the request). The conditions may also be
|
||||
* generated internally - for example based on a module's settings.
|
||||
*
|
||||
* @see hook_search_info()
|
||||
* @ingroup search
|
||||
*/
|
||||
function sample_search_conditions_callback($keys) {
|
||||
$conditions = array();
|
||||
|
||||
if (!empty($_REQUEST['keys'])) {
|
||||
$conditions['keys'] = $_REQUEST['keys'];
|
||||
}
|
||||
if (!empty($_REQUEST['sample_search_keys'])) {
|
||||
$conditions['sample_search_keys'] = $_REQUEST['sample_search_keys'];
|
||||
}
|
||||
if ($force_keys = variable_get('sample_search_force_keywords', '')) {
|
||||
$conditions['sample_search_force_keywords'] = $force_keys;
|
||||
}
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define access to a custom search routine.
|
||||
*
|
||||
@@ -252,22 +227,23 @@ function hook_search_execute($keys = NULL, $conditions = NULL) {
|
||||
/**
|
||||
* Override the rendering of search results.
|
||||
*
|
||||
* A module that implements hook_search_info() to define a type of search
|
||||
* may implement this hook in order to override the default theming of
|
||||
* its search results, which is otherwise themed using theme('search_results').
|
||||
* A module that implements hook_search_info() to define a type of search may
|
||||
* implement this hook in order to override the default theming of its search
|
||||
* results, which is otherwise themed using theme('search_results').
|
||||
*
|
||||
* Note that by default, theme('search_results') and theme('search_result')
|
||||
* work together to create an ordered list (OL). So your hook_search_page()
|
||||
* implementation should probably do this as well.
|
||||
*
|
||||
* @see search-result.tpl.php, search-results.tpl.php
|
||||
*
|
||||
* @param $results
|
||||
* An array of search results.
|
||||
*
|
||||
* @return
|
||||
* A renderable array, which will render the formatted search results with
|
||||
* a pager included.
|
||||
* A renderable array, which will render the formatted search results with a
|
||||
* pager included.
|
||||
*
|
||||
* @see search-result.tpl.php
|
||||
* @see search-results.tpl.php
|
||||
*/
|
||||
function hook_search_page($results) {
|
||||
$output['prefix']['#markup'] = '<ol class="search-results">';
|
||||
@@ -364,3 +340,41 @@ function hook_update_index() {
|
||||
/**
|
||||
* @} End of "addtogroup hooks".
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provide search query conditions.
|
||||
*
|
||||
* Callback for hook_search_info().
|
||||
*
|
||||
* This callback is invoked by search_view() to get an array of additional
|
||||
* search conditions to pass to search_data(). For example, a search module
|
||||
* may get additional keywords, filters, or modifiers for the search from
|
||||
* the query string.
|
||||
*
|
||||
* This example pulls additional search keywords out of the $_REQUEST variable,
|
||||
* (i.e. from the query string of the request). The conditions may also be
|
||||
* generated internally - for example based on a module's settings.
|
||||
*
|
||||
* @param $keys
|
||||
* The search keywords string.
|
||||
*
|
||||
* @return
|
||||
* An array of additional conditions, such as filters.
|
||||
*
|
||||
* @ingroup callbacks
|
||||
* @ingroup search
|
||||
*/
|
||||
function callback_search_conditions($keys) {
|
||||
$conditions = array();
|
||||
|
||||
if (!empty($_REQUEST['keys'])) {
|
||||
$conditions['keys'] = $_REQUEST['keys'];
|
||||
}
|
||||
if (!empty($_REQUEST['sample_search_keys'])) {
|
||||
$conditions['sample_search_keys'] = $_REQUEST['sample_search_keys'];
|
||||
}
|
||||
if ($force_keys = config('sample_search.settings')->get('force_keywords')) {
|
||||
$conditions['sample_search_force_keywords'] = $force_keys;
|
||||
}
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
@@ -105,6 +105,8 @@ class SearchQuery extends SelectQueryExtender {
|
||||
* Stores score expressions.
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @see addScore()
|
||||
*/
|
||||
protected $scores = array();
|
||||
|
||||
@@ -116,7 +118,7 @@ class SearchQuery extends SelectQueryExtender {
|
||||
protected $scoresArguments = array();
|
||||
|
||||
/**
|
||||
* Total value of all the multipliers.
|
||||
* Stores multipliers for score expressions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@@ -147,6 +149,17 @@ class SearchQuery extends SelectQueryExtender {
|
||||
$this->searchExpression = $expression;
|
||||
$this->type = $module;
|
||||
|
||||
// Add a search_* tag. This needs to be added before any preExecute methods
|
||||
// for decorated queries are called, as $this->prepared will be set to TRUE
|
||||
// and tags added in the execute method will never get used. For example,
|
||||
// if $query is extended by 'SearchQuery' then 'PagerDefault', the
|
||||
// search-specific tag will be added too late (when preExecute() has
|
||||
// already been called from the PagerDefault extender), and as a
|
||||
// consequence will not be available to hook_query_alter() implementations,
|
||||
// nor will the correct hook_query_TAG_alter() implementations get invoked.
|
||||
// See node_search_execute().
|
||||
$this->addTag('search_' . $module);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -206,7 +219,7 @@ class SearchQuery extends SelectQueryExtender {
|
||||
}
|
||||
$phrase = FALSE;
|
||||
// Strip off phrase quotes.
|
||||
if ($match[2]{0} == '"') {
|
||||
if ($match[2][0] == '"') {
|
||||
$match[2] = substr($match[2], 1, -1);
|
||||
$phrase = TRUE;
|
||||
$this->simple = FALSE;
|
||||
@@ -391,21 +404,39 @@ class SearchQuery extends SelectQueryExtender {
|
||||
/**
|
||||
* Adds a custom score expression to the search query.
|
||||
*
|
||||
* Each score expression can optionally use a multiplier, and multiple
|
||||
* expressions are combined.
|
||||
* Score expressions are used to order search results. If no calls to
|
||||
* addScore() have taken place, a default keyword relevance score will be
|
||||
* used. However, if at least one call to addScore() has taken place, the
|
||||
* keyword relevance score is not automatically added.
|
||||
*
|
||||
* Note that you must use this method to add ordering to your searches, and
|
||||
* not call orderBy() directly, when using the SearchQuery extender. This is
|
||||
* because of the two-pass system the SearchQuery class uses to normalize
|
||||
* scores.
|
||||
*
|
||||
* @param $score
|
||||
* The score expression.
|
||||
* The score expression, which should evaluate to a number between 0 and 1.
|
||||
* The string 'i.relevance' in a score expression will be replaced by a
|
||||
* measure of keyword relevance between 0 and 1.
|
||||
* @param $arguments
|
||||
* Custom query arguments for that expression.
|
||||
* Query arguments needed to provide values to the score expression.
|
||||
* @param $multiply
|
||||
* If set, the score is multiplied with that value. Search query ensures
|
||||
* that the search scores are still normalized.
|
||||
* If set, the score is multiplied with this value. However, all scores
|
||||
* with multipliers are then divided by the total of all multipliers, so
|
||||
* that overall, the normalization is maintained.
|
||||
*
|
||||
* @return object
|
||||
* The updated query object.
|
||||
*/
|
||||
public function addScore($score, $arguments = array(), $multiply = FALSE) {
|
||||
if ($multiply) {
|
||||
$i = count($this->multiply);
|
||||
// Modify the score expression so it is multiplied by the multiplier,
|
||||
// with a divisor to renormalize.
|
||||
$score = "CAST(:multiply_$i AS DECIMAL) * COALESCE(( " . $score . "), 0) / CAST(:total_$i AS DECIMAL)";
|
||||
// Add an argument for the multiplier. The :total_$i argument is taken
|
||||
// care of in the execute() method, which is when the total divisor is
|
||||
// calculated.
|
||||
$arguments[':multiply_' . $i] = $multiply;
|
||||
$this->multiply[] = $multiply;
|
||||
}
|
||||
@@ -446,8 +477,9 @@ class SearchQuery extends SelectQueryExtender {
|
||||
}
|
||||
|
||||
if (count($this->multiply)) {
|
||||
// Add the total multiplicator as many times as requested to maintain
|
||||
// normalization as far as possible.
|
||||
// Re-normalize scores with multipliers by dividing by the total of all
|
||||
// multipliers. The expressions were altered in addScore(), so here just
|
||||
// add the arguments for the total.
|
||||
$i = 0;
|
||||
$sum = array_sum($this->multiply);
|
||||
foreach ($this->multiply as $total) {
|
||||
@@ -456,19 +488,25 @@ class SearchQuery extends SelectQueryExtender {
|
||||
}
|
||||
}
|
||||
|
||||
// Replace i.relevance pseudo-field with the actual, normalized value.
|
||||
$this->scores = str_replace('i.relevance', '(' . (1.0 / $this->normalize) . ' * i.score * t.count)', $this->scores);
|
||||
// Convert scores to an expression.
|
||||
// Replace the pseudo-expression 'i.relevance' with a measure of keyword
|
||||
// relevance in all score expressions, using string replacement. Careful
|
||||
// though! If you just print out a float, some locales use ',' as the
|
||||
// decimal separator in PHP, while SQL always uses '.'. So, make sure to
|
||||
// set the number format correctly.
|
||||
$relevance = number_format((1.0 / $this->normalize), 10, '.', '');
|
||||
$this->scores = str_replace('i.relevance', '(' . $relevance . ' * i.score * t.count)', $this->scores);
|
||||
|
||||
// Add all scores together to form a query field.
|
||||
$this->addExpression('SUM(' . implode(' + ', $this->scores) . ')', 'calculated_score', $this->scoresArguments);
|
||||
|
||||
// If an order has not yet been set for this query, add a default order
|
||||
// that sorts by the calculated sum of scores.
|
||||
if (count($this->getOrderBy()) == 0) {
|
||||
// Add default order after adding the expression.
|
||||
$this->orderBy('calculated_score', 'DESC');
|
||||
}
|
||||
|
||||
// Add tag and useful metadata.
|
||||
// Add useful metadata.
|
||||
$this
|
||||
->addTag('search_' . $this->type)
|
||||
->addMetaData('normalize', $this->normalize)
|
||||
->fields('i', array('type', 'sid'));
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ files[] = search.test
|
||||
configure = admin/config/search/settings
|
||||
stylesheets[all][] = search.css
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
@@ -12,6 +12,7 @@ function search_uninstall() {
|
||||
variable_del('minimum_word_size');
|
||||
variable_del('overlap_cjk');
|
||||
variable_del('search_cron_limit');
|
||||
variable_del('search_logging');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1067,7 +1067,7 @@ function template_preprocess_search_block_form(&$variables) {
|
||||
$hidden = array();
|
||||
// Provide variables named after form keys so themers can print each element independently.
|
||||
foreach (element_children($variables['form']) as $key) {
|
||||
$type = $variables['form'][$key]['#type'];
|
||||
$type = isset($variables['form'][$key]['#type']) ? $variables['form'][$key]['#type'] : '';
|
||||
if ($type == 'hidden' || $type == 'token') {
|
||||
$hidden[] = drupal_render($variables['form'][$key]);
|
||||
}
|
||||
@@ -1172,7 +1172,7 @@ function search_excerpt($keys, $text) {
|
||||
}
|
||||
else {
|
||||
$info = search_simplify_excerpt_match($key, $text, $included[$key], $boundary);
|
||||
if ($info['where']) {
|
||||
if (isset($info['where'])) {
|
||||
$p = $info['where'];
|
||||
if ($info['keyword']) {
|
||||
$foundkeys[] = $info['keyword'];
|
||||
|
||||
@@ -49,7 +49,7 @@ function search_view($module = NULL, $keys = '') {
|
||||
// which will get us back to this page callback. In other words, the search
|
||||
// form submits with POST but redirects to GET. This way we can keep
|
||||
// the search query URL clean as a whistle.
|
||||
if (empty($_POST['form_id']) || $_POST['form_id'] != 'search_form') {
|
||||
if (empty($_POST['form_id']) || ($_POST['form_id'] != 'search_form' && $_POST['form_id'] != 'search_block_form')) {
|
||||
$conditions = NULL;
|
||||
if (isset($info['conditions_callback']) && function_exists($info['conditions_callback'])) {
|
||||
// Build an optional array of more search conditions.
|
||||
@@ -57,9 +57,10 @@ function search_view($module = NULL, $keys = '') {
|
||||
}
|
||||
// Only search if there are keywords or non-empty conditions.
|
||||
if ($keys || !empty($conditions)) {
|
||||
// Log the search keys.
|
||||
watchdog('search', 'Searched %type for %keys.', array('%keys' => $keys, '%type' => $info['title']), WATCHDOG_NOTICE, l(t('results'), 'search/' . $info['path'] . '/' . $keys));
|
||||
|
||||
if (variable_get('search_logging', TRUE)) {
|
||||
// Log the search keys.
|
||||
watchdog('search', 'Searched %type for %keys.', array('%keys' => $keys, '%type' => $info['title']), WATCHDOG_NOTICE, l(t('results'), 'search/' . $info['path'] . '/' . $keys));
|
||||
}
|
||||
// Collect the search results.
|
||||
$results = search_data($keys, $info['module'], $conditions);
|
||||
}
|
||||
|
||||
+193
-56
@@ -11,6 +11,9 @@ define('SEARCH_TYPE', '_test_');
|
||||
define('SEARCH_TYPE_2', '_test2_');
|
||||
define('SEARCH_TYPE_JPN', '_test3_');
|
||||
|
||||
/**
|
||||
* Indexes content and queries it.
|
||||
*/
|
||||
class SearchMatchTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
@@ -275,7 +278,7 @@ class SearchPageText extends DrupalWebTestCase {
|
||||
$edit = array();
|
||||
$edit['keys'] = 'bike shed ' . $this->randomName();
|
||||
$this->drupalPost('search/node', $edit, t('Search'));
|
||||
$this->assertText(t('Consider loosening your query with OR. bike OR shed will often show more results than bike shed.'), t('Help text is displayed when search returns no results.'));
|
||||
$this->assertText(t('Consider loosening your query with OR. bike OR shed will often show more results than bike shed.'), 'Help text is displayed when search returns no results.');
|
||||
$this->assertText(t('Search'));
|
||||
$this->assertTitle($title, 'Search page title is correct');
|
||||
|
||||
@@ -307,6 +310,9 @@ class SearchPageText extends DrupalWebTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes content and tests the advanced search form.
|
||||
*/
|
||||
class SearchAdvancedSearchForm extends DrupalWebTestCase {
|
||||
protected $node;
|
||||
|
||||
@@ -342,34 +348,37 @@ class SearchAdvancedSearchForm extends DrupalWebTestCase {
|
||||
* Test using the advanced search form to limit search to nodes of type "Basic page".
|
||||
*/
|
||||
function testNodeType() {
|
||||
$this->assertTrue($this->node->type == 'page', t('Node type is Basic page.'));
|
||||
$this->assertTrue($this->node->type == 'page', 'Node type is Basic page.');
|
||||
|
||||
// Assert that the dummy title doesn't equal the real title.
|
||||
$dummy_title = 'Lorem ipsum';
|
||||
$this->assertNotEqual($dummy_title, $this->node->title, t("Dummy title doesn't equal node title"));
|
||||
$this->assertNotEqual($dummy_title, $this->node->title, "Dummy title doesn't equal node title");
|
||||
|
||||
// Search for the dummy title with a GET query.
|
||||
$this->drupalGet('search/node/' . $dummy_title);
|
||||
$this->assertNoText($this->node->title, t('Basic page node is not found with dummy title.'));
|
||||
$this->assertNoText($this->node->title, 'Basic page node is not found with dummy title.');
|
||||
|
||||
// Search for the title of the node with a GET query.
|
||||
$this->drupalGet('search/node/' . $this->node->title);
|
||||
$this->assertText($this->node->title, t('Basic page node is found with GET query.'));
|
||||
$this->assertText($this->node->title, 'Basic page node is found with GET query.');
|
||||
|
||||
// Search for the title of the node with a POST query.
|
||||
$edit = array('or' => $this->node->title);
|
||||
$this->drupalPost('search/node', $edit, t('Advanced search'));
|
||||
$this->assertText($this->node->title, t('Basic page node is found with POST query.'));
|
||||
$this->assertText($this->node->title, 'Basic page node is found with POST query.');
|
||||
|
||||
// Advanced search type option.
|
||||
$this->drupalPost('search/node', array_merge($edit, array('type[page]' => 'page')), t('Advanced search'));
|
||||
$this->assertText($this->node->title, t('Basic page node is found with POST query and type:page.'));
|
||||
$this->assertText($this->node->title, 'Basic page node is found with POST query and type:page.');
|
||||
|
||||
$this->drupalPost('search/node', array_merge($edit, array('type[article]' => 'article')), t('Advanced search'));
|
||||
$this->assertText('bike shed', t('Article node is not found with POST query and type:article.'));
|
||||
$this->assertText('bike shed', 'Article node is not found with POST query and type:article.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes content and tests ranking factors.
|
||||
*/
|
||||
class SearchRankingTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
@@ -464,7 +473,7 @@ class SearchRankingTestCase extends DrupalWebTestCase {
|
||||
function testHTMLRankings() {
|
||||
// Login with sufficient privileges.
|
||||
$this->drupalLogin($this->drupalCreateUser(array('create page content')));
|
||||
|
||||
|
||||
// Test HTML tags with different weights.
|
||||
$sorted_tags = array('h1', 'h2', 'h3', 'h4', 'a', 'h5', 'h6', 'notag');
|
||||
$shuffled_tags = $sorted_tags;
|
||||
@@ -496,7 +505,7 @@ class SearchRankingTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Refresh variables after the treatment.
|
||||
$this->refreshVariables();
|
||||
|
||||
|
||||
// Disable all other rankings.
|
||||
$node_ranks = array('sticky', 'promote', 'recent', 'comments', 'views');
|
||||
foreach ($node_ranks as $node_rank) {
|
||||
@@ -534,7 +543,7 @@ class SearchRankingTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Assert the results.
|
||||
$this->assertEqual($set[0]['node']->nid, $node->nid, 'Search tag ranking for "<' . $tag . '>" order.');
|
||||
|
||||
|
||||
// Delete node so it doesn't show up in subsequent search results.
|
||||
node_delete($node->nid);
|
||||
}
|
||||
@@ -580,6 +589,9 @@ class SearchRankingTestCase extends DrupalWebTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the rendering of the search block.
|
||||
*/
|
||||
class SearchBlockTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
@@ -600,13 +612,13 @@ class SearchBlockTestCase extends DrupalWebTestCase {
|
||||
function testSearchFormBlock() {
|
||||
// Set block title to confirm that the interface is available.
|
||||
$this->drupalPost('admin/structure/block/manage/search/form/configure', array('title' => $this->randomName(8)), t('Save block'));
|
||||
$this->assertText(t('The block configuration has been saved.'), t('Block configuration set.'));
|
||||
$this->assertText(t('The block configuration has been saved.'), 'Block configuration set.');
|
||||
|
||||
// Set the block to a region to confirm block is available.
|
||||
$edit = array();
|
||||
$edit['blocks[search_form][region]'] = 'footer';
|
||||
$this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
|
||||
$this->assertText(t('The block settings have been updated.'), t('Block successfully move to footer region.'));
|
||||
$this->assertText(t('The block settings have been updated.'), 'Block successfully move to footer region.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -640,7 +652,7 @@ class SearchBlockTestCase extends DrupalWebTestCase {
|
||||
$this->assertEqual(
|
||||
$this->getUrl(),
|
||||
url('search/node/' . $terms['search_block_form'], array('absolute' => TRUE)),
|
||||
t('Redirected to correct url.')
|
||||
'Redirected to correct url.'
|
||||
);
|
||||
|
||||
// Test an empty search via the block form, from the front page.
|
||||
@@ -652,8 +664,26 @@ class SearchBlockTestCase extends DrupalWebTestCase {
|
||||
$this->assertEqual(
|
||||
$this->getUrl(),
|
||||
url('search/node/', array('absolute' => TRUE)),
|
||||
t('Redirected to correct url.')
|
||||
'Redirected to correct url.'
|
||||
);
|
||||
|
||||
// Test that after entering a too-short keyword in the form, you can then
|
||||
// search again with a longer keyword. First test using the block form.
|
||||
$terms = array('search_block_form' => 'a');
|
||||
$this->drupalPost('node', $terms, t('Search'));
|
||||
$this->assertText('You must include at least one positive keyword with 3 characters or more');
|
||||
$terms = array('search_block_form' => 'foo');
|
||||
$this->drupalPost(NULL, $terms, t('Search'));
|
||||
$this->assertNoText('You must include at least one positive keyword with 3 characters or more');
|
||||
$this->assertText('Your search yielded no results');
|
||||
|
||||
// Same test again, using the search page form for the second search this time.
|
||||
$terms = array('search_block_form' => 'a');
|
||||
$this->drupalPost('node', $terms, t('Search'));
|
||||
$terms = array('keys' => 'foo');
|
||||
$this->drupalPost(NULL, $terms, t('Search'));
|
||||
$this->assertNoText('You must include at least one positive keyword with 3 characters or more');
|
||||
$this->assertText('Your search yielded no results');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -727,7 +757,7 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Comment Search tests',
|
||||
'description' => 'Verify text formats and filters used elsewhere.',
|
||||
'description' => 'Test integration searching comments.',
|
||||
'group' => 'Search',
|
||||
);
|
||||
}
|
||||
@@ -790,20 +820,20 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
'search_block_form' => "'" . $edit_comment['subject'] . "'",
|
||||
);
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertText($node->title, t('Node found in search results.'));
|
||||
$this->assertText($edit_comment['subject'], t('Comment subject found in search results.'));
|
||||
$this->assertText($node->title, 'Node found in search results.');
|
||||
$this->assertText($edit_comment['subject'], 'Comment subject found in search results.');
|
||||
|
||||
// Search for the comment body.
|
||||
$edit = array(
|
||||
'search_block_form' => "'" . $comment_body . "'",
|
||||
);
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertText($node->title, t('Node found in search results.'));
|
||||
$this->assertText($node->title, 'Node found in search results.');
|
||||
|
||||
// Verify that comment is rendered using proper format.
|
||||
$this->assertText($comment_body, t('Comment body text found in search results.'));
|
||||
$this->assertNoRaw(t('n/a'), t('HTML in comment body is not hidden.'));
|
||||
$this->assertNoRaw(check_plain($edit_comment['comment_body[' . LANGUAGE_NONE . '][0][value]']), t('HTML in comment body is not escaped.'));
|
||||
$this->assertText($comment_body, 'Comment body text found in search results.');
|
||||
$this->assertNoRaw(t('n/a'), 'HTML in comment body is not hidden.');
|
||||
$this->assertNoRaw(check_plain($edit_comment['comment_body[' . LANGUAGE_NONE . '][0][value]']), 'HTML in comment body is not escaped.');
|
||||
|
||||
// Hide comments.
|
||||
$this->drupalLogin($this->admin_user);
|
||||
@@ -816,7 +846,7 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Search for $title.
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertNoText($comment_body, t('Comment body text not found in search results.'));
|
||||
$this->assertNoText($comment_body, 'Comment body text not found in search results.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -875,7 +905,7 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
$this->setRolePermissions(DRUPAL_AUTHENTICATED_RID, TRUE, TRUE);
|
||||
$this->setRolePermissions($this->admin_role, TRUE, FALSE);
|
||||
$this->checkCommentAccess('Admin user has access comments permission and no search permission, but comments should be indexed because admin user inherits authenticated user\'s permission to search', TRUE);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -926,7 +956,7 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
// Verify that if you view the node on its own page, 'add new comment'
|
||||
// is there.
|
||||
$this->drupalGet('node/' . $node->nid);
|
||||
$this->assertText(t('Add new comment'), t('Add new comment appears on node page'));
|
||||
$this->assertText(t('Add new comment'), 'Add new comment appears on node page');
|
||||
|
||||
// Run cron to index this page.
|
||||
$this->drupalLogout();
|
||||
@@ -935,13 +965,13 @@ class SearchCommentTestCase extends DrupalWebTestCase {
|
||||
// Search for 'comment'. Should be no results.
|
||||
$this->drupalLogin($user);
|
||||
$this->drupalPost('search/node', array('keys' => 'comment'), t('Search'));
|
||||
$this->assertText(t('Your search yielded no results'), t('No results searching for the word comment'));
|
||||
$this->assertText(t('Your search yielded no results'), 'No results searching for the word comment');
|
||||
|
||||
// Search for the node title. Should be found, and 'Add new comment' should
|
||||
// not be part of the search snippet.
|
||||
$this->drupalPost('search/node', array('keys' => 'short'), t('Search'));
|
||||
$this->assertText($node->title, t('Search for keyword worked'));
|
||||
$this->assertNoText(t('Add new comment'), t('Add new comment does not appear on search results page'));
|
||||
$this->assertText($node->title, 'Search for keyword worked');
|
||||
$this->assertNoText(t('Add new comment'), 'Add new comment does not appear on search results page');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1074,8 +1104,8 @@ class SearchCommentCountToggleTestCase extends DrupalWebTestCase {
|
||||
|
||||
// Test comment count display for nodes with comment status set to Open
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertText(t('0 comments'), t('Empty comment count displays for nodes with comment status set to Open'));
|
||||
$this->assertText(t('1 comment'), t('Non-empty comment count displays for nodes with comment status set to Open'));
|
||||
$this->assertText(t('0 comments'), 'Empty comment count displays for nodes with comment status set to Open');
|
||||
$this->assertText(t('1 comment'), 'Non-empty comment count displays for nodes with comment status set to Open');
|
||||
|
||||
// Test comment count display for nodes with comment status set to Closed
|
||||
$this->searchable_nodes['0 comments']->comment = COMMENT_NODE_CLOSED;
|
||||
@@ -1084,8 +1114,8 @@ class SearchCommentCountToggleTestCase extends DrupalWebTestCase {
|
||||
node_save($this->searchable_nodes['1 comment']);
|
||||
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertNoText(t('0 comments'), t('Empty comment count does not display for nodes with comment status set to Closed'));
|
||||
$this->assertText(t('1 comment'), t('Non-empty comment count displays for nodes with comment status set to Closed'));
|
||||
$this->assertNoText(t('0 comments'), 'Empty comment count does not display for nodes with comment status set to Closed');
|
||||
$this->assertText(t('1 comment'), 'Non-empty comment count displays for nodes with comment status set to Closed');
|
||||
|
||||
// Test comment count display for nodes with comment status set to Hidden
|
||||
$this->searchable_nodes['0 comments']->comment = COMMENT_NODE_HIDDEN;
|
||||
@@ -1094,8 +1124,8 @@ class SearchCommentCountToggleTestCase extends DrupalWebTestCase {
|
||||
node_save($this->searchable_nodes['1 comment']);
|
||||
|
||||
$this->drupalPost('', $edit, t('Search'));
|
||||
$this->assertNoText(t('0 comments'), t('Empty comment count does not display for nodes with comment status set to Hidden'));
|
||||
$this->assertNoText(t('1 comment'), t('Non-empty comment count does not display for nodes with comment status set to Hidden'));
|
||||
$this->assertNoText(t('0 comments'), 'Empty comment count does not display for nodes with comment status set to Hidden');
|
||||
$this->assertNoText(t('1 comment'), 'Non-empty comment count does not display for nodes with comment status set to Hidden');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1160,7 +1190,7 @@ class SearchSimplifyTestCase extends DrupalWebTestCase {
|
||||
for ($i = 0; $i < 32; $i++) {
|
||||
$string .= chr($i);
|
||||
}
|
||||
$this->assertIdentical(' ', search_simplify($string), t('Search simplify works for ASCII control characters.'));
|
||||
$this->assertIdentical(' ', search_simplify($string), 'Search simplify works for ASCII control characters.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1316,7 +1346,7 @@ class SearchNumbersTestCase extends DrupalWebTestCase {
|
||||
$this->drupalPost('search/node',
|
||||
array('keys' => $number),
|
||||
t('Search'));
|
||||
$this->assertText($node->title, $type . ': node title shown (search found the node) in search for number ' . $number);
|
||||
$this->assertText($node->title, format_string('%type: node title shown (search found the node) in search for number %number.', array('%type' => $type, '%number' => $number)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1384,7 +1414,7 @@ class SearchNumberMatchingTestCase extends DrupalWebTestCase {
|
||||
$this->drupalPost('search/node',
|
||||
array('keys' => 'foo'),
|
||||
t('Search'));
|
||||
$this->assertNoText($node->title, $i . ': node title not shown in dummy search');
|
||||
$this->assertNoText($node->title, format_string('%number: node title not shown in dummy search', array('%number' => $i)));
|
||||
|
||||
// Now verify that we can find node i by searching for any of the
|
||||
// numbers.
|
||||
@@ -1397,7 +1427,7 @@ class SearchNumberMatchingTestCase extends DrupalWebTestCase {
|
||||
$this->drupalPost('search/node',
|
||||
array('keys' => $number),
|
||||
t('Search'));
|
||||
$this->assertText($node->title, $i . ': node title shown (search found the node) in search for number ' . $number);
|
||||
$this->assertText($node->title, format_string('%i: node title shown (search found the node) in search for number %number', array('%i' => $i, '%number' => $number)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1423,7 +1453,7 @@ class SearchConfigSettingsForm extends DrupalWebTestCase {
|
||||
parent::setUp('search', 'search_extra_type');
|
||||
|
||||
// Login as a user that can create and search content.
|
||||
$this->search_user = $this->drupalCreateUser(array('search content', 'administer search', 'administer nodes', 'bypass node access', 'access user profiles', 'administer users', 'administer blocks'));
|
||||
$this->search_user = $this->drupalCreateUser(array('search content', 'administer search', 'administer nodes', 'bypass node access', 'access user profiles', 'administer users', 'administer blocks', 'access site reports'));
|
||||
$this->drupalLogin($this->search_user);
|
||||
|
||||
// Add a single piece of content and index it.
|
||||
@@ -1472,6 +1502,19 @@ class SearchConfigSettingsForm extends DrupalWebTestCase {
|
||||
);
|
||||
$this->drupalPost('admin/config/search/settings', $edit, t('Save configuration'));
|
||||
$this->assertNoText(t('The configuration options have been saved.'), 'Form does not save with an invalid word length.');
|
||||
|
||||
// Test logging setting. It should be on by default.
|
||||
$text = $this->randomName(5);
|
||||
$this->drupalPost('search/node', array('keys' => $text), t('Search'));
|
||||
$this->drupalGet('admin/reports/dblog');
|
||||
$this->assertLink('Searched Content for ' . $text . '.', 0, 'Search was logged');
|
||||
|
||||
// Turn off logging.
|
||||
variable_set('search_logging', FALSE);
|
||||
$text = $this->randomName(5);
|
||||
$this->drupalPost('search/node', array('keys' => $text), t('Search'));
|
||||
$this->drupalGet('admin/reports/dblog');
|
||||
$this->assertNoLink('Searched Content for ' . $text . '.', 'Search was not logged');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1558,7 +1601,7 @@ class SearchConfigSettingsForm extends DrupalWebTestCase {
|
||||
$this->drupalGet($path);
|
||||
foreach ($modules as $module) {
|
||||
$title = $module_info[$module]['title'];
|
||||
$this->assertText($title, $title . ' search tab is shown');
|
||||
$this->assertText($title, format_string('%title search tab is shown', array('%title' => $title)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1567,7 +1610,7 @@ class SearchConfigSettingsForm extends DrupalWebTestCase {
|
||||
/**
|
||||
* Tests the search_excerpt() function.
|
||||
*/
|
||||
class SearchExcerptTestCase extends DrupalUnitTestCase {
|
||||
class SearchExcerptTestCase extends DrupalWebTestCase {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Search excerpt extraction',
|
||||
@@ -1577,8 +1620,7 @@ class SearchExcerptTestCase extends DrupalUnitTestCase {
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
drupal_load('module', 'search');
|
||||
parent::setUp();
|
||||
parent::setUp('search');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1603,7 +1645,7 @@ class SearchExcerptTestCase extends DrupalUnitTestCase {
|
||||
$this->assertEqual($result, 'The quick brown <strong>fox</strong> & jumps over the lazy dog ...', 'Found keyword is highlighted');
|
||||
|
||||
$longtext = str_repeat($text . ' ', 10);
|
||||
$result = preg_replace('| +|', ' ', search_excerpt('nothing', $text));
|
||||
$result = preg_replace('| +|', ' ', search_excerpt('nothing', $longtext));
|
||||
$this->assertTrue(strpos($result, $expected) === 0, 'When keyword is not found in long string, return value starts as expected');
|
||||
|
||||
$entities = str_repeat('készítése ', 20);
|
||||
@@ -1955,42 +1997,42 @@ class SearchLanguageTestCase extends DrupalWebTestCase {
|
||||
function testLanguages() {
|
||||
// Check that there are initially no languages displayed.
|
||||
$this->drupalGet('search/node');
|
||||
$this->assertNoText(t('Languages'), t('No languages to choose from.'));
|
||||
$this->assertNoText(t('Languages'), 'No languages to choose from.');
|
||||
|
||||
// Add predefined language.
|
||||
$edit = array('langcode' => 'fr');
|
||||
$this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
|
||||
$this->assertText('fr', t('Language added successfully.'));
|
||||
$this->assertText('fr', 'Language added successfully.');
|
||||
|
||||
// Now we should have languages displayed.
|
||||
$this->drupalGet('search/node');
|
||||
$this->assertText(t('Languages'), t('Languages displayed to choose from.'));
|
||||
$this->assertText(t('English'), t('English is a possible choice.'));
|
||||
$this->assertText(t('French'), t('French is a possible choice.'));
|
||||
$this->assertText(t('Languages'), 'Languages displayed to choose from.');
|
||||
$this->assertText(t('English'), 'English is a possible choice.');
|
||||
$this->assertText(t('French'), 'French is a possible choice.');
|
||||
|
||||
// Ensure selecting no language does not make the query different.
|
||||
$this->drupalPost('search/node', array(), t('Advanced search'));
|
||||
$this->assertEqual($this->getUrl(), url('search/node/', array('absolute' => TRUE)), t('Correct page redirection, no language filtering.'));
|
||||
$this->assertEqual($this->getUrl(), url('search/node/', array('absolute' => TRUE)), 'Correct page redirection, no language filtering.');
|
||||
|
||||
// Pick French and ensure it is selected.
|
||||
$edit = array('language[fr]' => TRUE);
|
||||
$this->drupalPost('search/node', $edit, t('Advanced search'));
|
||||
$this->assertFieldByXPath('//input[@name="keys"]', 'language:fr', t('Language filter added to query.'));
|
||||
$this->assertFieldByXPath('//input[@name="keys"]', 'language:fr', 'Language filter added to query.');
|
||||
|
||||
// Change the default language and disable English.
|
||||
$path = 'admin/config/regional/language';
|
||||
$this->drupalGet($path);
|
||||
$this->assertFieldChecked('edit-site-default-en', t('English is the default language.'));
|
||||
$this->assertFieldChecked('edit-site-default-en', 'English is the default language.');
|
||||
$edit = array('site_default' => 'fr');
|
||||
$this->drupalPost(NULL, $edit, t('Save configuration'));
|
||||
$this->assertNoFieldChecked('edit-site-default-en', t('Default language updated.'));
|
||||
$this->assertNoFieldChecked('edit-site-default-en', 'Default language updated.');
|
||||
$edit = array('enabled[en]' => FALSE);
|
||||
$this->drupalPost('admin/config/regional/language', $edit, t('Save configuration'));
|
||||
$this->assertNoFieldChecked('edit-enabled-en', t('Language disabled.'));
|
||||
$this->assertNoFieldChecked('edit-enabled-en', 'Language disabled.');
|
||||
|
||||
// Check that there are again no languages displayed.
|
||||
$this->drupalGet('search/node');
|
||||
$this->assertNoText(t('Languages'), t('No languages to choose from.'));
|
||||
$this->assertNoText(t('Languages'), 'No languages to choose from.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2018,10 +2060,11 @@ class SearchNodeAccessTest extends DrupalWebTestCase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that search returns results with punctuation in the search phrase.
|
||||
* Tests that search works with punctuation and HTML entities.
|
||||
*/
|
||||
function testPhraseSearchPunctuation() {
|
||||
$node = $this->drupalCreateNode(array('body' => array(LANGUAGE_NONE => array(array('value' => "The bunny's ears were fuzzy.")))));
|
||||
$node2 = $this->drupalCreateNode(array('body' => array(LANGUAGE_NONE => array(array('value' => 'Dignissim Aliquam & Quieligo meus natu quae quia te. Damnum© erat— neo pneum. Facilisi feugiat ibidem ratis.')))));
|
||||
|
||||
// Update the search index.
|
||||
module_invoke_all('update_index');
|
||||
@@ -2034,5 +2077,99 @@ class SearchNodeAccessTest extends DrupalWebTestCase {
|
||||
$edit = array('keys' => '"bunny\'s"');
|
||||
$this->drupalPost('search/node', $edit, t('Search'));
|
||||
$this->assertText($node->title);
|
||||
|
||||
// Search for "&" and verify entities are not broken up in the output.
|
||||
$edit = array('keys' => '&');
|
||||
$this->drupalPost('search/node', $edit, t('Search'));
|
||||
$this->assertNoRaw('<strong>&</strong>amp;');
|
||||
$this->assertText('You must include at least one positive keyword');
|
||||
|
||||
$edit = array('keys' => '&');
|
||||
$this->drupalPost('search/node', $edit, t('Search'));
|
||||
$this->assertNoRaw('<strong>&</strong>amp;');
|
||||
$this->assertText('You must include at least one positive keyword');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests node search with query tags.
|
||||
*/
|
||||
class SearchNodeTagTest extends DrupalWebTestCase {
|
||||
public $test_user;
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Node search query tags',
|
||||
'description' => 'Tests Node search tags functionality.',
|
||||
'group' => 'Search',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('search', 'search_node_tags');
|
||||
node_access_rebuild();
|
||||
|
||||
// Create a test user and log in.
|
||||
$this->test_user = $this->drupalCreateUser(array('search content'));
|
||||
$this->drupalLogin($this->test_user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the correct tags are available and hooks invoked.
|
||||
*/
|
||||
function testNodeSearchQueryTags() {
|
||||
$this->drupalCreateNode(array('body' => array(LANGUAGE_NONE => array(array('value' => 'testing testing testing.')))));
|
||||
|
||||
// Update the search index.
|
||||
module_invoke_all('update_index');
|
||||
search_update_totals();
|
||||
|
||||
$edit = array('keys' => 'testing');
|
||||
$this->drupalPost('search/node', $edit, t('Search'));
|
||||
|
||||
$this->assertTrue(variable_get('search_node_tags_test_query_tag', FALSE), 'hook_query_alter() was invoked and the query contained the "search_node" tag.');
|
||||
$this->assertTrue(variable_get('search_node_tags_test_query_tag_hook', FALSE), 'hook_query_search_node_alter() was invoked.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests searching with locale values set.
|
||||
*/
|
||||
class SearchSetLocaleTest extends DrupalWebTestCase {
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Search with numeric locale set',
|
||||
'description' => 'Check that search works with numeric locale settings',
|
||||
'group' => 'Search',
|
||||
);
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp('search');
|
||||
|
||||
// Create a simple node so something will be put in the index.
|
||||
$info = array(
|
||||
'body' => array(LANGUAGE_NONE => array(array('value' => 'Tapir'))),
|
||||
);
|
||||
$this->drupalCreateNode($info);
|
||||
|
||||
// Run cron to index.
|
||||
$this->cronRun();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that search works with a numeric locale set.
|
||||
*/
|
||||
public function testSearchWithNumericLocale() {
|
||||
// French decimal point is comma.
|
||||
setlocale(LC_NUMERIC, 'fr_FR');
|
||||
|
||||
// An exception will be thrown if a float in the wrong format occurs in the
|
||||
// query to the database, so an assertion is not necessary here.
|
||||
db_select('search_index', 'i')
|
||||
->extend('searchquery')
|
||||
->searchexpression('tapir', 'node')
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,7 @@ version = VERSION
|
||||
core = 7.x
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
@@ -5,8 +5,7 @@ version = VERSION
|
||||
core = 7.x
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
name = "Test search node tags"
|
||||
description = "Support module for Node search tags testing."
|
||||
package = Testing
|
||||
version = VERSION
|
||||
core = 7.x
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1600272641"
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Dummy module implementing a node search hooks for search module testing.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Implements hook_query_alter().
|
||||
*/
|
||||
function search_node_tags_query_alter(QueryAlterableInterface $query) {
|
||||
if ($query->hasTag('search_node')) {
|
||||
variable_set('search_node_tags_test_query_tag', TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_query_TAG_alter().
|
||||
*/
|
||||
function search_node_tags_query_search_node_alter(QueryAlterableInterface $query) {
|
||||
variable_set('search_node_tags_test_query_tag_hook', TRUE);
|
||||
}
|
||||
Reference in New Issue
Block a user