3 use Drush\Log\LogLevel;
6 * Implementation of hook_drush_help().
8 function search_drush_help($section) {
10 case 'meta:search:title':
11 return dt('Search commands');
12 case 'meta:search:summary':
13 return dt('Interact with Drupal\'s core search system.');
17 function search_drush_command() {
18 $items['search-status'] = array(
19 'description' => 'Show how many items remain to be indexed out of the total.',
20 'drupal dependencies' => array('search'),
21 'outputformat' => array(
22 'default' => 'message',
23 'pipe-format' => 'message',
24 'field-labels' => array('remaining' => 'Items not yet indexed', 'total' => 'Total items'),
25 'message-template' => 'There are !remaining items out of !total still to be indexed.',
26 'pipe-metadata' => array(
27 'message-template' => '!remaining/!total',
29 'output-data-type' => 'format-list',
32 $items['search-index'] = array(
33 'description' => 'Index the remaining search items without wiping the index.',
34 'drupal dependencies' => array('search'),
36 $items['search-reindex'] = array(
37 'description' => 'Force the search index to be rebuilt.',
38 'drupal dependencies' => array('search'),
40 'immediate' => 'Rebuild the index immediately, instead of waiting for cron.',
46 function drush_search_status() {
47 list($remaining, $total) = _drush_search_status();
49 'remaining' => $remaining,
54 function _drush_search_status() {
57 if (drush_drupal_major_version() >= 8) {
58 $search_page_repository = \Drupal::service('search.search_page_repository');
59 foreach ($search_page_repository->getIndexableSearchPages() as $entity) {
60 $status = $entity->getPlugin()->indexStatus();
61 $remaining += $status['remaining'];
62 $total += $status['total'];
65 elseif (drush_drupal_major_version() == 7) {
66 foreach (variable_get('search_active_modules', array('node', 'user')) as $module) {
67 drush_include_engine('drupal', 'environment');
68 $status = drush_module_invoke($module, 'search_status');
69 $remaining += $status['remaining'];
70 $total += $status['total'];
74 drush_include_engine('drupal', 'environment');
75 foreach (drush_module_implements('search') as $module) {
76 // Special case. Apachesolr recommends disabling core indexing with
77 // search_cron_limit = 0. Need to avoid infinite status loop.
78 if ($module == 'node' && variable_get('search_cron_limit', 10) == 0) {
81 $status = drush_module_invoke($module, 'search', 'status');
82 if (isset($status['remaining']) && isset($status['total'])) {
83 $remaining += $status['remaining'];
84 $total += $status['total'];
88 return array($remaining, $total);
91 function drush_search_index() {
92 drush_op('_drush_search_index');
93 drush_log(dt('The search index has been built.'), LogLevel::OK);
96 function _drush_search_index() {
97 list($remaining, $total) = _drush_search_status();
98 register_shutdown_function('search_update_totals');
100 while ($remaining > 0) {
101 $done = $total - $remaining;
102 $percent = $done / $total * 100;
103 drush_log(dt('!percent complete. Remaining items to be indexed: !count', array('!percent' => number_format($percent, 2), '!count' => $remaining)), LogLevel::OK);
104 $eval = "register_shutdown_function('search_update_totals');";
106 // Use drush_invoke_process() to start subshell. Avoids out of memory issue.
107 if (drush_drupal_major_version() >= 8) {
108 $eval = "drush_module_invoke('search', 'cron');";
110 elseif (drush_drupal_major_version() == 7) {
111 // If needed, prod drush_module_implements() to recognize our
112 // hook_node_update_index() implementations.
113 drush_include_engine('drupal', 'environment');
114 $implementations = drush_module_implements('node_update_index');
115 if (!in_array('system', $implementations)) {
116 // Note that this resets module_implements cache.
117 drush_module_implements('node_update_index', FALSE, TRUE);
120 foreach (variable_get('search_active_modules', array('node', 'user')) as $module) {
121 // TODO: Make sure that drush_module_invoke is really available when doing this eval().
122 $eval .= " drush_module_invoke('$module', 'update_index');";
126 // If needed, prod module_implements() to recognize our hook_nodeapi()
128 $implementations = module_implements('nodeapi');
129 if (!in_array('system', $implementations)) {
130 // Note that this resets module_implements cache.
131 module_implements('nodeapi', FALSE, TRUE);
134 $eval .= " module_invoke_all('update_index');";
136 drush_invoke_process('@self', 'php-eval', array($eval));
137 $previous_remaining = $remaining;
138 list($remaining, ) = _drush_search_status();
139 // Make sure we're actually making progress.
140 if ($remaining == $previous_remaining) {
142 if ($failures == 3) {
143 drush_log(dt('Indexing stalled with @number items remaining.', array(
144 '@number' => $remaining,
145 )), LogLevel::ERROR);
149 // Only count consecutive failures.
156 function drush_search_reindex() {
157 drush_print(dt("The search index must be fully rebuilt before any new items can be indexed."));
158 if (drush_get_option('immediate')) {
159 drush_print(dt("Rebuilding the index may take a long time."));
161 if (!drush_confirm(dt('Do you really want to continue?'))) {
162 return drush_user_abort();
165 if (drush_drupal_major_version() == 8) {
166 // D8 CR: https://www.drupal.org/node/2326575
167 $search_page_repository = \Drupal::service('search.search_page_repository');
168 foreach ($search_page_repository->getIndexableSearchPages() as $entity) {
169 $entity->getPlugin()->markForReindex();
172 elseif (drush_drupal_major_version() == 7) {
173 drush_op('search_reindex');
176 drush_op('search_wipe');
179 if (drush_get_option('immediate')) {
180 drush_op('_drush_search_index');
181 drush_log(dt('The search index has been rebuilt.'), LogLevel::OK);
184 drush_log(dt('The search index will be rebuilt.'), LogLevel::OK);
189 * Fake an implementation of hook_node_update_index() for Drupal 7.
191 function system_node_update_index($node) {
193 if (drush_get_context('DRUSH_VERBOSE')) {
195 if (is_object($nid)) {
196 // In D8, this is a FieldItemList.
200 drush_log(dt('Indexing node !nid.', array('!nid' => $nid)), LogLevel::OK);
205 * Fake an implementation of hook_nodeapi() for Drupal 6.
207 function system_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
208 if ($op == 'update index') {
210 if (drush_get_context('DRUSH_VERBOSE')) {
211 drush_log(dt('Indexing node !nid.', array('!nid' => $node->nid)), LogLevel::OK);