diff --git a/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php index b7ad7c6..5f4bbc8 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php +++ b/core/modules/node/lib/Drupal/node/Plugin/Search/NodeSearch.php @@ -10,6 +10,7 @@ use Drupal\Core\Config\Config; use Drupal\Core\Database\Connection; use Drupal\Core\Database\Query\SelectExtender; +use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManager; use Drupal\Core\Extension\ModuleHandlerInterface; @@ -71,26 +72,25 @@ public function execute() { } $keys = $this->keywords; // Build matching conditions - $query = $this->database - ->select('search_index', 'i', array('target' => 'slave')) - ->extend('Drupal\search\SearchQuery') - ->extend('Drupal\Core\Database\Query\PagerSelectExtender'); - $query->join('node', 'n', 'n.nid = i.sid'); - $query - ->condition('n.status', 1) - ->addTag('node_access') - ->searchExpression($keys, 'node'); - - // Insert special keywords. - $query->setOption('type', 'n.type'); - $query->setOption('langcode', 'n.langcode'); - if ($query->setOption('term', 'ti.tid')) { - $query->join('taxonomy_index', 'ti', 'n.nid = ti.nid'); - } - // Only continue if the first pass query matches. - if (!$query->executeFirstPass()) { - return array(); - } + $query = $this->database + ->select('search_index', 'i', array('target' => 'slave')) + ->extend('Drupal\search\SearchQuery') + ->extend('Drupal\Core\Database\Query\PagerSelectExtender'); + $query->join('node_field_data', 'n', 'n.nid = i.sid'); + $query->condition('n.status', 1) + ->addTag('node_access') + ->searchExpression($keys, 'node'); + + // Insert special keywords. + $query->setOption('type', 'n.type'); + $query->setOption('langcode', 'n.langcode'); + if ($query->setOption('term', 'ti.tid')) { + $query->join('taxonomy_index', 'ti', 'n.nid = ti.nid'); + } + // Only continue if the first pass query matches. + if (!$query->executeFirstPass()) { + return array(); + } // Add the ranking expressions. $this->addNodeRankings($query); @@ -108,7 +108,7 @@ public function execute() { foreach ($find as $item) { // Render the node. - $entities = $node_storage->load(array($item->sid)); + $entities = $node_storage->loadMultiple(array($item->sid)); $node = $entities[$item->sid]; $build = $node_render->view($node, 'search_result', $item->langcode); unset($build['#theme']); @@ -121,17 +121,21 @@ public function execute() { $language = $this->moduleHandler->invoke('language', 'load', array($item->langcode)); $uri = $node->uri(); + $username = array( + '#theme' => 'username', + '#account' => $node, + ); $results[] = array( 'link' => url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE, 'language' => $language))), - 'type' => check_plain($this->moduleHandler->invoke('node', 'get_type_label', array($node))), + 'type' => check_plain(node_get_type_label($node)), 'title' => $node->label($item->langcode), - 'user' => theme('username', array('account' => $node)), - 'date' => $node->changed, + 'user' => drupal_render($username), + 'date' => $node->getChangedTime(), 'node' => $node, 'extra' => $extra, 'score' => $item->calculated_score, 'snippet' => search_excerpt($keys, $node->rendered, $item->langcode), - 'langcode' => $node->langcode, + 'langcode' => $node->language()->id, ); } return $results; @@ -159,6 +163,7 @@ protected function addNodeRankings(SelectExtender $query) { } } } + /** * {@inheritdoc} */ @@ -175,7 +180,7 @@ public function updateIndex() { // of a node. $counter = 0; $node_storage = $this->entityManager->getStorageController('node'); - foreach ($node_storage->load($nids) as $node) { + foreach ($node_storage->loadMultiple($nids) as $node) { // Determine when the maximum number of indexable items is reached. $counter += count($node->getTranslationLanguages()); if ($counter > $limit) { @@ -195,27 +200,27 @@ protected function indexNode(EntityInterface $node) { // Save the changed time of the most recent indexed node, for the search // results half-life calculation. - $this->state->set('node.cron_last', $node->changed); + $this->state->set('node.cron_last', $node->getChangedTime()); $languages = $node->getTranslationLanguages(); foreach ($languages as $language) { // Render the node. - $build = $this->moduleHandler->invoke('node', 'view', array($node, 'search_index', $language->langcode)); + $build = $this->moduleHandler->invoke('node', 'view', array($node, 'search_index', $language->id)); unset($build['#theme']); $node->rendered = drupal_render($build); - $text = '

