Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 and 402] [Versions 401 and 403]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Manage global search areas.
  19   *
  20   * @package   core_search
  21   * @copyright 2016 Dan Poltawski <dan@moodle.com>
  22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  require_once(__DIR__ . '/../config.php');
  25  require_once($CFG->libdir . '/adminlib.php');
  26  
  27  admin_externalpage_setup('searchareas');
  28  
  29  $areaid = optional_param('areaid', null, PARAM_ALPHANUMEXT);
  30  $action = optional_param('action', null, PARAM_ALPHA);
  31  $indexingenabled = \core_search\manager::is_indexing_enabled(); // This restricts many of the actions on this page.
  32  
  33  // Get a search manager instance, which we'll need for display and to handle some actions.
  34  try {
  35      $searchmanager = \core_search\manager::instance();
  36  } catch (core_search\engine_exception $searchmanagererror) {
  37      // In action cases, we'll throw this exception below. In non-action cases, we produce a lang string error.
  38  }
  39  
  40  $PAGE->set_primary_active_tab('siteadminnode');
  41  
  42  // Handle all the actions.
  43  if ($action) {
  44      // If dealing with an areaid, we need to check that the area exists.
  45      if ($areaid) {
  46          $area = \core_search\manager::get_search_area($areaid);
  47          if ($area === false) {
  48              throw new moodle_exception('invalidrequest');
  49          }
  50      }
  51  
  52      // All the indexing actions.
  53      if (in_array($action, ['delete', 'indexall', 'reindexall', 'deleteall'])) {
  54  
  55          // All of these actions require that indexing is enabled.
  56          if ($indexingenabled) {
  57  
  58              // For all of these actions, we strictly need a manager instance.
  59              if (isset($searchmanagererror)) {
  60                  throw $searchmanagererror;
  61              }
  62  
  63              // Show confirm prompt for all these actions as they may be inadvisable, or may cause
  64              // an interruption in search functionality, on production systems.
  65              if (!optional_param('confirm', 0, PARAM_INT)) {
  66                  // Display confirmation prompt.
  67                  $a = null;
  68                  if ($areaid) {
  69                      $a = html_writer::tag('strong', $area->get_visible_name());
  70                  }
  71  
  72                  $actionparams = ['sesskey' => sesskey(), 'action' => $action, 'confirm' => 1];
  73                  if ($areaid) {
  74                      $actionparams['areaid'] = $areaid;
  75                  }
  76                  $actionurl = new moodle_url('/admin/searchareas.php', $actionparams);
  77                  $cancelurl = new moodle_url('/admin/searchareas.php');
  78                  echo $OUTPUT->header();
  79                  echo $OUTPUT->confirm(get_string('confirm_' . $action, 'search', $a),
  80                      new single_button($actionurl, get_string('continue'), 'post', true),
  81                      new single_button($cancelurl, get_string('cancel'), 'get'));
  82                  echo $OUTPUT->footer();
  83                  exit;
  84              } else {
  85                  // Confirmed, so run the required action.
  86                  require_sesskey();
  87  
  88                  switch ($action) {
  89                      case 'delete':
  90                          $searchmanager->delete_index($areaid);
  91                          \core\notification::success(get_string('searchindexdeleted', 'admin'));
  92                          break;
  93                      case 'indexall':
  94                          $searchmanager->index();
  95                          \core\notification::success(get_string('searchindexupdated', 'admin'));
  96                          break;
  97                      case 'reindexall':
  98                          $searchmanager->index(true);
  99                          \core\notification::success(get_string('searchreindexed', 'admin'));
 100                          break;
 101                      case 'deleteall':
 102                          $searchmanager->delete_index();
 103                          \core\notification::success(get_string('searchalldeleted', 'admin'));
 104                          break;
 105                      default:
 106                          break;
 107                  }
 108  
 109                  // Redirect back to the main page after taking action.
 110                  redirect(new moodle_url('/admin/searchareas.php'));
 111              }
 112          }
 113      } else if (in_array($action, ['enable', 'disable'])) {
 114          // Toggling search areas requires no confirmation.
 115          require_sesskey();
 116  
 117          switch ($action) {
 118              case 'enable':
 119                  $area->set_enabled(true);
 120                  \core\notification::success(get_string('searchareaenabled', 'admin'));
 121                  break;
 122              case 'disable':
 123                  $area->set_enabled(false);
 124                  core\notification::success(get_string('searchareadisabled', 'admin'));
 125                  break;
 126              default:
 127                  break;
 128          }
 129  
 130          redirect(new moodle_url('/admin/searchareas.php'));
 131      } else {
 132          // Invalid action.
 133          throw new moodle_exception('invalidaction');
 134      }
 135  }
 136  
 137  
 138  // Display.
 139  if (isset($searchmanager) && $indexingenabled) {
 140      \core\notification::info(get_string('indexinginfo', 'admin'));
 141  } else if (isset($searchmanager)) {
 142      $params = (object) [
 143          'url' => (new moodle_url("/admin/settings.php?section=manageglobalsearch#admin-searchindexwhendisabled"))->out(false)
 144      ];
 145      \core\notification::error(get_string('indexwhendisabledfullnotice', 'search', $params));
 146  } else {
 147      // In non-action cases, init errors are translated and displayed to the user as error notifications.
 148      $errorstr = get_string($searchmanagererror->errorcode, $searchmanagererror->module, $searchmanagererror->a);
 149      \core\notification::error($errorstr);
 150  }
 151  
 152  echo $OUTPUT->header();
 153  
 154  $table = new html_table();
 155  $table->id = 'core-search-areas';
 156  $table->head = [
 157      get_string('searcharea', 'search'),
 158      get_string('searchareacategories', 'search'),
 159      get_string('enable'),
 160      get_string('newestdocindexed', 'admin'),
 161      get_string('searchlastrun', 'admin'),
 162      get_string('searchindexactions', 'admin')
 163  ];
 164  
 165  $searchareas = \core_search\manager::get_search_areas_list();
 166  core_collator::asort_objects_by_method($searchareas, 'get_visible_name');
 167  $areasconfig = isset($searchmanager) ? $searchmanager->get_areas_config($searchareas) : false;
 168  foreach ($searchareas as $area) {
 169      $areaid = $area->get_area_id();
 170      $columns = array(new html_table_cell($area->get_visible_name()));
 171  
 172      $areacategories = [];
 173      foreach (\core_search\manager::get_search_area_categories() as $category) {
 174          if (key_exists($areaid, $category->get_areas())) {
 175              $areacategories[] = $category->get_visiblename();
 176          }
 177      }
 178      $columns[] = new html_table_cell(implode(', ', $areacategories));
 179  
 180      if ($area->is_enabled()) {
 181          $columns[] = $OUTPUT->action_icon(admin_searcharea_action_url('disable', $areaid),
 182              new pix_icon('t/hide', get_string('disable'), 'moodle', array('title' => '', 'class' => 'iconsmall')),
 183              null, array('title' => get_string('disable')));
 184  
 185          if ($areasconfig && $indexingenabled) {
 186              $columns[] = $areasconfig[$areaid]->lastindexrun;
 187  
 188              if ($areasconfig[$areaid]->indexingstart) {
 189                  $timediff = $areasconfig[$areaid]->indexingend - $areasconfig[$areaid]->indexingstart;
 190                  $laststatus = $timediff . ' , ' .
 191                      $areasconfig[$areaid]->docsprocessed . ' , ' .
 192                      $areasconfig[$areaid]->recordsprocessed . ' , ' .
 193                      $areasconfig[$areaid]->docsignored;
 194                  if ($areasconfig[$areaid]->partial) {
 195                      $laststatus .= ' ' . get_string('searchpartial', 'admin');
 196                  }
 197              } else {
 198                  $laststatus = '';
 199              }
 200              $columns[] = $laststatus;
 201              $accesshide = html_writer::span($area->get_visible_name(), 'accesshide');
 202              $actions = [];
 203              $actions[] = $OUTPUT->pix_icon('t/delete', '') .
 204                      html_writer::link(admin_searcharea_action_url('delete', $areaid),
 205                      get_string('deleteindex', 'search', $accesshide));
 206              if ($area->supports_get_document_recordset()) {
 207                  $actions[] = $OUTPUT->pix_icon('i/reload', '') . html_writer::link(
 208                          new moodle_url('searchreindex.php', ['areaid' => $areaid]),
 209                          get_string('gradualreindex', 'search', $accesshide));
 210              }
 211              $columns[] = html_writer::alist($actions, ['class' => 'unstyled list-unstyled']);
 212  
 213          } else {
 214              if (!$areasconfig) {
 215                  $blankrow = new html_table_cell(get_string('searchnotavailable', 'admin'));
 216              } else {
 217                  $blankrow = new html_table_cell(get_string('indexwhendisabledshortnotice', 'search'));
 218              }
 219              $blankrow->colspan = 3;
 220              $columns[] = $blankrow;
 221          }
 222  
 223      } else {
 224          $columns[] = $OUTPUT->action_icon(admin_searcharea_action_url('enable', $areaid),
 225              new pix_icon('t/show', get_string('enable'), 'moodle', array('title' => '', 'class' => 'iconsmall')),
 226                  null, array('title' => get_string('enable')));
 227  
 228          $blankrow = new html_table_cell(get_string('searchareadisabled', 'admin'));
 229          $blankrow->colspan = 3;
 230          $columns[] = $blankrow;
 231      }
 232      $row = new html_table_row($columns);
 233      $table->data[] = $row;
 234  }
 235  
 236  // Cross-search area tasks.
 237  $options = (isset($searchmanager) && $indexingenabled) ? [] : ['disabled' => true];
 238  echo $OUTPUT->box_start('search-areas-actions');
 239  echo $OUTPUT->single_button(admin_searcharea_action_url('indexall'), get_string('searchupdateindex', 'admin'), 'get', $options);
 240  echo $OUTPUT->single_button(admin_searcharea_action_url('reindexall'), get_string('searchreindexindex', 'admin'), 'get', $options);
 241  echo $OUTPUT->single_button(admin_searcharea_action_url('deleteall'), get_string('searchdeleteindex', 'admin'), 'get', $options);
 242  echo $OUTPUT->box_end();
 243  
 244  echo html_writer::table($table);
 245  
 246  if (isset($searchmanager)) {
 247      // Show information about queued index requests for specific contexts.
 248      $searchrenderer = $PAGE->get_renderer('core_search');
 249      echo $searchrenderer->render_index_requests_info($searchmanager->get_index_requests_info());
 250  }
 251  
 252  echo $OUTPUT->footer();
 253  
 254  /**
 255   * Helper for generating url for management actions.
 256   *
 257   * @param string $action
 258   * @param string $areaid
 259   * @return moodle_url
 260   */
 261  function admin_searcharea_action_url($action, $areaid = false) {
 262      $params = array('action' => $action);
 263      if ($areaid) {
 264          $params['areaid'] = $areaid;
 265      }
 266      if ($action === 'disable' || $action === 'enable') {
 267          $params['sesskey'] = sesskey();
 268      }
 269      return new moodle_url('/admin/searchareas.php', $params);
 270  }