Skip to content

Commit

Permalink
MDL-62869 search: implement searching for all courses
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitriim committed Feb 28, 2019
1 parent 89d1238 commit 2085e86
Show file tree
Hide file tree
Showing 19 changed files with 533 additions and 72 deletions.
6 changes: 5 additions & 1 deletion admin/settings/plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -576,14 +576,18 @@
$temp->add(new admin_setting_configduration('searchindextime',
new lang_string('searchindextime', 'admin'), new lang_string('searchindextime_desc', 'admin'),
600));
$temp->add(new admin_setting_heading('searchcoursesheading', new lang_string('searchablecourses', 'admin'), ''));
$options = [
0 => new lang_string('searchallavailablecourses_off', 'admin'),
1 => new lang_string('searchallavailablecourses_on', 'admin')
];
$temp->add(new admin_setting_configselect('searchallavailablecourses',
new lang_string('searchallavailablecourses', 'admin'),
new lang_string('searchallavailablecourses_desc', 'admin'),
new lang_string('searchallavailablecoursesdesc', 'admin'),
0, $options));
$temp->add(new admin_setting_configcheckbox('searchincludeallcourses',
new lang_string('searchincludeallcourses', 'admin'), new lang_string('searchincludeallcourses_desc', 'admin'),
0));

// Search display options.
$temp->add(new admin_setting_heading('searchdisplay', new lang_string('searchdisplay', 'admin'), ''));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Search area for Moodle courses I can access.
* Search area for Moodle courses.
*
* @package core_course
* @copyright 2016 Skylar Kelty <S.Kelty@kent.ac.uk>
Expand All @@ -26,13 +26,13 @@
defined('MOODLE_INTERNAL') || die();

/**
* Search area for Moodle courses I can access.
* Search area for Moodle courses.
*
* @package core_course
* @copyright 2016 Skylar Kelty <S.Kelty@kent.ac.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mycourse extends \core_search\base {
class course extends \core_search\base {

/**
* The context levels the search implementation is working on.
Expand Down Expand Up @@ -112,9 +112,13 @@ public function check_access($id) {
if (!$course) {
return \core_search\manager::ACCESS_DELETED;
}
if (can_access_course($course)) {

$coursecontext = \context_course::instance($course->id);

if ($course->visible || has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
return \core_search\manager::ACCESS_GRANTED;
}

return \core_search\manager::ACCESS_DENIED;
}

Expand Down
3 changes: 2 additions & 1 deletion course/classes/search/customfield.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ public function check_access($id) {
if (!$course) {
return \core_search\manager::ACCESS_DELETED;
}
if (can_access_course($course)) {
$coursecontext = \context_course::instance($course->id);
if ($course->visible || has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
return \core_search\manager::ACCESS_GRANTED;
}
return \core_search\manager::ACCESS_DENIED;
Expand Down
74 changes: 54 additions & 20 deletions course/tests/search_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class course_search_testcase extends advanced_testcase {
/**
* @var string Area id
*/
protected $mycoursesareaid = null;
protected $coursesareaid = null;

