Beispiel #1
0
 /**
  * Checks the schema is properly set up.
  *
  * @throws \moodle_exception
  * @return void
  */
 public function validate_setup()
 {
     $fields = \search_solr\document::get_default_fields_definition();
     // Field id is already there.
     unset($fields['id']);
     $this->check_index();
     $this->validate_fields($fields, true);
 }
Beispiel #2
0
 /**
  * Prepares a new query object with needed limits, filters, etc.
  *
  * @param stdClass  $filters Containing query and filters.
  * @param array     $usercontexts Contexts where the user has access. True if the user can access all contexts.
  * @return SolrDisMaxQuery
  */
 protected function create_user_query($filters, $usercontexts)
 {
     global $USER;
     // Let's keep these changes internal.
     $data = clone $filters;
     $query = new \SolrDisMaxQuery();
     $this->set_query($query, $data->q);
     $this->add_fields($query);
     // Search filters applied, we don't cache these filters as we don't want to pollute the cache with tmp filters
     // we are really interested in caching contexts filters instead.
     if (!empty($data->title)) {
         $query->addFilterQuery('{!field cache=false f=title}' . $data->title);
     }
     if (!empty($data->areaids)) {
         // If areaids are specified, we want to get any that match.
         $query->addFilterQuery('{!cache=false}areaid:(' . implode(' OR ', $data->areaids) . ')');
     }
     if (!empty($data->courseids)) {
         $query->addFilterQuery('{!cache=false}courseid:(' . implode(' OR ', $data->courseids) . ')');
     }
     if (!empty($data->timestart) or !empty($data->timeend)) {
         if (empty($data->timestart)) {
             $data->timestart = '*';
         } else {
             $data->timestart = \search_solr\document::format_time_for_engine($data->timestart);
         }
         if (empty($data->timeend)) {
             $data->timeend = '*';
         } else {
             $data->timeend = \search_solr\document::format_time_for_engine($data->timeend);
         }
         // No cache.
         $query->addFilterQuery('{!cache=false}modified:[' . $data->timestart . ' TO ' . $data->timeend . ']');
     }
     // Restrict to users who are supposed to be able to see a particular result.
     $query->addFilterQuery('owneruserid:(' . \core_search\manager::NO_OWNER_ID . ' OR ' . $USER->id . ')');
     // And finally restrict it to the context where the user can access, we want this one cached.
     // If the user can access all contexts $usercontexts value is just true, we don't need to filter
     // in that case.
     if ($usercontexts && is_array($usercontexts)) {
         // Join all area contexts into a single array and implode.
         $allcontexts = array();
         foreach ($usercontexts as $areaid => $areacontexts) {
             if (!empty($data->areaids) && !in_array($areaid, $data->areaids)) {
                 // Skip unused areas.
                 continue;
             }
             foreach ($areacontexts as $contextid) {
                 // Ensure they are unique.
                 $allcontexts[$contextid] = $contextid;
             }
         }
         if (empty($allcontexts)) {
             // This means there are no valid contexts for them, so they get no results.
             return array();
         }
         $query->addFilterQuery('contextid:(' . implode(' OR ', $allcontexts) . ')');
     }
     if ($this->file_indexing_enabled()) {
         // Now group records by solr_filegroupingid. Limit to 3 results per group.
         $query->setGroup(true);
         $query->setGroupLimit(3);
         $query->setGroupNGroups(true);
         $query->addGroupField('solr_filegroupingid');
     } else {
         // Make sure we only get text files, in case the index has pre-existing files.
         $query->addFilterQuery('type:' . \core_search\manager::TYPE_TEXT);
     }
     return $query;
 }
