upgrades core to 8.4.2
This commit is contained in:
@@ -10,6 +10,7 @@ source:
|
||||
- minimum_word_size
|
||||
- overlap_cjk
|
||||
- search_cron_limit
|
||||
source_module: search
|
||||
process:
|
||||
'index/minimum_word_size': minimum_word_size
|
||||
'index/overlap_cjk': overlap_cjk
|
||||
|
||||
@@ -13,6 +13,7 @@ source:
|
||||
- search_tag_weights
|
||||
- search_and_or_limit
|
||||
- search_default_module
|
||||
source_module: search
|
||||
process:
|
||||
'index/minimum_word_size': minimum_word_size
|
||||
'index/overlap_cjk': overlap_cjk
|
||||
|
||||
@@ -16,6 +16,7 @@ source:
|
||||
id: node_search
|
||||
path: node
|
||||
plugin: node_search
|
||||
source_module: search
|
||||
process:
|
||||
id: 'constants/id'
|
||||
path: 'constants/path'
|
||||
|
||||
@@ -6,8 +6,8 @@ package: Core
|
||||
# core: 8.x
|
||||
configure: entity.search_page.collection
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Cache\Cache;
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
|
||||
@@ -218,7 +219,7 @@ function search_update_totals() {
|
||||
// search_total. We use a LEFT JOIN between the two tables and keep only the
|
||||
// rows which fail to join.
|
||||
$result = db_query("SELECT t.word AS realword, i.word FROM {search_total} t LEFT JOIN {search_index} i ON t.word = i.word WHERE i.word IS NULL", [], ['target' => 'replica']);
|
||||
$or = db_or();
|
||||
$or = new Condition('OR');
|
||||
foreach ($result as $word) {
|
||||
$or->condition('word', $word->realword);
|
||||
}
|
||||
@@ -445,14 +446,21 @@ function search_index($type, $sid, $langcode, $text) {
|
||||
// Note: PHP ensures the array consists of alternating delimiters and literals
|
||||
// and begins and ends with a literal (inserting $null as required).
|
||||
|
||||
$tag = FALSE; // Odd/even counter. Tag or no tag.
|
||||
$score = 1; // Starting score per word
|
||||
$accum = ' '; // Accumulator for cleaned up data
|
||||
$tagstack = []; // Stack with open tags
|
||||
$tagwords = 0; // Counter for consecutive words
|
||||
$focus = 1; // Focus state
|
||||
// Odd/even counter. Tag or no tag.
|
||||
$tag = FALSE;
|
||||
// Starting score per word.
|
||||
$score = 1;
|
||||
// Accumulator for cleaned up data.
|
||||
$accum = ' ';
|
||||
// Stack with open tags.
|
||||
$tagstack = [];
|
||||
// Counter for consecutive words.
|
||||
$tagwords = 0;
|
||||
// Focus state.
|
||||
$focus = 1;
|
||||
|
||||
$scored_words = []; // Accumulator for words for index
|
||||
// Accumulator for words for index.
|
||||
$scored_words = [];
|
||||
|
||||
foreach ($split as $value) {
|
||||
if ($tag) {
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Drupal\search\Controller;
|
||||
use Drupal\Core\Cache\CacheableDependencyInterface;
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\search\Form\SearchPageForm;
|
||||
use Drupal\search\SearchPageInterface;
|
||||
use Drupal\search\SearchPageRepositoryInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
@@ -84,7 +85,7 @@ class SearchController extends ControllerBase {
|
||||
}
|
||||
|
||||
$build['#title'] = $plugin->suggestedTitle();
|
||||
$build['search_form'] = $this->entityFormBuilder()->getForm($entity, 'search');
|
||||
$build['search_form'] = $this->formBuilder()->getForm(SearchPageForm::class, $entity);
|
||||
|
||||
// Build search results, if keywords or other search parameters are in the
|
||||
// GET parameters. Note that we need to try the search if 'keys' is in
|
||||
@@ -148,8 +149,6 @@ class SearchController extends ControllerBase {
|
||||
/**
|
||||
* Creates a render array for the search help page.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object.
|
||||
* @param \Drupal\search\SearchPageInterface $entity
|
||||
* The search page entity.
|
||||
*
|
||||
|
||||
@@ -22,7 +22,6 @@ use Drupal\search\SearchPageInterface;
|
||||
* "form" = {
|
||||
* "add" = "Drupal\search\Form\SearchPageAddForm",
|
||||
* "edit" = "Drupal\search\Form\SearchPageEditForm",
|
||||
* "search" = "Drupal\search\Form\SearchPageForm",
|
||||
* "delete" = "Drupal\Core\Entity\EntityDeleteForm"
|
||||
* }
|
||||
* },
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
namespace Drupal\search\Form;
|
||||
|
||||
use Drupal\Core\Entity\EntityForm;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\search\SearchPageInterface;
|
||||
|
||||
/**
|
||||
* Provides a search form for site wide search.
|
||||
@@ -15,10 +16,10 @@ use Drupal\Core\Url;
|
||||
* trigger the search being processed by the controller, and adding in any
|
||||
* additional query parameters they need to execute search.
|
||||
*/
|
||||
class SearchPageForm extends EntityForm {
|
||||
class SearchPageForm extends FormBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* The search page entity.
|
||||
*
|
||||
* @var \Drupal\search\SearchPageInterface
|
||||
*/
|
||||
@@ -34,7 +35,9 @@ class SearchPageForm extends EntityForm {
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function form(array $form, FormStateInterface $form_state) {
|
||||
public function buildForm(array $form, FormStateInterface $form_state, SearchPageInterface $search_page = NULL) {
|
||||
$this->entity = $search_page;
|
||||
|
||||
$plugin = $this->entity->getPlugin();
|
||||
$form_state->set('search_page_id', $this->entity->id());
|
||||
|
||||
@@ -72,16 +75,7 @@ class SearchPageForm extends EntityForm {
|
||||
|
||||
// Allow the plugin to add to or alter the search form.
|
||||
$plugin->searchFormAlter($form, $form_state);
|
||||
|
||||
return parent::form($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function actions(array $form, FormStateInterface $form_state) {
|
||||
// The submit button is added in the form directly.
|
||||
return [];
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,7 @@ abstract class ConfigurableSearchPluginBase extends SearchPluginBase implements
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $this->configuration);
|
||||
$this->setConfiguration($configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +44,7 @@ abstract class ConfigurableSearchPluginBase extends SearchPluginBase implements
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setConfiguration(array $configuration) {
|
||||
$this->configuration = $configuration;
|
||||
$this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -110,7 +110,7 @@ interface SearchInterface extends PluginInspectionInterface {
|
||||
*
|
||||
* The core search module only invokes this method on active module plugins
|
||||
* when building a form for them in
|
||||
* \Drupal\search\Form\SearchPageForm::form(). A plugin implementing this
|
||||
* \Drupal\search\Form\SearchPageForm::buildForm(). A plugin implementing this
|
||||
* will also need to implement the buildSearchUrlQuery() method.
|
||||
*
|
||||
* @param array $form
|
||||
|
||||
@@ -146,16 +146,18 @@ abstract class SearchPluginBase extends PluginBase implements ContainerFactoryPl
|
||||
public function getHelp() {
|
||||
// This default search help is appropriate for plugins like NodeSearch
|
||||
// that use the SearchQuery class.
|
||||
$help = ['list' => [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => [
|
||||
$this->t('Search looks for exact, case-insensitive keywords; keywords shorter than a minimum length are ignored.'),
|
||||
$this->t('Use upper-case OR to get more results. Example: cat OR dog (content contains either "cat" or "dog").'),
|
||||
$this->t('You can use upper-case AND to require all words, but this is the same as the default behavior. Example: cat AND dog (same as cat dog, content must contain both "cat" and "dog").'),
|
||||
$this->t('Use quotes to search for a phrase. Example: "the cat eats mice".'),
|
||||
$this->t('You can precede keywords by - to exclude them; you must still have at least one "positive" keyword. Example: cat -dog (content must contain cat and cannot contain dog).'),
|
||||
$help = [
|
||||
'list' => [
|
||||
'#theme' => 'item_list',
|
||||
'#items' => [
|
||||
$this->t('Search looks for exact, case-insensitive keywords; keywords shorter than a minimum length are ignored.'),
|
||||
$this->t('Use upper-case OR to get more results. Example: cat OR dog (content contains either "cat" or "dog").'),
|
||||
$this->t('You can use upper-case AND to require all words, but this is the same as the default behavior. Example: cat AND dog (same as cat dog, content must contain both "cat" and "dog").'),
|
||||
$this->t('Use quotes to search for a phrase. Example: "the cat eats mice".'),
|
||||
$this->t('You can precede keywords by - to exclude them; you must still have at least one "positive" keyword. Example: cat -dog (content must contain cat and cannot contain dog).'),
|
||||
],
|
||||
],
|
||||
]];
|
||||
];
|
||||
|
||||
return $help;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\search\Plugin\views\argument;
|
||||
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\views\Plugin\views\argument\ArgumentPluginBase;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
use Drupal\views\ViewExecutable;
|
||||
@@ -76,7 +77,7 @@ class Search extends ArgumentPluginBase {
|
||||
else {
|
||||
$search_index = $this->ensureMyTable();
|
||||
|
||||
$search_condition = db_and();
|
||||
$search_condition = new Condition('AND');
|
||||
|
||||
// Create a new join to relate the 'search_total' table to our current 'search_index' table.
|
||||
$definition = [
|
||||
@@ -96,7 +97,7 @@ class Search extends ArgumentPluginBase {
|
||||
$search_dataset = $this->query->addTable('node_search_dataset');
|
||||
$conditions = $this->searchQuery->conditions();
|
||||
$condition_conditions =& $conditions->conditions();
|
||||
foreach ($condition_conditions as $key => &$condition) {
|
||||
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.
|
||||
@@ -109,7 +110,7 @@ class Search extends ArgumentPluginBase {
|
||||
// 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();
|
||||
$or = new Condition('OR');
|
||||
foreach ($words as $word) {
|
||||
$or->condition("$search_index.word", $word);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\search\Plugin\views\filter;
|
||||
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\views\Plugin\views\filter\FilterPluginBase;
|
||||
use Drupal\views\Plugin\views\display\DisplayPluginBase;
|
||||
@@ -150,7 +151,7 @@ class Search extends FilterPluginBase {
|
||||
else {
|
||||
$search_index = $this->ensureMyTable();
|
||||
|
||||
$search_condition = db_and();
|
||||
$search_condition = new Condition('AND');
|
||||
|
||||
// Create a new join to relate the 'search_total' table to our current
|
||||
// 'search_index' table.
|
||||
@@ -171,7 +172,7 @@ class Search extends FilterPluginBase {
|
||||
$search_dataset = $this->query->addTable('node_search_dataset');
|
||||
$conditions = $this->searchQuery->conditions();
|
||||
$condition_conditions =& $conditions->conditions();
|
||||
foreach ($condition_conditions as $key => &$condition) {
|
||||
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.
|
||||
@@ -184,7 +185,7 @@ class Search extends FilterPluginBase {
|
||||
// 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();
|
||||
$or = new Condition('OR');
|
||||
foreach ($words as $word) {
|
||||
$or->condition("$search_index.word", $word);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Drupal\search;
|
||||
|
||||
use Drupal\Core\Database\Query\Condition;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Database\Query\SelectExtender;
|
||||
use Drupal\Core\Database\Query\SelectInterface;
|
||||
@@ -205,7 +206,7 @@ class SearchQuery extends SelectExtender {
|
||||
$this->addTag('search_' . $type);
|
||||
|
||||
// Initialize conditions and status.
|
||||
$this->conditions = db_and();
|
||||
$this->conditions = new Condition('AND');
|
||||
$this->status = 0;
|
||||
|
||||
return $this;
|
||||
@@ -313,7 +314,7 @@ class SearchQuery extends SelectExtender {
|
||||
}
|
||||
$has_or = TRUE;
|
||||
$has_new_scores = FALSE;
|
||||
$queryor = db_or();
|
||||
$queryor = new Condition('OR');
|
||||
foreach ($key as $or) {
|
||||
list($num_new_scores) = $this->parseWord($or);
|
||||
$has_new_scores |= $num_new_scores;
|
||||
@@ -401,7 +402,7 @@ class SearchQuery extends SelectExtender {
|
||||
}
|
||||
|
||||
// Build the basic search query: match the entered keywords.
|
||||
$or = db_or();
|
||||
$or = new Condition('OR');
|
||||
foreach ($this->words as $word) {
|
||||
$or->condition('i.word', $word);
|
||||
}
|
||||
@@ -573,7 +574,7 @@ class SearchQuery extends SelectExtender {
|
||||
|
||||
// Add arguments for the keyword relevance normalization number.
|
||||
$normalization = 1.0 / $this->normalize;
|
||||
for ($i = 0; $i < $this->relevance_count; $i++ ) {
|
||||
for ($i = 0; $i < $this->relevance_count; $i++) {
|
||||
$this->scoresArguments[':normalization_' . $i] = $normalization;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class SearchConfigSettingsFormTest extends SearchTestBase {
|
||||
// also needs the word "pizza" so we can use it as the search keyword.
|
||||
$body_key = 'body[0][value]';
|
||||
$edit[$body_key] = \Drupal::l($node->label(), $node->urlInfo()) . ' pizza sandwich';
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
|
||||
$this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
|
||||
|
||||
$this->container->get('plugin.manager.search')->createInstance('node_search')->updateIndex();
|
||||
search_update_totals();
|
||||
@@ -177,7 +177,7 @@ class SearchConfigSettingsFormTest extends SearchTestBase {
|
||||
$this->submitGetForm('node', $terms, t('Search'));
|
||||
$current = $this->getURL();
|
||||
$expected = \Drupal::url('search.view_' . $entity->id(), [], ['query' => ['keys' => $info['keys']], 'absolute' => TRUE]);
|
||||
$this->assertEqual( $current, $expected, 'Block redirected to right search page');
|
||||
$this->assertEqual($current, $expected, 'Block redirected to right search page');
|
||||
|
||||
// Try an invalid search path, which should 404.
|
||||
$this->drupalGet('search/not_a_plugin_path');
|
||||
|
||||
@@ -39,7 +39,8 @@ class SearchNodeUpdateAndDeletionTest extends SearchTestBase {
|
||||
$node = $this->drupalCreateNode([
|
||||
'title' => 'Someone who says Ni!',
|
||||
'body' => [['value' => "We are the knights who say Ni!"]],
|
||||
'type' => 'page']);
|
||||
'type' => 'page',
|
||||
]);
|
||||
|
||||
$node_search_plugin = $this->container->get('plugin.manager.search')->createInstance('node_search');
|
||||
// Update the search index.
|
||||
@@ -73,7 +74,8 @@ class SearchNodeUpdateAndDeletionTest extends SearchTestBase {
|
||||
$node = $this->drupalCreateNode([
|
||||
'title' => 'No dragons here',
|
||||
'body' => [['value' => 'Again: No dragons here']],
|
||||
'type' => 'page']);
|
||||
'type' => 'page',
|
||||
]);
|
||||
|
||||
$node_search_plugin = $this->container->get('plugin.manager.search')->createInstance('node_search');
|
||||
// Update the search index.
|
||||
|
||||
@@ -53,9 +53,9 @@ class SearchRankingTest extends SearchTestBase {
|
||||
foreach ($node_ranks as $node_rank) {
|
||||
$settings = [
|
||||
'type' => 'page',
|
||||
'comment' => [[
|
||||
'status' => CommentItemInterface::HIDDEN,
|
||||
]],
|
||||
'comment' => [
|
||||
['status' => CommentItemInterface::HIDDEN],
|
||||
],
|
||||
'title' => 'Drupal rocks',
|
||||
'body' => [['value' => "Drupal's search rocks"]],
|
||||
// Node is one day old.
|
||||
|
||||
@@ -74,8 +74,8 @@ class ViewsSearchQuery extends SearchQuery {
|
||||
$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.
|
||||
// As conditions can be nested, the function has to be called
|
||||
// recursively.
|
||||
$this->conditionReplaceString($search, $replace, $subcondition);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -8,8 +8,8 @@ dependencies:
|
||||
- test_page_test
|
||||
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ class SearchExtraTypeSearch extends ConfigurableSearchPluginBase {
|
||||
$pager = [
|
||||
'#type' => 'pager',
|
||||
];
|
||||
$output['suffix']['#markup'] = '</ol>' . drupal_render($pager);
|
||||
$output['suffix']['#markup'] = '</ol>' . \Drupal::service('renderer')->render($pager);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -5,8 +5,8 @@ package: Testing
|
||||
# version: VERSION
|
||||
# core: 8.x
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-08-16
|
||||
version: '8.3.7'
|
||||
# Information added by Drupal.org packaging script on 2017-11-03
|
||||
version: '8.4.2'
|
||||
core: '8.x'
|
||||
project: 'drupal'
|
||||
datestamp: 1502903957
|
||||
datestamp: 1509719929
|
||||
|
||||
@@ -78,16 +78,11 @@ class SearchMultilingualEntityTest extends SearchTestBase {
|
||||
// After the third node, we don't care what the settings are. But we
|
||||
// need to have at least 5 to make sure the throttling is working
|
||||
// correctly. So, let's make 8 total.
|
||||
[
|
||||
],
|
||||
[
|
||||
],
|
||||
[
|
||||
],
|
||||
[
|
||||
],
|
||||
[
|
||||
],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
];
|
||||
$this->searchableNodes = [];
|
||||
foreach ($nodes as $setting) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\search\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\search\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user