MDL-55356 core_search: Change existing search areas to new API

This change considers all existing search areas in Moodle and makes
necessary changes.

Custom change to course search, supported by helper in base.php:

* course/classes/search/mycourse.php

Custom change to message search:

* message/classes/search/message_received.php
* message/classes/search/message_sent.php

Custom change to user search:

* user/classes/search/user.php

Custom changes to module areas, supported by helper in base_mod.php:

* mod/book/classes/search/chapter.php
* mod/data/classes/search/entry.php
* mod/forum/classes/search/post.php
* mod/glossary/classes/search/entry.php
* mod/survey/classes/search/activity.php
* mod/wiki/classes/search/collaborative_page.php

(Note: the unit tests do not exhaustively check every context type
for these, given that's mainly handled by the helper function
which was already tested in the base_activity test.)

Handled by block base class (no change):

* blocks/html/classes/search/content.php

Handled by activity base class (no change):

* mod/assign/classes/search/activity.php
* mod/book/classes/search/activity.php
* mod/chat/classes/search/activity.php
* mod/choice/classes/search/activity.php
* mod/data/classes/search/activity.php
* mod/feedback/classes/search/activity.php
* mod/folder/classes/search/activity.php
* mod/forum/classes/search/activity.php
* mod/glossary/classes/search/activity.php
* mod/imscp/classes/search/activity.php
* mod/label/classes/search/activity.php
* mod/lesson/classes/search/activity.php
* mod/lti/classes/search/activity.php
* mod/page/classes/search/activity.php
* mod/quiz/classes/search/activity.php
* mod/resource/classes/search/activity.php
* mod/scorm/classes/search/activity.php
* mod/url/classes/search/activity.php
* mod/wiki/classes/search/activity.php
* mod/workshop/classes/search/activity.php
This commit is contained in:
sam marshall 2017-09-11 11:29:26 +01:00
parent 81a988833e
commit 66e3702680
21 changed files with 584 additions and 58 deletions

View file

@ -132,4 +132,53 @@ abstract class base_message extends \core_search\base {
return $users;
}
/**
* Helper function to implement get_document_recordset for subclasses.
*
* @param int $modifiedfrom Modified from date
* @param \context|null $context Context or null
* @param string $userfield Name of user field (from or to) being considered
* @return \moodle_recordset|null Recordset or null if no results possible
* @throws \coding_exception If context invalid
*/
protected function get_document_recordset_helper($modifiedfrom, \context $context = null,
$userfield) {
global $DB;
// Set up basic query.
$where = $userfield . ' != :noreplyuser AND ' . $userfield .
' != :supportuser AND timecreated >= :modifiedfrom';
$params = [
'noreplyuser' => \core_user::NOREPLY_USER,
'supportuser' => \core_user::SUPPORT_USER,
'modifiedfrom' => $modifiedfrom
];
// Check context to see whether to add other restrictions.
if ($context === null) {
$context = \context_system::instance();
}
switch ($context->contextlevel) {
case CONTEXT_COURSECAT:
case CONTEXT_COURSE:
case CONTEXT_MODULE:
case CONTEXT_BLOCK:
// There are no messages in any of these contexts so nothing can be found.
return null;
case CONTEXT_USER:
// Add extra restriction to specific user context.
$where .= ' AND ' . $userfield . ' = :userid';
$params['userid'] = $context->instanceid;
break;
case CONTEXT_SYSTEM:
break;
default:
throw new \coding_exception('Unexpected contextlevel: ' . $context->contextlevel);
}
return $DB->get_recordset_select('message_read', $where, $params, 'timeread ASC');
}
}

View file

