diff --git a/core/modules/help_topics/help_topics.install b/core/modules/help_topics/help_topics.install index b0b604f0a9..ef3e343da2 100644 --- a/core/modules/help_topics/help_topics.install +++ b/core/modules/help_topics/help_topics.install @@ -18,8 +18,8 @@ function help_topics_schema() { 'unsigned' => TRUE, 'not null' => TRUE, ], - 'plugin_type' => [ - 'description' => 'The help plugin type the item comes from', + 'section_plugin_id' => [ + 'description' => 'The help section the item comes from', 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, @@ -32,8 +32,8 @@ function help_topics_schema() { 'not null' => TRUE, 'default' => '', ], - 'id' => [ - 'description' => 'The plugin ID of the item', + 'topic_id' => [ + 'description' => 'The topic ID of the item', 'type' => 'varchar_ascii', 'length' => 255, 'not null' => TRUE, @@ -42,8 +42,8 @@ function help_topics_schema() { ], 'primary key' => ['sid'], 'indexes' => [ - 'plugin_type' => ['plugin_type'], - 'id' => ['id'], + 'section_plugin_id' => ['section_plugin_id'], + 'topic_id' => ['topic_id'], ], ]; diff --git a/core/modules/help_topics/src/Plugin/HelpSection/HelpTopicSection.php b/core/modules/help_topics/src/Plugin/HelpSection/HelpTopicSection.php index 5466475974..c604d650ae 100644 --- a/core/modules/help_topics/src/Plugin/HelpSection/HelpTopicSection.php +++ b/core/modules/help_topics/src/Plugin/HelpSection/HelpTopicSection.php @@ -202,8 +202,8 @@ public function listSearchableTopics() { /** * {@inheritdoc} */ - public function renderTopicForSearch($id, LanguageInterface $language) { - $plugin = $this->pluginManager->createInstance($id); + public function renderTopicForSearch($topic_id, LanguageInterface $language) { + $plugin = $this->pluginManager->createInstance($topic_id); if (!$plugin) { return []; } diff --git a/core/modules/help_topics/src/Plugin/Search/HelpSearch.php b/core/modules/help_topics/src/Plugin/Search/HelpSearch.php index 4967f0abc6..bb2f2eb1f3 100644 --- a/core/modules/help_topics/src/Plugin/Search/HelpSearch.php +++ b/core/modules/help_topics/src/Plugin/Search/HelpSearch.php @@ -89,7 +89,7 @@ class HelpSearch extends SearchPluginBase implements AccessibleInterface, Search * * @var \Drupal\help\HelpSectionManager */ - protected $helpManager; + protected $helpSectionManager; /** * {@inheritdoc} @@ -130,10 +130,10 @@ public static function create(ContainerInterface $container, array $configuratio * The $account object to use for checking for access to view help. * @param \Drupal\Core\State\StateInterface $state * The state object. - * @param \Drupal\help\HelpSectionManager $help_manager + * @param \Drupal\help\HelpSectionManager $help_section_manager * The help section manager. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, Config $search_settings, LanguageManagerInterface $language_manager, MessengerInterface $messenger, AccountInterface $account = NULL, StateInterface $state, HelpSectionManager $help_manager) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database, Config $search_settings, LanguageManagerInterface $language_manager, MessengerInterface $messenger, AccountInterface $account, StateInterface $state, HelpSectionManager $help_section_manager) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->database = $database; $this->searchSettings = $search_settings; @@ -141,7 +141,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition $this->messenger = $messenger; $this->account = $account; $this->state = $state; - $this->helpManager = $help_manager; + $this->helpSectionManager = $help_section_manager; } /** @@ -193,14 +193,16 @@ protected function findResults() { if (!$this->account->hasPermission('access administration pages')) { return NULL; } - $denied_permissions = array_filter($this->database + $permissions = $this->database ->select('help_search_items', 'hsi') + ->distinct() ->fields('hsi', ['permission']) - ->groupBy('hsi.permission') + ->condition('permission', '', '<>') ->execute() - ->fetchCol(), function ($permission) { - return $permission && !$this->account->hasPermission($permission); - }); + ->fetchCol(); + $denied_permissions = array_filter($permissions, function ($permission) { + return !$this->account->hasPermission($permission); + }); $query = $this->database ->select('search_index', 'i') @@ -208,11 +210,11 @@ protected function findResults() { ->condition('i.langcode', $this->languageManager->getCurrentLanguage()->getId()) ->extend(SearchQuery::class) ->extend(PagerSelectExtender::class); - $query->join('help_search_items', 'hsi', 'i.sid = hsi.sid AND i.type = :type', [':type' => $this->getPluginId()]); - if (count($denied_permissions)) { + $query->innerJoin('help_search_items', 'hsi', 'i.sid = hsi.sid AND i.type = :type', [':type' => $this->getType()]); + if ($denied_permissions) { $query->condition('hsi.permission', $denied_permissions, 'NOT IN'); } - $query->searchExpression($this->getKeywords(), $this->getPluginId()); + $query->searchExpression($this->getKeywords(), $this->getType()); $find = $query ->fields('i', ['langcode']) @@ -258,18 +260,18 @@ protected function prepareResults(StatementInterface $found) { foreach ($found as $item) { $record = $this->database->select('help_search_items', 'hsi') ->condition('sid', $item->sid) - ->fields('hsi', ['plugin_type', 'id']) + ->fields('hsi', ['section_plugin_id', 'topic_id']) ->execute()->fetchObject(); - $type = $record->plugin_type; - if (!isset($plugins[$type])) { - $plugins[$type] = $this->getSectionPlugin($type); + $section_plugin_id = $record->section_plugin_id; + if (!isset($plugins[$section_plugin_id])) { + $plugins[$section_plugin_id] = $this->getSectionPlugin($section_plugin_id); } - if ($plugins[$type]) { + if ($plugins[$section_plugin_id]) { $langcode = $item->langcode; if (!isset($languages[$langcode])) { $languages[$langcode] = $this->languageManager->getLanguage($item->langcode); } - $topic = $plugins[$type]->renderTopicForSearch($record->id, $languages[$langcode]); + $topic = $plugins[$section_plugin_id]->renderTopicForSearch($record->topic_id, $languages[$langcode]); if ($topic) { if (isset($topic['cacheable_metadata'])) { $this->addCacheableDependency($topic['cacheable_metadata']); @@ -301,12 +303,12 @@ public function updateIndex() { $limit = (int) $this->searchSettings->get('index.cron_limit'); $query = $this->database->select('help_search_items', 'hsi'); - $query->fields('hsi', ['sid', 'plugin_type', 'id']); - $query->leftJoin('search_dataset', 'sd', 'sd.sid = hsi.sid AND sd.type = :type', [':type' => $this->getPluginId()]); + $query->fields('hsi', ['sid', 'section_plugin_id', 'topic_id']); + $query->leftJoin('search_dataset', 'sd', 'sd.sid = hsi.sid AND sd.type = :type', [':type' => $this->getType()]); $query->where('sd.sid IS NULL'); $query->groupBy('hsi.sid') - ->groupBy('hsi.plugin_type') - ->groupBy('hsi.id') + ->groupBy('hsi.section_plugin_id') + ->groupBy('hsi.topic_id') ->range(0, $limit); $items = $query->execute()->fetchAll(); @@ -314,39 +316,39 @@ public function updateIndex() { // been indexed before, but are currently marked as needing a re-index. if (count($items) < $limit) { $query = $this->database->select('help_search_items', 'hsi'); - $query->fields('hsi', ['sid', 'plugin_type', 'id']); - $query->leftJoin('search_dataset', 'sd', 'sd.sid = hsi.sid AND sd.type = :type', [':type' => $this->getPluginId()]); + $query->fields('hsi', ['sid', 'section_plugin_id', 'topic_id']); + $query->leftJoin('search_dataset', 'sd', 'sd.sid = hsi.sid AND sd.type = :type', [':type' => $this->getType()]); $query->condition('sd.reindex', 0, '<>'); $query->groupBy('hsi.sid') - ->groupBy('hsi.plugin_type') - ->groupBy('hsi.id') + ->groupBy('hsi.section_plugin_id') + ->groupBy('hsi.topic_id') ->range(0, $limit - count($items)); $items = $items + $query->execute()->fetchAll(); } // Index the items we have chosen, in all available languages. $language_list = $this->languageManager->getLanguages(LanguageInterface::STATE_CONFIGURABLE); - $plugins = []; + $section_plugins = []; foreach ($items as $item) { - $type = $item->plugin_type; - if (!isset($plugins[$type])) { - $plugins[$type] = $this->getSectionPlugin($type); + $section_plugin_id = $item->section_plugin_id; + if (!isset($section_plugins[$section_plugin_id])) { + $section_plugins[$section_plugin_id] = $this->getSectionPlugin($section_plugin_id); } - if (!$plugins[$type]) { + if (!$section_plugins[$section_plugin_id]) { $this->removeItemsFromIndex($item->sid); continue; } - $plugin = $plugins[$type]; - search_index_clear($this->getPluginId(), $item->sid); + $section_plugin = $section_plugins[$section_plugin_id]; + search_index_clear($this->getType(), $item->sid); foreach ($language_list as $langcode => $language) { - $topic = $plugin->renderTopicForSearch($item->id, $language); + $topic = $section_plugin->renderTopicForSearch($item->topic_id, $language); if ($topic) { // Index the title plus body text. $text = '

' . $topic['title'] . '

' . "\n" . $topic['text']; - search_index($this->getPluginId(), $item->sid, $langcode, $text); + search_index($this->getType(), $item->sid, $langcode, $text); } } } @@ -356,7 +358,7 @@ public function updateIndex() { * {@inheritdoc} */ public function indexClear() { - search_index_clear($this->getPluginId()); + search_index_clear($this->getType()); } /** @@ -366,30 +368,25 @@ public function markForReindex() { // Update the list of help items. Start by fetching the existing list, // so we can remove items not found at the end. $old_list = $this->database->select('help_search_items', 'hsi') - ->fields('hsi', ['sid', 'id', 'plugin_type', 'permission']) - ->execute() - ->fetchAll(); + ->fields('hsi', ['sid', 'topic_id', 'section_plugin_id', 'permission']) + ->execute(); $old_list_ordered = []; $sids_to_remove = []; foreach ($old_list as $item) { - $old_list_ordered[$item->plugin_type][$item->id] = $item; + $old_list_ordered[$item->section_plugin_id][$item->topic_id] = $item; $sids_to_remove[$item->sid] = $item->sid; } - $plugins = $this->helpManager->getDefinitions(); - foreach ($plugins as $plugin_id => $plugin_definition) { - $plugin = $this->getSectionPlugin($plugin_id); + $section_plugins = $this->helpSectionManager->getDefinitions(); + foreach ($section_plugins as $section_plugin_id => $section_plugin_definition) { + $plugin = $this->getSectionPlugin($section_plugin_id); if (!$plugin) { continue; } - $permission = $plugin_definition['permission'] ?? ''; - $items = $plugin->listSearchableTopics(); - if (!count($items)) { - continue; - } - foreach ($items as $id) { - if (isset($old_list_ordered[$plugin_id][$id])) { - $old_item = $old_list_ordered[$plugin_id][$id]; + $permission = $section_plugin_definition['permission'] ?? ''; + foreach ($plugin->listSearchableTopics() as $topic_id) { + if (isset($old_list_ordered[$section_plugin_id][$topic_id])) { + $old_item = $old_list_ordered[$section_plugin_id][$topic_id]; if ($old_item->permission == $permission) { // Record has not changed. unset($sids_to_remove[$old_item->sid]); @@ -408,9 +405,9 @@ public function markForReindex() { // New record, create it. $this->database->insert('help_search_items') ->fields([ - 'plugin_type' => $plugin_id, + 'section_plugin_id' => $section_plugin_id, 'permission' => $permission, - 'id' => $id, + 'topic_id' => $topic_id, ]) ->execute(); } @@ -421,7 +418,7 @@ public function markForReindex() { // Mark all items currently in the search index database as needing // reindex. - search_mark_for_reindex($this->getPluginId()); + search_mark_for_reindex($this->getType()); $this->state->set('help_search_reindex_needed', FALSE); } @@ -440,7 +437,7 @@ public function indexStatus() { $query = $this->database->select('help_search_items', 'hsi'); $query->addExpression('COUNT(DISTINCT(hsi.sid))'); - $query->leftJoin('search_dataset', 'sd', 'hsi.sid = sd.sid AND sd.type = :type', [':type' => $this->getPluginId()]); + $query->leftJoin('search_dataset', 'sd', 'hsi.sid = sd.sid AND sd.type = :type', [':type' => $this->getType()]); $condition = new Condition('OR'); $condition->condition('sd.reindex', 0, '<>') ->isNull('sd.sid'); @@ -472,27 +469,24 @@ protected function removeItemsFromIndex($sids) { // Remove items from the search tables individually, as there is no bulk // function to delete items from the search index. foreach ($sids as $sid) { - search_index_clear($this->getPluginId(), $sid); + search_index_clear($this->getType(), $sid); } } /** * Instantiates a help section plugin and verifies it is searchable. * - * @param string $plugin_type + * @param string $section_plugin_id * Type of plugin to instantiate. * * @return \Drupal\help_topics\SearchableHelpInterface|false - * Plugin object, or FALSE if it is not a searchable type. + * Plugin object, or FALSE if it is not searchable. */ - protected function getSectionPlugin($plugin_type) { - /** @var \Drupal\help\HelpSectionPluginInterface $plugin */ - $plugin = $this->helpManager->createInstance($plugin_type); - if ($plugin && $plugin instanceof SearchableHelpInterface) { - return $plugin; - } + protected function getSectionPlugin($section_plugin_id) { + /** @var \Drupal\help\HelpSectionPluginInterface $section_plugin */ + $section_plugin = $this->helpSectionManager->createInstance($section_plugin_id); // Intentionally return boolean to allow caching of results. - return FALSE; + return $section_plugin instanceof SearchableHelpInterface ? $section_plugin : FALSE; } } diff --git a/core/modules/help_topics/src/SearchableHelpInterface.php b/core/modules/help_topics/src/SearchableHelpInterface.php index 1cac8dea49..06fdb939c1 100644 --- a/core/modules/help_topics/src/SearchableHelpInterface.php +++ b/core/modules/help_topics/src/SearchableHelpInterface.php @@ -21,14 +21,14 @@ interface SearchableHelpInterface { * * @return string[] * An array of topic IDs that should be searchable. IDs need to be - * unique within this HelpSection plugin type. + * unique within this HelpSection plugin. */ public function listSearchableTopics(); /** * Renders one topic for search indexing or search results. * - * @param string $id + * @param string $topic_id * The ID of the topic to be indexed. * @param \Drupal\Core\Language\LanguageInterface $language * The language to render the topic in. @@ -41,6 +41,6 @@ public function listSearchableTopics(); * - cacheable_metadata: (optional) An object to add as a cache dependency * if this topic is shown in search results. */ - public function renderTopicForSearch($id, LanguageInterface $language); + public function renderTopicForSearch($topic_id, LanguageInterface $language); } diff --git a/core/modules/help_topics/tests/modules/help_topics_test/src/Plugin/HelpSection/TestHelpSection.php b/core/modules/help_topics/tests/modules/help_topics_test/src/Plugin/HelpSection/TestHelpSection.php index 69d3f81c5d..7c3ccdd48d 100644 --- a/core/modules/help_topics/tests/modules/help_topics_test/src/Plugin/HelpSection/TestHelpSection.php +++ b/core/modules/help_topics/tests/modules/help_topics_test/src/Plugin/HelpSection/TestHelpSection.php @@ -41,8 +41,8 @@ public function listSearchableTopics() { /** * {@inheritdoc} */ - public function renderTopicForSearch($id, LanguageInterface $language) { - switch ($id) { + public function renderTopicForSearch($topic_id, LanguageInterface $language) { + switch ($topic_id) { case 'foo': if ($language->getId() == 'en') { return [ diff --git a/core/modules/help_topics/tests/src/Functional/HelpTopicSearchTest.php b/core/modules/help_topics/tests/src/Functional/HelpTopicSearchTest.php index 48cbb84765..40b81e1ee6 100644 --- a/core/modules/help_topics/tests/src/Functional/HelpTopicSearchTest.php +++ b/core/modules/help_topics/tests/src/Functional/HelpTopicSearchTest.php @@ -55,14 +55,12 @@ protected function setUp() { // Run cron until the topics are fully indexed, with a limit of 100 runs // to avoid infinite loops. - $num_runs = 0; - $indexed = FALSE; + $num_runs = 100; $plugin = HelpSearch::create($this->container, [], 'foo', []); - while (($num_runs < 100) && !$indexed) { + do { $this->cronRun(); $status = $plugin->indexStatus(); - $indexed = ($status['remaining'] == $status['total']); - } + } while (--$num_runs && $status['remaining'] != $status['total']); // Visit the Search settings page and verify it says 100% indexed. $this->drupalGet('admin/config/search/pages');