/**
* @var string Area id for sections
Expand All @@ -57,7 +57,7 @@ public function setUp() {
$this->resetAfterTest(true);
set_config('enableglobalsearch', true);

$this->mycoursesareaid = \core_search\manager::generate_areaid('core_course', 'mycourse');
$this->coursesareaid = \core_search\manager::generate_areaid('core_course', 'course');
$this->sectionareaid = \core_search\manager::generate_areaid('core_course', 'section');
$this->customfieldareaid = \core_search\manager::generate_areaid('core_course', 'customfield');

Expand All @@ -66,15 +66,15 @@ public function setUp() {
}

/**
* Indexing my courses contents.
* Indexing courses contents.
*
* @return void
*/
public function test_mycourses_indexing() {
public function test_courses_indexing() {

// Returns the instance as long as the area is supported.
$searcharea = \core_search\manager::get_search_area($this->mycoursesareaid);
$this->assertInstanceOf('\core_course\search\mycourse', $searcharea);
$searcharea = \core_search\manager::get_search_area($this->coursesareaid);
$this->assertInstanceOf('\core_course\search\course', $searcharea);

$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
Expand Down Expand Up @@ -113,10 +113,10 @@ public function test_mycourses_indexing() {
/**
* Tests course indexing support for contexts.
*/
public function test_mycourses_indexing_contexts() {
public function test_courses_indexing_contexts() {
global $DB, $USER, $SITE;

$searcharea = \core_search\manager::get_search_area($this->mycoursesareaid);
$searcharea = \core_search\manager::get_search_area($this->coursesareaid);

// Create some courses in categories, and a forum.
$generator = $this->getDataGenerator();
Expand Down Expand Up @@ -194,11 +194,11 @@ protected static function recordset_to_ids(moodle_recordset $rs) {
*
* @return void
*/
public function test_mycourses_document() {
public function test_courses_document() {

// Returns the instance as long as the area is supported.
$searcharea = \core_search\manager::get_search_area($this->mycoursesareaid);
$this->assertInstanceOf('\core_course\search\mycourse', $searcharea);
$searcharea = \core_search\manager::get_search_area($this->coursesareaid);
$this->assertInstanceOf('\core_course\search\course', $searcharea);

$user = self::getDataGenerator()->create_user();
$course = self::getDataGenerator()->create_course();
Expand All @@ -207,7 +207,7 @@ public function test_mycourses_document() {
$doc = $searcharea->get_document($course);
$this->assertInstanceOf('\core_search\document', $doc);
$this->assertEquals($course->id, $doc->get('itemid'));
$this->assertEquals($this->mycoursesareaid . '-' . $course->id, $doc->get('id'));
$this->assertEquals($this->coursesareaid . '-' . $course->id, $doc->get('id'));
$this->assertEquals($course->id, $doc->get('courseid'));
$this->assertFalse($doc->is_set('userid'));
$this->assertEquals(\core_search\manager::NO_OWNER_ID, $doc->get('owneruserid'));
Expand All @@ -224,10 +224,11 @@ public function test_mycourses_document() {
*
* @return void
*/
public function test_mycourses_access() {
public function test_courses_access() {
$this->resetAfterTest();

// Returns the instance as long as the area is supported.
$searcharea = \core_search\manager::get_search_area($this->mycoursesareaid);
$searcharea = \core_search\manager::get_search_area($this->coursesareaid);

$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
Expand All @@ -244,13 +245,13 @@ public function test_mycourses_access() {
$this->setUser($user1);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1->id));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course2->id));
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course3->id));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course3->id));
$this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-123));

$this->setUser($user2);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1->id));
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course2->id));
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course3->id));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course3->id));
}

/**
Expand Down Expand Up @@ -538,10 +539,43 @@ public function test_customfield_document() {
}

/**
* Test document icon for mycourse area.
* Document accesses for customfield area.
*/
public function test_get_doc_icon_for_mycourse_area() {
$searcharea = \core_search\manager::get_search_area($this->mycoursesareaid);
public function test_customfield_access() {
$this->resetAfterTest();

// Returns the instance as long as the area is supported.
$searcharea = \core_search\manager::get_search_area($this->customfieldareaid);

$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();

$course1 = self::getDataGenerator()->create_course();
$course2 = self::getDataGenerator()->create_course(array('visible' => 0));
$course3 = self::getDataGenerator()->create_course();

$this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'teacher');
$this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student');
$this->getDataGenerator()->enrol_user($user1->id, $course2->id, 'teacher');
$this->getDataGenerator()->enrol_user($user2->id, $course2->id, 'student');

$this->setUser($user1);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1->id));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course2->id));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course3->id));
$this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-123));

$this->setUser($user2);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1->id));
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course2->id));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course3->id));
}