@ -36,19 +36,14 @@ defined('MOODLE_INTERNAL') || die();
class message_received extends base_message {
/**
* Returns recordset containing message records.
* Returns a recordset with the messages for indexing.
*
* @param int $modifiedfrom timestamp
* @return \moodle_recordset
* @param int $modifiedfrom
* @param \context|null $context Optional context to restrict scope of returned results
* @return moodle_recordset|null Recordset (or null if no results)
*/
public function get_recordset_by_timestamp($modifiedfrom = 0) {
global $DB;
// We don't want to index messages received from noreply and support users.
$params = array('modifiedfrom' => $modifiedfrom, 'noreplyuser' => \core_user::NOREPLY_USER,
'supportuser' => \core_user::SUPPORT_USER);
return $DB->get_recordset_select('message_read', 'timeread >= :modifiedfrom AND
useridto != :noreplyuser AND useridto != :supportuser', $params, 'timeread ASC');
public function get_document_recordset($modifiedfrom = 0, \context $context = null) {
return $this->get_document_recordset_helper($modifiedfrom, $context, 'useridto');
}
/**

View file

@ -35,19 +35,14 @@ defined('MOODLE_INTERNAL') || die();
class message_sent extends base_message {
/**
* Returns recordset containing message records.
* Returns a recordset with the messages for indexing.
*
* @param int $modifiedfrom timestamp
* @return \moodle_recordset
* @param int $modifiedfrom
* @param \context|null $context Optional context to restrict scope of returned results
* @return moodle_recordset|null Recordset (or null if no results)
*/
public function get_recordset_by_timestamp($modifiedfrom = 0) {
global $DB;
// We don't want to index messages sent by noreply and support users.
$params = array('modifiedfrom' => $modifiedfrom, 'noreplyuser' => \core_user::NOREPLY_USER,
'supportuser' => \core_user::SUPPORT_USER);
return $DB->get_recordset_select('message_read', 'timeread >= :modifiedfrom AND
useridfrom != :noreplyuser AND useridfrom != :supportuser', $params, 'timeread ASC');
public function get_document_recordset($modifiedfrom = 0, \context $context = null) {
return $this->get_document_recordset_helper($modifiedfrom, $context, 'useridfrom');
}
/**

View file

@ -113,6 +113,71 @@ class message_received_search_testcase extends advanced_testcase {
$recordset->close();
}
/**
* Indexing messages, with restricted contexts.
*/
public function test_message_received_indexing_contexts() {
global $SITE;
require_once(__DIR__ . '/search_sent_test.php');
$searcharea = \core_search\manager::get_search_area($this->messagereceivedareaid);
$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
$this->preventResetByRollback();
$sink = $this->redirectMessages();
// Send first message.
$message = new \core\message\message();
$message->courseid = SITEID;
$message->userfrom = $user1;
$message->userto = $user2;
$message->subject = 'Test1';
$message->smallmessage = 'Test small messsage';
$message->fullmessage = 'Test full messsage';
$message->fullmessageformat = 0;
$message->fullmessagehtml = null;
$message->notification = 0;
$message->component = 'moodle';
$message->name = 'instantmessage';
message_send($message);
// Ensure that ordering by timestamp will return in consistent order.
$this->waitForSecond();
// Send second message in opposite direction.
$message = new \core\message\message();
$message->courseid = SITEID;
$message->userfrom = $user2;
$message->userto = $user1;
$message->subject = 'Test2';
$message->smallmessage = 'Test small messsage';
$message->fullmessage = 'Test full messsage';
$message->fullmessageformat = 0;
$message->fullmessagehtml = null;
$message->notification = 0;
$message->component = 'moodle';
$message->name = 'instantmessage';
message_send($message);
// Test function with null context and system context (same).
$rs = $searcharea->get_document_recordset(0, null);
$this->assertEquals(['Test1', 'Test2'], message_sent_search_testcase::recordset_to_subjects($rs));
$rs = $searcharea->get_document_recordset(0, context_system::instance());
$this->assertEquals(['Test1', 'Test2'], message_sent_search_testcase::recordset_to_subjects($rs));
// Test with user context for each user.
$rs = $searcharea->get_document_recordset(0, \context_user::instance($user1->id));
$this->assertEquals(['Test2'], message_sent_search_testcase::recordset_to_subjects($rs));
$rs = $searcharea->get_document_recordset(0, \context_user::instance($user2->id));
$this->assertEquals(['Test1'], message_sent_search_testcase::recordset_to_subjects($rs));
// Test with a course context (should return null).
$this->assertNull($searcharea->get_document_recordset(0,
context_course::instance($SITE->id)));
}
/**
* Document contents.
*

View file

@ -113,6 +113,85 @@ class message_sent_search_testcase extends advanced_testcase {
$recordset->close();
}
/**
* Indexing messages, with restricted contexts.
*/
public function test_message_sent_indexing_contexts() {
global $SITE;
$searcharea = \core_search\manager::get_search_area($this->messagesentareaid);
$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
$this->preventResetByRollback();
$sink = $this->redirectMessages();
// Send first message.
$message = new \core\message\message();
$message->courseid = SITEID;
$message->userfrom = $user1;
$message->userto = $user2;
$message->subject = 'Test1';
$message->smallmessage = 'Test small messsage';
$message->fullmessage = 'Test full messsage';
$message->fullmessageformat = 0;
$message->fullmessagehtml = null;
$message->notification = 0;
$message->component = 'moodle';
$message->name = 'instantmessage';
message_send($message);
// Ensure that ordering by timestamp will return in consistent order.
$this->waitForSecond();
// Send second message in opposite direction.
$message = new \core\message\message();
$message->courseid = SITEID;
$message->userfrom = $user2;
$message->userto = $user1;
$message->subject = 'Test2';
$message->smallmessage = 'Test small messsage';
$message->fullmessage = 'Test full messsage';
$message->fullmessageformat = 0;
$message->fullmessagehtml = null;
$message->notification = 0;
$message->component = 'moodle';
$message->name = 'instantmessage';
message_send($message);
// Test function with null context and system context (same).
$rs = $searcharea->get_document_recordset(0, null);
$this->assertEquals(['Test1', 'Test2'], self::recordset_to_subjects($rs));
$rs = $searcharea->get_document_recordset(0, context_system::instance());
$this->assertEquals(['Test1', 'Test2'], self::recordset_to_subjects($rs));
// Test with user context for each user.
$rs = $searcharea->get_document_recordset(0, \context_user::instance($user1->id));
$this->assertEquals(['Test1'], self::recordset_to_subjects($rs));
$rs = $searcharea->get_document_recordset(0, \context_user::instance($user2->id));
$this->assertEquals(['Test2'], self::recordset_to_subjects($rs));
// Test with a course context (should return null).
$this->assertNull($searcharea->get_document_recordset(0,
context_course::instance($SITE->id)));
}
/**
* Utility function to convert recordset to array of message subjects for testing.
*
* @param moodle_recordset $rs Recordset to convert (and close)
* @return array Array of IDs from records indexed by number (0, 1, 2, ...)
*/
public static function recordset_to_subjects(moodle_recordset $rs) {
$results = [];
foreach ($rs as $rec) {
$results[] = $rec->subject;
}
$rs->close();
return $results;
}
/**
* Document contents.
*
@ -272,4 +351,4 @@ class message_sent_search_testcase extends advanced_testcase {
$this->assertFalse($doc);
}
}
}