[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/search/classes/ -> engine.php (source)

   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   * Base class for search engines.
  19   *
  20   * All search engines must extend this class.
  21   *
  22   * @package   core_search
  23   * @copyright 2015 Daniel Neis
  24   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  namespace core_search;
  28  
  29  defined('MOODLE_INTERNAL') || die();
  30  
  31  /**
  32   * Base class for search engines.
  33   *
  34   * All search engines must extend this class.
  35   *
  36   * @package   core_search
  37   * @copyright 2015 Daniel Neis
  38   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   */
  40  abstract class engine {
  41  
  42      /**
  43       * The search engine configuration.
  44       *
  45       * @var stdClass
  46       */
  47      protected $config = null;
  48  
  49      /**
  50       * Last executed query error, if there was any.
  51       * @var string
  52       */
  53      protected $queryerror = null;
  54  
  55      /**
  56       * @var array Internal cache.
  57       */
  58      protected $cachedareas = array();
  59  
  60      /**
  61       * @var array Internal cache.
  62       */
  63      protected $cachedcourses = array();
  64  
  65      /**
  66       * User data required to show their fullnames. Indexed by userid.
  67       *
  68       * @var stdClass[]
  69       */
  70      protected static $cachedusers = array();
  71  
  72      /**
  73       * @var string Frankenstyle plugin name.
  74       */
  75      protected $pluginname = null;
  76  
  77      /**
  78       * Initialises the search engine configuration.
  79       *
  80       * Search engine availability should be checked separately.
  81       *
  82       * @return void
  83       */
  84      public function __construct() {
  85  
  86          $classname = get_class($this);
  87          if (strpos($classname, '\\') === false) {
  88              throw new \coding_exception('"' . $classname . '" class should specify its component namespace and it should be named engine.');
  89          } else if (strpos($classname, '_') === false) {
  90              throw new \coding_exception('"' . $classname . '" class namespace should be its frankenstyle name');
  91          }
  92  
  93          // This is search_xxxx config.
  94          $this->pluginname = substr($classname, 0, strpos($classname, '\\'));
  95          if ($config = get_config($this->pluginname)) {
  96              $this->config = $config;
  97          } else {
  98              $this->config = new stdClass();
  99          }
 100      }
 101  
 102      /**
 103       * Returns a course instance checking internal caching.
 104       *
 105       * @param int $courseid
 106       * @return stdClass
 107       */
 108      protected function get_course($courseid) {
 109          if (!empty($this->cachedcourses[$courseid])) {
 110              return $this->cachedcourses[$courseid];
 111          }
 112  
 113          // No need to clone, only read.
 114          $this->cachedcourses[$courseid] = get_course($courseid, false);
 115  
 116          return $this->cachedcourses[$courseid];
 117      }
 118  
 119      /**
 120       * Returns user data checking the internal static cache.
 121       *
 122       * Including here the minimum required user information as this may grow big.
 123       *
 124       * @param int $userid
 125       * @return stdClass
 126       */
 127      public function get_user($userid) {
 128          global $DB;
 129  
 130          if (empty(self::$cachedusers[$userid])) {
 131              $fields = get_all_user_name_fields(true);
 132              self::$cachedusers[$userid] = $DB->get_record('user', array('id' => $userid), 'id, ' . $fields);
 133          }
 134          return self::$cachedusers[$userid];
 135      }
 136  
 137      /**
 138       * Returns a search instance of the specified area checking internal caching.
 139       *
 140       * @param string $areaid Area id
 141       * @return \core_search\base
 142       */
 143      protected function get_search_area($areaid) {
 144  
 145          if (isset($this->cachedareas[$areaid]) && $this->cachedareas[$areaid] === false) {
 146              // We already checked that area and it is not available.
 147              return false;
 148          }
 149  
 150          if (!isset($this->cachedareas[$areaid])) {
 151              // First result that matches this area.
 152  
 153              $this->cachedareas[$areaid] = \core_search\manager::get_search_area($areaid);
 154              if ($this->cachedareas[$areaid] === false) {
 155                  // The area does not exist or it is not available any more.
 156  
 157                  $this->cachedareas[$areaid] = false;
 158                  return false;
 159              }
 160  
 161              if (!$this->cachedareas[$areaid]->is_enabled()) {
 162                  // We skip the area if it is not enabled.
 163  
 164                  // Marking it as false so next time we don' need to check it again.
 165                  $this->cachedareas[$areaid] = false;
 166  
 167                  return false;
 168              }
 169          }
 170  
 171          return $this->cachedareas[$areaid];
 172      }
 173  
 174      /**
 175       * Returns a document instance prepared to be rendered.
 176       *
 177       * @param \core_search\base $searcharea
 178       * @param array $docdata
 179       * @return \core_search\document
 180       */
 181      protected function to_document(\core_search\base $searcharea, $docdata) {
 182  
 183          list($componentname, $areaname) = \core_search\manager::extract_areaid_parts($docdata['areaid']);
 184          $doc = \core_search\document_factory::instance($docdata['itemid'], $componentname, $areaname, $this);
 185          $doc->set_data_from_engine($docdata);
 186          $doc->set_doc_url($searcharea->get_doc_url($doc));
 187          $doc->set_context_url($searcharea->get_context_url($doc));
 188  
 189          // Uses the internal caches to get required data needed to render the document later.
 190          $course = $this->get_course($doc->get('courseid'));
 191          $doc->set_extra('coursefullname', $course->fullname);
 192  
 193          if ($doc->is_set('userid')) {
 194              $user = $this->get_user($doc->get('userid'));
 195              $doc->set_extra('userfullname', fullname($user));
 196          }
 197  
 198          return $doc;
 199      }
 200  
 201      /**
 202       * Returns the plugin name.
 203       *
 204       * @return string Frankenstyle plugin name.
 205       */
 206      public function get_plugin_name() {
 207          return $this->pluginname;
 208      }
 209  
 210      /**
 211       * Gets the document class used by this search engine.
 212       *
 213       * Search engines can overwrite \core_search\document with \search_ENGINENAME\document class.
 214       *
 215       * Looks for a document class in the current search engine namespace, falling back to \core_search\document.
 216  
 217       * Publicly available because search areas do not have access to the engine details,
 218       * \core_search\document_factory accesses this function.
 219       *
 220       * @return string
 221       */
 222      public function get_document_classname() {
 223          $classname = $this->pluginname . '\\document';
 224          if (!class_exists($classname)) {
 225              $classname = '\\core_search\\document';
 226          }
 227          return $classname;
 228      }
 229  
 230      /**
 231       * Run any pre-indexing operations.
 232       *
 233       * Should be overwritten if the search engine needs to do any pre index preparation.
 234       *
 235       * @param bool $fullindex True if a full index will be performed
 236       * @return void
 237       */
 238      public function index_starting($fullindex = false) {
 239          // Nothing by default.
 240      }
 241  
 242      /**
 243       * Run any post indexing operations.
 244       *
 245       * Should be overwritten if the search engine needs to do any post index cleanup.
 246       *
 247       * @param int $numdocs The number of documents that were added to the index
 248       * @param bool $fullindex True if a full index was performed
 249       * @return void
 250       */
 251      public function index_complete($numdocs = 0, $fullindex = false) {
 252          // Nothing by default.
 253      }
 254  
 255      /**
 256       * Do anything that may need to be done before an area is indexed.
 257       *
 258       * @param \core_search\base $searcharea The search area that was complete
 259       * @param bool $fullindex True if a full index is being performed
 260       * @return void
 261       */
 262      public function area_index_starting($searcharea, $fullindex = false) {
 263          // Nothing by default.
 264      }
 265  
 266      /**
 267       * Do any area cleanup needed, and do anything to confirm contents.
 268       *
 269       * Return false to prevent the search area completed time and stats from being updated.
 270       *
 271       * @param \core_search\base $searcharea The search area that was complete
 272       * @param int $numdocs The number of documents that were added to the index
 273       * @param bool $fullindex True if a full index is being performed
 274       * @return bool True means that data is considered indexed
 275       */
 276      public function area_index_complete($searcharea, $numdocs = 0, $fullindex = false) {
 277          return true;
 278      }
 279  
 280      /**
 281       * Optimizes the search engine.
 282       *
 283       * Should be overwritten if the search engine can optimize its contents.
 284       *
 285       * @return void
 286       */
 287      public function optimize() {
 288          // Nothing by default.
 289      }
 290  
 291      /**
 292       * Does the system satisfy all the requirements.
 293       *
 294       * Should be overwritten if the search engine has any system dependencies
 295       * that needs to be checked.
 296       *
 297       * @return bool
 298       */
 299      public function is_installed() {
 300          return true;
 301      }
 302  
 303      /**
 304       * Returns any error reported by the search engine when executing the provided query.
 305       *
 306       * It should be called from static::execute_query when an exception is triggered.
 307       *
 308       * @return string
 309       */
 310      public function get_query_error() {
 311          return $this->queryerror;
 312      }
 313  
 314      /**
 315       * Returns the total number of documents available for the most recent call to execute_query.
 316       *
 317       * This can be an estimate, but should get more accurate the higher the limited passed to execute_query is.
 318       * To do that, the engine can use (actual result returned count + count of unchecked documents), or
 319       * (total possible docs - docs that have been checked and rejected).
 320       *
 321       * Engine can limit to manager::MAX_RESULTS if there is cost to determining more.
 322       * If this cannot be computed in a reasonable way, manager::MAX_RESULTS may be returned.
 323       *
 324       * @return int
 325       */
 326      abstract public function get_query_total_count();
 327  
 328      /**
 329       * Return true if file indexing is supported and enabled. False otherwise.
 330       *
 331       * @return bool
 332       */
 333      public function file_indexing_enabled() {
 334          return false;
 335      }
 336  
 337      /**
 338       * Clears the current query error value.
 339       *
 340       * @return void
 341       */
 342      public function clear_query_error() {
 343          $this->queryerror = null;
 344      }
 345  
 346      /**
 347       * Is the server ready to use?
 348       *
 349       * This should also check that the search engine configuration is ok.
 350       *
 351       * @return true|string Returns true if all good or an error string.
 352       */
 353      abstract function is_server_ready();
 354  
 355      /**
 356       * Adds a document to the search engine.
 357       *
 358       * @param document $document
 359       * @param bool     $fileindexing True if file indexing is to be used
 360       * @return bool    False if the file was skipped or failed, true on success
 361       */
 362      abstract function add_document($document, $fileindexing = false);
 363  
 364      /**
 365       * Executes the query on the engine.
 366       *
 367       * Implementations of this function should check user context array to limit the results to contexts where the
 368       * user have access. They should also limit the owneruserid field to manger::NO_OWNER_ID or the current user's id.
 369       * Engines must use area->check_access() to confirm user access.
 370       *
 371       * Engines should reasonably attempt to fill up to limit with valid results if they are available.
 372       *
 373       * @param  stdClass $filters Query and filters to apply.
 374       * @param  array    $usercontexts Contexts where the user has access. True if the user can access all contexts.
 375       * @param  int      $limit The maximum number of results to return. If empty, limit to manager::MAX_RESULTS.
 376       * @return \core_search\document[] Results or false if no results
 377       */
 378      abstract function execute_query($filters, $usercontexts, $limit = 0);
 379  
 380      /**
 381       * Delete all documents.
 382       *
 383       * @param string $areaid To filter by area
 384       * @return void
 385       */
 386      abstract function delete($areaid = null);
 387  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1