' . check_plain($node->label($language->langcode)) . '

' . $node->rendered; + $text = '

' . check_plain($node->label($language->id)) . '

' . $node->rendered; // Fetch extra data normally not visible. - $extra = $this->moduleHandler->invokeAll('node_update_index', array($node, $language->langcode)); + $extra = $this->moduleHandler->invokeAll('node_update_index', array($node, $language->id)); foreach ($extra as $t) { $text .= $t; } // Update index. - $this->moduleHandler->invoke('search', 'index', array($node->nid, 'node', $text, $language->langcode)); + $this->moduleHandler->invoke('search', 'index', array($node->nid, 'node', $text, $language->id)); } } diff --git a/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php b/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php index 0fd7e1b..02131d7 100644 --- a/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php +++ b/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php @@ -11,6 +11,8 @@ use Drupal\Core\Extension\ModuleHandler; use Drupal\Core\KeyValueStore\KeyValueStoreInterface; use Drupal\Component\Utility\NestedArray; +use Drupal\search\SearchPluginManager; + use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -25,6 +27,13 @@ class SearchSettingsForm extends SystemConfigFormBase { protected $searchSettings; /** + * A search plugin manager object. + * + * @var \Drupal\search\SearchPluginManager + */ + protected $searchPluginManager; + + /** * The module handler. * * @var \Drupal\Core\Extension\ModuleHandler @@ -43,11 +52,14 @@ class SearchSettingsForm extends SystemConfigFormBase { * * @param \Drupal\Core\Config\Config $search_settings * The configuration object that manages search settings. + * @param \Drupal\search\SearchPluginManager $manager + * The manager for search plugins. * @param \Drupal\Core\Extension\ModuleHandler $module_handler * The module handler */ - public function __construct(Config $search_settings, ModuleHandler $module_handler, KeyValueStoreInterface $state) { + public function __construct(Config $search_settings, SearchPluginManager $manager, ModuleHandler $module_handler, KeyValueStoreInterface $state) { $this->searchSettings = $search_settings; + $this->searchPluginManager = $manager; $this->moduleHandler = $module_handler; $this->state = $state; } @@ -58,6 +70,7 @@ public function __construct(Config $search_settings, ModuleHandler $module_handl public static function create(ContainerInterface $container) { return new static( $container->get('config.factory')->get('search.settings'), + $container->get('plugin.manager.search'), $container->get('module_handler'), $container->get('keyvalue')->get('state') ); @@ -92,8 +105,11 @@ public function buildForm(array $form, array &$form_state) { // Collect some stats $remaining = 0; $total = 0; - foreach ($this->searchSettings->get('active_modules') as $module) { - if ($status = $this->moduleHandler->invoke($module, 'search_status')) { + $active_plugins = array(); + // @todo: make search_get_info() just a wrapper on a plugin manager method. + foreach(search_get_info() as $module => $search_info) { + $active_plugins[$module] = $this->searchPluginManager->createInstance($search_info['id']); + if ($status = $active_plugins[$module]->indexStatus()) { $remaining += $status['remaining']; $total += $status['total']; } @@ -172,12 +188,9 @@ public function buildForm(array $form, array &$form_state) { '#description' => t('Choose which search module is the default.') ); - // Per module settings - foreach ($this->searchSettings->get('active_modules') as $module) { - $added_form = $this->moduleHandler->invoke($module, 'search_admin'); - if (is_array($added_form)) { - $form = NestedArray::mergeDeep($form, $added_form); - } + // Per module plugin settings + foreach($active_plugins as $plugin) { + $plugin->addToAdminForm($form, $form_state); } // Set #submit so we are sure it's invoked even if one of // the active search modules added its own #submit. @@ -217,7 +230,11 @@ public function submitForm(array &$form, array &$form_state) { } $this->searchSettings->set('index.cron_limit', $form_state['values']['cron_limit']); $this->searchSettings->set('default_module', $form_state['values']['default_module']); - + // Handle per-plugin submission logic. + foreach(search_get_info() as $module => $search_info) { + $plugin = $this->searchPluginManager->createInstance($search_info['id']); + $plugin->submitAdminForm($form, $form_state); + } // Check whether we are resetting the values. if ($form_state['triggering_element']['#value'] == t('Reset to defaults')) { $new_modules = array('node', 'user'); diff --git a/core/modules/search/lib/Drupal/search/Plugin/SearchInterface.php b/core/modules/search/lib/Drupal/search/Plugin/SearchInterface.php index 6a6fb2a..8d75604 100644 --- a/core/modules/search/lib/Drupal/search/Plugin/SearchInterface.php +++ b/core/modules/search/lib/Drupal/search/Plugin/SearchInterface.php @@ -112,7 +112,7 @@ public function indexStatus(); /** * Add elements to the search settings form. - * + * * The core search module only invokes this method on active module plugins. * * @param $form @@ -126,7 +126,7 @@ public function addToAdminForm(array &$form, array &$form_state); /** * Handle any submission for elements on the search settings form. - * + * * The core search module only invokes this method on active module plugins. * * @param $form diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php index df9769a..a272442 100644 --- a/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php +++ b/core/modules/search/lib/Drupal/search/Tests/SearchMultilingualEntityTest.php @@ -95,7 +95,8 @@ function testIndexingThrottle() { // Index only 4 items per cron run. config('search.settings')->set('index.cron_limit', 4)->save(); // Update the index. This does the initial processing. - $this->container->get('plugin.manager.search')->createInstance('node_search')->updateIndex(); + $plugin = $this->container->get('plugin.manager.search')->createInstance('node_search'); + $plugin->updateIndex(); // Run the shutdown function. Testing is a unique case where indexing // and searching has to happen in the same request, so running the shutdown // function manually is needed to finish the indexing process. @@ -104,7 +105,7 @@ function testIndexingThrottle() { // the first has one, the second has two and the third has three language // variants. Indexing the third would exceed the throttle limit, so we // expect that only the first two will be indexed. - $status = module_invoke('node', 'search_status'); + $status = $plugin->indexStatus(); $this->assertEqual($status['remaining'], 1, 'Remaining items after updating the search index is 1.'); } diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchNodeAccessTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchNodeAccessTest.php index 3d4b49e..8f067f6 100644 --- a/core/modules/search/lib/Drupal/search/Tests/SearchNodeAccessTest.php +++ b/core/modules/search/lib/Drupal/search/Tests/SearchNodeAccessTest.php @@ -45,7 +45,7 @@ function testPhraseSearchPunctuation() { $node = $this->drupalCreateNode(array('body' => array(array('value' => "The bunny's ears were fluffy.")))); // Update the search index. - $this->container->get('plugin.manager.search')->createInstance('node_search'); + $this->container->get('plugin.manager.search')->createInstance('node_search')->updateIndex(); search_update_totals(); // Refresh variables after the treatment. diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchRankingTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchRankingTest.php index e146363..cafad8d 100644 --- a/core/modules/search/lib/Drupal/search/Tests/SearchRankingTest.php +++ b/core/modules/search/lib/Drupal/search/Tests/SearchRankingTest.php @@ -90,8 +90,6 @@ function testRankings() { for ($i = 0; $i < 5; $i ++) { $client->post($stats_path, array(), array('nid' => $nid))->send(); } - $plugin = $this->container->get('plugin.manager.search')->createInstance('node_search'); - $plugin->setSearch('rocks', array(), array()); // Test each of the possible rankings. foreach ($node_ranks as $node_rank) { // Disable all relevancy rankings except the one we are testing. @@ -99,6 +97,8 @@ function testRankings() { variable_set('node_rank_' . $var, $var == $node_rank ? 10 : 0); } // Do the search and assert the results. + $plugin = $this->container->get('plugin.manager.search')->createInstance('node_search'); + $plugin->setSearch('rocks', array(), array()); $set = $plugin->execute(); $this->assertEqual($set[0]['node']->nid, $nodes[$node_rank][1]->nid, 'Search ranking "' . $node_rank . '" order.'); } diff --git a/core/modules/user/lib/Drupal/user/Plugin/Search/UserSearch.php b/core/modules/user/lib/Drupal/user/Plugin/Search/UserSearch.php index 96c5cb6..689fcc1 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Search/UserSearch.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Search/UserSearch.php @@ -86,7 +86,7 @@ public function execute() { ->limit(15) ->execute() ->fetchCol(); - $accounts = $this->entityManager->getStorageController('user')->load($uids); + $accounts = $this->entityManager->getStorageController('user')->loadMultiple($uids); foreach ($accounts as $account_ng) { $account = $account_ng->getBCEntity();