Beispiel #3
0
 public function test_export_file_for_engine()
 {
     // Get area to work with.
     $areaid = \core_search\manager::generate_areaid('core_mocksearch', 'mock_search_area');
     $area = \core_search\manager::get_search_area($areaid);
     $record = $this->generator->create_record();
     $doc = $area->get_document($record);
     $filerecord = new stdClass();
     $filerecord->timemodified = 978310800;
     $file = $this->generator->create_file($filerecord);
     $doc->add_stored_file($file);
     $filearray = $doc->export_file_for_engine($file);
     $this->assertEquals(\core_search\manager::TYPE_FILE, $filearray['type']);
     $this->assertEquals($file->get_id(), $filearray['solr_fileid']);
     $this->assertEquals($file->get_contenthash(), $filearray['solr_filecontenthash']);
     $this->assertEquals(\search_solr\document::INDEXED_FILE_TRUE, $filearray['solr_fileindexstatus']);
     $this->assertEquals($file->get_filename(), $filearray['title']);
     $this->assertEquals(978310800, \search_solr\document::import_time_from_engine($filearray['modified']));
 }
Beispiel #4
0
 /**
  * Prepares a Solr query, applies filters and executes it returning its results.
  *
  * @throws \core_search\engine_exception
  * @param  stdClass     $filters Containing query and filters.
  * @param  array        $usercontexts Contexts where the user has access. True if the user can access all contexts.
  * @return \core_search\document[] Results or false if no results
  */
 public function execute_query($filters, $usercontexts)
 {
     // Let's keep these changes internal.
     $data = clone $filters;
     // If there is any problem we trigger the exception as soon as possible.
     $this->client = $this->get_search_client();
     $serverstatus = $this->is_server_ready();
     if ($serverstatus !== true) {
         throw new \core_search\engine_exception('engineserverstatus', 'search');
     }
     $query = new \SolrQuery();
     $this->set_query($query, $data->q);
     $this->add_fields($query);
     // Search filters applied, we don't cache these filters as we don't want to pollute the cache with tmp filters
     // we are really interested in caching contexts filters instead.
     if (!empty($data->title)) {
         $query->addFilterQuery('{!field cache=false f=title}' . $data->title);
     }
     if (!empty($data->areaid)) {
         // Even if it is only supposed to contain PARAM_ALPHANUMEXT, better to prevent.
         $query->addFilterQuery('{!field cache=false f=areaid}' . $data->areaid);
     }
     if (!empty($data->timestart) or !empty($data->timeend)) {
         if (empty($data->timestart)) {
             $data->timestart = '*';
         } else {
             $data->timestart = \search_solr\document::format_time_for_engine($data->timestart);
         }
         if (empty($data->timeend)) {
             $data->timeend = '*';
         } else {
             $data->timeend = \search_solr\document::format_time_for_engine($data->timeend);
         }
         // No cache.
         $query->addFilterQuery('{!cache=false}modified:[' . $data->timestart . ' TO ' . $data->timeend . ']');
     }
     // And finally restrict it to the context where the user can access, we want this one cached.
     // If the user can access all contexts $usercontexts value is just true, we don't need to filter
     // in that case.
     if ($usercontexts && is_array($usercontexts)) {
         if (!empty($data->areaid)) {
             $query->addFilterQuery('contextid:(' . implode(' OR ', $usercontexts[$data->areaid]) . ')');
         } else {
             // Join all area contexts into a single array and implode.
             $allcontexts = array();
             foreach ($usercontexts as $areacontexts) {
                 foreach ($areacontexts as $contextid) {
                     // Ensure they are unique.
                     $allcontexts[$contextid] = $contextid;
                 }
             }
             $query->addFilterQuery('contextid:(' . implode(' OR ', $allcontexts) . ')');
         }
     }
     try {
         return $this->query_response($this->client->query($query));
     } catch (\SolrClientException $ex) {
         debugging('Error executing the provided query: ' . $ex->getMessage(), DEBUG_DEVELOPER);
         $this->queryerror = $ex->getMessage();
         return array();
     } catch (\SolrServerException $ex) {
         debugging('Error executing the provided query: ' . $ex->getMessage(), DEBUG_DEVELOPER);
         $this->queryerror = $ex->getMessage();
         return array();
     }
 }