/**
* Test document icon for course area.
*/
public function test_get_doc_icon_for_course_area() {
$searcharea = \core_search\manager::get_search_area($this->coursesareaid);

$document = $this->getMockBuilder('\core_search\document')
->disableOriginalConstructor()
Expand Down Expand Up @@ -573,7 +607,7 @@ public function test_get_doc_icon_for_section_area() {
* Test assigned search categories.
*/
public function test_get_category_names() {
$coursessearcharea = \core_search\manager::get_search_area($this->mycoursesareaid);
$coursessearcharea = \core_search\manager::get_search_area($this->coursesareaid);
$sectionsearcharea = \core_search\manager::get_search_area($this->sectionareaid);

$this->assertEquals(['core-courses'], $coursessearcharea->get_category_names());
Expand Down
4 changes: 4 additions & 0 deletions lang/en/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,7 @@
$string['savechanges'] = 'Save changes';
$string['scssinvalid'] = 'SCSS code is not valid, fails with: {$a}';
$string['search'] = 'Search';
$string['searchablecourses'] = 'Searchable courses';
$string['searchallavailablecourses'] = 'Searchable courses';
$string['searchallavailablecourses_off'] = 'Search within enrolled courses only';
$string['searchallavailablecourses_on'] = 'Search within all courses the user can access';
Expand All @@ -1066,6 +1067,9 @@
$string['searchhideallcategory_desc'] = 'If checked, the category with all results will be hidden on the search result screen.';
$string['searchdefaultcategory'] = 'Default search category';
$string['searchdefaultcategory_desc'] = 'Results from the selected search area category will be displayed by default.';
$string['searchallavailablecoursesdesc'] = 'If set to search within enrolled courses only, course information (name and summary) and course content will only be searched in courses which the user is enrolled in. Otherwise, course information and course content will be searched in all courses which the user can access, such as courses with guest access enabled.';
$string['searchincludeallcourses'] = 'Include all visible courses';
$string['searchincludeallcourses_desc'] = 'If enabled, search results will include course information (name and summary) of courses which are visible to the user, even if they don\'t have access to the course content.';
$string['searchalldeleted'] = 'All indexed contents have been deleted';
$string['searchareaenabled'] = 'Search area enabled';
$string['searchareadisabled'] = 'Search area disabled';
Expand Down
4 changes: 3 additions & 1 deletion lang/en/deprecated.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,6 @@ eventmessagecontactunblocked,core_message
userisblockingyou,core_message
userisblockingyounoncontact,core_message
error:invalidbadgeurl,core_badges
nomessages,core_message
nomessages,core_message
searchallavailablecourses_desc,core_admin
search:mycourse,core_search
2 changes: 2 additions & 0 deletions lang/en/search.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
$string['ittook'] = 'It took';
$string['matchingfile'] = 'Matched from file <span class="filename">{$a}</span>';
$string['matchingfiles'] = 'Matched from files:';
$string['mycoursesonly'] = 'My courses only';
$string['next'] = 'Next';
$string['noindexmessage'] = 'Admin: There appears to be no search index. Please';
$string['noresults'] = 'No results';
Expand Down Expand Up @@ -113,6 +114,7 @@
$string['search:message_received'] = 'Messages - received';
$string['search:message_sent'] = 'Messages - sent';
$string['search:mycourse'] = 'My courses';
$string['search:course'] = 'Courses';
$string['search:section'] = 'Course sections';
$string['search:user'] = 'Users';
$string['searcharea'] = 'Search area';
Expand Down
53 changes: 53 additions & 0 deletions lib/classes/task/clean_up_deleted_search_area_task.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Adhoc task that clean up data related ro deleted search area.
*
* @package core
* @copyright 2019 Dmitrii Metelkin <dmitriim@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

namespace core\task;

defined('MOODLE_INTERNAL') || die();

/**
* Class that cleans up data related to deleted search area.
*
* Custom data accepted:
* - areaid -> String search area id .
*
* @package core
* @copyright 2019 Dmitrii Metelkin <dmitriim@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class clean_up_deleted_search_area_task extends adhoc_task {

/**
* Run the task to clean up deleted search are data.
*/
public function execute() {
$areaid = $this->get_custom_data();

try {
\core_search\manager::clean_up_non_existing_area($areaid);
} catch (\core_search\engine_exception $e) {
mtrace('Search is not configured. Skip deleting index for search area ' . $areaid);
}
}
}
17 changes: 17 additions & 0 deletions lib/db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -2736,5 +2736,22 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2019021500.02);
}

if ($oldversion < 2019022500.00) {
// Create adhoc task to delete renamed My Course search area (ID core_course-mycourse).
$record = new \stdClass();
$record->classname = '\core\task\clean_up_deleted_search_area_task';
$record->component = 'core';

// Next run time based from nextruntime computation in \core\task\manager::queue_adhoc_task().
$nextruntime = time() - 1;
$record->nextruntime = $nextruntime;
$record->customdata = json_encode('core_course-mycourse');

$DB->insert_record('task_adhoc', $record);

// Main savepoint reached.
upgrade_main_savepoint(true, 2019022500.00);
}

return true;
}
13 changes: 11 additions & 2 deletions search/classes/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,7 @@ public function get_config() {
list($componentname, $varname) = $this->get_config_var_name();

$config = [];
$settingnames = array('_enabled', '_indexingstart', '_indexingend', '_lastindexrun',
'_docsignored', '_docsprocessed', '_recordsprocessed', '_partial');
$settingnames = self::get_settingnames();
foreach ($settingnames as $name) {
$config[$varname . $name] = get_config($componentname, $varname . $name);
}
Expand All @@ -188,6 +187,16 @@ public function get_config() {
return $config;
}

/**
* Return a list of all required setting names.
*
* @return array
*/
public static function get_settingnames() {
return array('_enabled', '_indexingstart', '_indexingend', '_lastindexrun',
'_docsignored', '_docsprocessed', '_recordsprocessed', '_partial');
}

/**
* Is the search component enabled by the system administrator?
*
Expand Down
Loading

0 comments on commit 2085e86

Please sign in to comment.