Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.
   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  namespace core_search\external;
  18  
  19  use core_external\external_api;
  20  use core_external\external_function_parameters;
  21  use core_external\external_single_structure;
  22  use core_external\external_multiple_structure;
  23  use core_external\external_value;
  24  use moodle_exception;
  25  
  26  /**
  27   * External function for retrieving search results.
  28   *
  29   * @package    core_search
  30   * @copyright  2023 David Monllao & Juan Leyva <juan@moodle.com>
  31   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  32   * @since      Moodle 4.3
  33   */
  34  class get_results extends external_api {
  35  
  36      /**
  37       * Webservice parameters.
  38       *
  39       * @return external_function_parameters
  40       */
  41      public static function execute_parameters(): external_function_parameters {
  42          return new external_function_parameters(
  43              [
  44                  'query' => new external_value(PARAM_NOTAGS, 'the search query'),
  45                  'filters' => new external_single_structure(
  46                      [
  47                          'title' => new external_value(PARAM_NOTAGS, 'result title', VALUE_OPTIONAL),
  48                          'areaids' => new external_multiple_structure(
  49                              new external_value(PARAM_ALPHANUMEXT, 'areaid'), 'restrict results to these areas', VALUE_DEFAULT, []
  50                          ),
  51                          'courseids' => new external_multiple_structure(
  52                              new external_value(PARAM_INT, 'courseid'), 'restrict results to these courses', VALUE_DEFAULT, []
  53                          ),
  54                          'contextids' => new external_multiple_structure(
  55                              new external_value(PARAM_INT, 'contextid'), 'restrict results to these contexts', VALUE_DEFAULT, []
  56                          ),
  57                          'cat' => new external_value(PARAM_NOTAGS, 'category to filter areas', VALUE_DEFAULT, ''),
  58                          'userids' => new external_multiple_structure(
  59                              new external_value(PARAM_INT, 'userid'), 'restrict results to these users', VALUE_DEFAULT, []
  60                          ),
  61                          'groupids' => new external_multiple_structure(
  62                              new external_value(PARAM_INT, 'groupid'), 'restrict results to these groups', VALUE_DEFAULT, []
  63                          ),
  64                          'mycoursesonly' => new external_value(PARAM_BOOL, 'only results from my courses', VALUE_DEFAULT, false),
  65                          'order' => new external_value(PARAM_ALPHA, 'how to order', VALUE_DEFAULT, ''),
  66                          'timestart' => new external_value(PARAM_INT, 'docs modified after this date', VALUE_DEFAULT, 0),
  67                          'timeend' => new external_value(PARAM_INT, 'docs modified before this date', VALUE_DEFAULT, 0)
  68                      ], 'filters to apply', VALUE_DEFAULT, []
  69                  ),
  70                  'page' => new external_value(PARAM_INT, 'results page number starting from 0, defaults to the first page',
  71                      VALUE_DEFAULT, 0)
  72              ]
  73          );
  74      }
  75  
  76      /**
  77       * Gets global search results based on the provided query and filters.
  78       *
  79       * @param string $query the search query
  80       * @param array $filters filters to apply
  81       * @param int $page results page
  82       * @return array search results
  83       */
  84      public static function execute(string $query, array $filters = [], int $page = 0): array {
  85          global $PAGE;
  86  
  87          $params = self::validate_parameters(self::execute_parameters(),
  88              [
  89                  'query' => $query,
  90                  'filters' => $filters,
  91                  'page' => $page,
  92              ]
  93          );
  94  
  95          $system = \context_system::instance();
  96          external_api::validate_context($system);
  97  
  98          require_capability('moodle/search:query', $system);
  99  
 100          if (\core_search\manager::is_global_search_enabled() === false) {
 101              throw new moodle_exception('globalsearchdisabled', 'search');
 102          }
 103  
 104          $search = \core_search\manager::instance();
 105  
 106          $data = new \stdClass();
 107          // First, mandatory parameters for consistency with web.
 108          $data->q = $params['query'];
 109          $data->title = $params['filters']['title'] ?? '';
 110          $data->timestart = $params['filters']['timestart'] ?? 0;
 111          $data->timeend = $params['filters']['timeend'] ?? 0;
 112          $data->areaids = $params['filters']['areaids'] ?? [];
 113          $data->courseids = $params['filters']['courseids'] ?? [];
 114          $data->contextids = $params['filters']['contextids'] ?? [];
 115          $data->userids = $params['filters']['userids'] ?? [];
 116          $data->groupids = $params['filters']['groupids'] ?? [];
 117  
 118          $cat = $params['filters']['cat'] ?? '';
 119          if (\core_search\manager::is_search_area_categories_enabled()) {
 120              $cat = \core_search\manager::get_search_area_category_by_name($cat);
 121          }
 122          if ($cat instanceof \core_search\area_category) {
 123              $data->cat = $cat->get_name();
 124          }
 125  
 126          $docs = $search->paged_search($data, $page);
 127  
 128          $return = [
 129              'totalcount' => $docs->totalcount,
 130              'warnings' => [],
 131              'results' => []
 132          ];
 133  
 134          // Convert results to simple data structures.
 135          if ($docs) {
 136              foreach ($docs->results as $doc) {
 137                  $return['results'][] = $doc->export_doc($PAGE->get_renderer('core'));
 138              }
 139          }
 140          return $return;
 141      }
 142  
 143      /**
 144       * Webservice returns.
 145       *
 146       * @return external_single_structure
 147       */
 148      public static function execute_returns(): external_single_structure {
 149          return new external_single_structure(
 150              [
 151                  'totalcount' => new external_value(PARAM_INT, 'Total number of results'),
 152                  'results' => new external_multiple_structure(
 153                      \core_search\external\document_exporter::get_read_structure()
 154                  ),
 155              ]
 156          );
 157      }
 158  }