mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 20:42:22 +02:00
MDL-60913 search: add search area categories
This commit is contained in:
parent
c092f75791
commit
e9074ee381
@ -153,6 +153,7 @@ $table = new html_table();
|
||||
$table->id = 'core-search-areas';
|
||||
$table->head = [
|
||||
get_string('searcharea', 'search'),
|
||||
get_string('searchareacategories', 'search'),
|
||||
get_string('enable'),
|
||||
get_string('newestdocindexed', 'admin'),
|
||||
get_string('searchlastrun', 'admin'),
|
||||
@ -165,6 +166,14 @@ foreach ($searchareas as $area) {
|
||||
$areaid = $area->get_area_id();
|
||||
$columns = array(new html_table_cell($area->get_visible_name()));
|
||||
|
||||
$areacategories = [];
|
||||
foreach (\core_search\manager::get_search_area_categories() as $category) {
|
||||
if (key_exists($areaid, $category->get_areas())) {
|
||||
$areacategories[] = $category->get_visiblename();
|
||||
}
|
||||
}
|
||||
$columns[] = new html_table_cell(implode(', ', $areacategories));
|
||||
|
||||
if ($area->is_enabled()) {
|
||||
$columns[] = $OUTPUT->action_icon(admin_searcharea_action_url('disable', $areaid),
|
||||
new pix_icon('t/hide', get_string('disable'), 'moodle', array('title' => '', 'class' => 'iconsmall')),
|
||||
|
@ -573,6 +573,25 @@ if ($hassiteconfig) {
|
||||
new lang_string('searchallavailablecourses_desc', 'admin'),
|
||||
0, $options));
|
||||
|
||||
// Search display options.
|
||||
$temp->add(new admin_setting_heading('searchdisplay', new lang_string('searchdisplay', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configcheckbox('searchenablecategories',
|
||||
new lang_string('searchenablecategories', 'admin'),
|
||||
new lang_string('searchenablecategories_desc', 'admin'),
|
||||
0));
|
||||
$options = [];
|
||||
foreach (\core_search\manager::get_search_area_categories() as $category) {
|
||||
$options[$category->get_name()] = $category->get_visiblename();
|
||||
}
|
||||
$temp->add(new admin_setting_configselect('searchdefaultcategory',
|
||||
new lang_string('searchdefaultcategory', 'admin'),
|
||||
new lang_string('searchdefaultcategory_desc', 'admin'),
|
||||
\core_search\manager::SEARCH_AREA_CATEGORY_ALL, $options));
|
||||
$temp->add(new admin_setting_configcheckbox('searchhideallcategory',
|
||||
new lang_string('searchhideallcategory', 'admin'),
|
||||
new lang_string('searchhideallcategory_desc', 'admin'),
|
||||
0));
|
||||
|
||||
$ADMIN->add('searchplugins', $temp);
|
||||
$ADMIN->add('searchplugins', new admin_externalpage('searchareas', new lang_string('searchareas', 'admin'),
|
||||
new moodle_url('/admin/searchareas.php')));
|
||||
|
@ -184,4 +184,13 @@ class mycourse extends \core_search\base {
|
||||
public function get_doc_icon(\core_search\document $doc) : \core_search\document_icon {
|
||||
return new \core_search\document_icon('i/course');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of category names associated with the area.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_category_names() {
|
||||
return [\core_search\manager::SEARCH_AREA_CATEGORY_COURSES];
|
||||
}
|
||||
}
|
||||
|
@ -205,4 +205,13 @@ class section extends \core_search\base {
|
||||
public function get_doc_icon(\core_search\document $doc) : \core_search\document_icon {
|
||||
return new \core_search\document_icon('i/section');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of category names associated with the area.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_category_names() {
|
||||
return [\core_search\manager::SEARCH_AREA_CATEGORY_COURSE_CONTENT];
|
||||
}
|
||||
}
|
||||
|
@ -478,4 +478,15 @@ class course_search_testcase extends advanced_testcase {
|
||||
$this->assertEquals('i/section', $result->get_name());
|
||||
$this->assertEquals('moodle', $result->get_component());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test assigned search categories.
|
||||
*/
|
||||
public function test_get_category_names() {
|
||||
$coursessearcharea = \core_search\manager::get_search_area($this->mycoursesareaid);
|
||||
$sectionsearcharea = \core_search\manager::get_search_area($this->sectionareaid);
|
||||
|
||||
$this->assertEquals(['core-courses'], $coursessearcharea->get_category_names());
|
||||
$this->assertEquals(['core-course-content'], $sectionsearcharea->get_category_names());
|
||||
}
|
||||
}
|
||||
|
@ -1054,6 +1054,13 @@ $string['searchallavailablecourses'] = 'Searchable courses';
|
||||
$string['searchallavailablecourses_off'] = 'Search within enrolled courses only';
|
||||
$string['searchallavailablecourses_on'] = 'Search within all courses the user can access';
|
||||
$string['searchallavailablecourses_desc'] = 'In some situations the search engine may not work when searching across a large number of courses. Set to search only enrolled courses if you need to restrict the number of courses searched.';
|
||||
$string['searchdisplay'] = 'Search results display options';
|
||||
$string['searchenablecategories'] = 'Display results in separate categories';
|
||||
$string['searchenablecategories_desc'] = 'If enabled, search results will be displayed in separate categories.';
|
||||
$string['searchhideallcategory'] = 'Hide All results category';
|
||||
$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['searchalldeleted'] = 'All indexed contents have been deleted';
|
||||
$string['searchareaenabled'] = 'Search area enabled';
|
||||
$string['searchareadisabled'] = 'Search area disabled';
|
||||
|
@ -36,6 +36,11 @@ $string['confirm_delete'] = 'Are you sure you want to delete the index for {$a}?
|
||||
$string['confirm_indexall'] = 'Are you sure you want to update indexed contents now? If a large amount of content needs indexing, this can take a long time. For live servers, you should normally leave indexing to the \'Global search indexing\' scheduled task.';
|
||||
$string['confirm_reindexall'] = 'Are you sure you want to reindex all site contents now? If your site contains a large amount of content, this will take a long time, and users may not get full search results until it completes.';
|
||||
$string['confirm_deleteall'] = 'Are you sure you want to delete all indexed contents now? Until the site is indexed again, users will not get search results.';
|
||||
$string['core-all'] = 'All';
|
||||
$string['core-course-content'] = 'Course content';
|
||||
$string['core-courses'] = 'Courses';
|
||||
$string['core-users'] = 'Users';
|
||||
$string['core-other'] = 'Other';
|
||||
$string['createanindex'] = 'create an index';
|
||||
$string['createdon'] = 'Created on';
|
||||
$string['database'] = 'Database';
|
||||
@ -111,6 +116,7 @@ $string['search:mycourse'] = 'My courses';
|
||||
$string['search:section'] = 'Course sections';
|
||||
$string['search:user'] = 'Users';
|
||||
$string['searcharea'] = 'Search area';
|
||||
$string['searchareacategories'] = 'Seach area categories';
|
||||
$string['searching'] = 'Searching in ...';
|
||||
$string['searchnotpermitted'] = 'You are not allowed to do a search';
|
||||
$string['searchsetupdescription'] = 'The following steps help you to set up Moodle global search.';
|
||||
|
@ -207,4 +207,13 @@ abstract class base_message extends \core_search\base {
|
||||
public function get_doc_icon(\core_search\document $doc) : \core_search\document_icon {
|
||||
return new \core_search\document_icon('t/message');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of category names associated with the area.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_category_names() {
|
||||
return [\core_search\manager::SEARCH_AREA_CATEGORY_USERS];
|
||||
}
|
||||
}
|
||||
|
@ -352,4 +352,14 @@ class message_received_search_testcase extends advanced_testcase {
|
||||
$this->assertEquals('t/message', $result->get_name());
|
||||
$this->assertEquals('moodle', $result->get_component());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test assigned search categories.
|
||||
*/
|
||||
public function test_get_category_names() {
|
||||
$searcharea = \core_search\manager::get_search_area($this->messagereceivedareaid);
|
||||
|
||||
$expected = ['core-users'];
|
||||
$this->assertEquals($expected, $searcharea->get_category_names());
|
||||
}
|
||||
}
|
||||
|
@ -367,4 +367,14 @@ class message_sent_search_testcase extends advanced_testcase {
|
||||
$this->assertEquals('t/message', $result->get_name());
|
||||
$this->assertEquals('moodle', $result->get_component());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test assigned search categories.
|
||||
*/
|
||||
public function test_get_category_names() {
|
||||
$searcharea = \core_search\manager::get_search_area($this->messagesentareaid);
|
||||
|
||||
$expected = ['core-users'];
|
||||
$this->assertEquals($expected, $searcharea->get_category_names());
|
||||
}
|
||||
}
|
||||
|
126
search/classes/area_category.php
Normal file
126
search/classes/area_category.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Search area category.
|
||||
*
|
||||
* @package core_search
|
||||
* @copyright Dmitrii Metelkin <dmitriim@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_search;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Search area category.
|
||||
*
|
||||
* @package core_search
|
||||
* @copyright Dmitrii Metelkin <dmitriim@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class area_category {
|
||||
|
||||
/**
|
||||
* Category name.
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Category visible name.
|
||||
* @var string
|
||||
*/
|
||||
protected $visiblename;
|
||||
|
||||
/**
|
||||
* Category order.
|
||||
* @var int
|
||||
*/
|
||||
protected $order = 0;
|
||||
|
||||
/**
|
||||
* Category areas.
|
||||
* @var \core_search\base[]
|
||||
*/
|
||||
protected $areas = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name Unique name of the category.
|
||||
* @param string $visiblename Visible name of the category.
|
||||
* @param int $order Category position in the list (smaller numbers will be displayed first).
|
||||
* @param \core_search\base[] $areas A list of search areas associated with this category.
|
||||
*/
|
||||
public function __construct(string $name, string $visiblename, int $order = 0, array $areas = []) {
|
||||
$this->name = $name;
|
||||
$this->visiblename = $visiblename;
|
||||
$this->order = $order;
|
||||
$this->set_areas($areas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get visible name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_visiblename() {
|
||||
return $this->visiblename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order to display.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_order() {
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a keyed by area id list of areas for this category.
|
||||
*
|
||||
* @return \core_search\base[]
|
||||
*/
|
||||
public function get_areas() {
|
||||
return $this->areas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list of search areas for this category,
|
||||
*
|
||||
* @param \core_search\base[] $areas
|
||||
*/
|
||||
public function set_areas(array $areas) {
|
||||
foreach ($areas as $area) {
|
||||
if ($area instanceof base && !key_exists($area->get_area_id(), $this->areas)) {
|
||||
$this->areas[$area->get_area_id()] = $area;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -532,4 +532,13 @@ abstract class base {
|
||||
public function get_doc_icon(document $doc) : document_icon {
|
||||
return new document_icon('i/empty');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of category names associated with the area.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_category_names() {
|
||||
return [manager::SEARCH_AREA_CATEGORY_OTHER];
|
||||
}
|
||||
}
|
||||
|
@ -408,4 +408,13 @@ abstract class base_block extends base {
|
||||
public function get_doc_icon(document $doc) : document_icon {
|
||||
return new document_icon('e/anchor');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of category names associated with the area.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_category_names() {
|
||||
return [manager::SEARCH_AREA_CATEGORY_COURSE_CONTENT];
|
||||
}
|
||||
}
|
||||
|
@ -296,4 +296,13 @@ abstract class base_mod extends base {
|
||||
public function get_doc_icon(document $doc) : document_icon {
|
||||
return new document_icon('icon', $this->get_module_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of category names associated with the area.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_category_names() {
|
||||
return [manager::SEARCH_AREA_CATEGORY_COURSE_CONTENT];
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +97,31 @@ class manager {
|
||||
*/
|
||||
const INDEX_PRIORITY_REINDEXING = 50;
|
||||
|
||||
/**
|
||||
* @var string Core search area category for all results.
|
||||
*/
|
||||
const SEARCH_AREA_CATEGORY_ALL = 'core-all';
|
||||
|
||||
/**
|
||||
* @var string Core search area category for course content.
|
||||
*/
|
||||
const SEARCH_AREA_CATEGORY_COURSE_CONTENT = 'core-course-content';
|
||||
|
||||
/**
|
||||
* @var string Core search area category for courses.
|
||||
*/
|
||||
const SEARCH_AREA_CATEGORY_COURSES = 'core-courses';
|
||||
|
||||
/**
|
||||
* @var string Core search area category for users.
|
||||
*/
|
||||
const SEARCH_AREA_CATEGORY_USERS = 'core-users';
|
||||
|
||||
/**
|
||||
* @var string Core search area category for results that do not fit into any of existing categories.
|
||||
*/
|
||||
const SEARCH_AREA_CATEGORY_OTHER = 'core-other';
|
||||
|
||||
/**
|
||||
* @var \core_search\base[] Enabled search areas.
|
||||
*/
|
||||
@ -107,6 +132,11 @@ class manager {
|
||||
*/
|
||||
protected static $allsearchareas = null;
|
||||
|
||||
/**
|
||||
* @var \core_search\area_category[] A list of search area categories.
|
||||
*/
|
||||
protected static $searchareacategories = null;
|
||||
|
||||
/**
|
||||
* @var \core_search\manager
|
||||
*/
|
||||
@ -359,6 +389,162 @@ class manager {
|
||||
return static::$allsearchareas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return search area category instance by category name.
|
||||
*
|
||||
* @param string $name Category name. If name is not valid will return default category.
|
||||
*
|
||||
* @return \core_search\area_category
|
||||
*/
|
||||
public static function get_search_area_category_by_name($name) {
|
||||
if (key_exists($name, self::get_search_area_categories())) {
|
||||
return self::get_search_area_categories()[$name];
|
||||
} else {
|
||||
return self::get_search_area_categories()[self::get_default_area_category_name()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of existing search area categories.
|
||||
*
|
||||
* @return \core_search\area_category[]
|
||||
*/
|
||||
public static function get_search_area_categories() {
|
||||
if (!isset(static::$searchareacategories)) {
|
||||
$categories = self::get_core_search_area_categories();
|
||||
|
||||
// Go through all existing search areas and get categories they are assigned to.
|
||||
$areacategories = [];
|
||||
foreach (self::get_search_areas_list() as $searcharea) {
|
||||
foreach ($searcharea->get_category_names() as $categoryname) {
|
||||
if (!key_exists($categoryname, $areacategories)) {
|
||||
$areacategories[$categoryname] = [];
|
||||
}
|
||||
|
||||
$areacategories[$categoryname][] = $searcharea;
|
||||
}
|
||||
}
|
||||
|
||||
// Populate core categories by areas.
|
||||
foreach ($areacategories as $name => $searchareas) {
|
||||
if (key_exists($name, $categories)) {
|
||||
$categories[$name]->set_areas($searchareas);
|
||||
} else {
|
||||
throw new \coding_exception('Unknown core search area category ' . $name);
|
||||
}
|
||||
}
|
||||
|
||||
// Get additional categories.
|
||||
$additionalcategories = self::get_additional_search_area_categories();
|
||||
foreach ($additionalcategories as $additionalcategory) {
|
||||
if (!key_exists($additionalcategory->get_name(), $categories)) {
|
||||
$categories[$additionalcategory->get_name()] = $additionalcategory;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove categories without areas.
|
||||
foreach ($categories as $key => $category) {
|
||||
if (empty($category->get_areas())) {
|
||||
unset($categories[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort categories by order.
|
||||
uasort($categories, function($category1, $category2) {
|
||||
return $category1->get_order() > $category2->get_order();
|
||||
});
|
||||
|
||||
static::$searchareacategories = $categories;
|
||||
}
|
||||
|
||||
return static::$searchareacategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of core search area categories.
|
||||
*
|
||||
* @return \core_search\area_category[]
|
||||
*/
|
||||
protected static function get_core_search_area_categories() {
|
||||
$categories = [];
|
||||
|
||||
$categories[self::SEARCH_AREA_CATEGORY_ALL] = new area_category(
|
||||
self::SEARCH_AREA_CATEGORY_ALL,
|
||||
get_string('core-all', 'search'),
|
||||
0,
|
||||
self::get_search_areas_list(true)
|
||||
);
|
||||
|
||||
$categories[self::SEARCH_AREA_CATEGORY_COURSE_CONTENT] = new area_category(
|
||||
self::SEARCH_AREA_CATEGORY_COURSE_CONTENT,
|
||||
get_string('core-course-content', 'search'),
|
||||
1
|
||||
);
|
||||
|
||||
$categories[self::SEARCH_AREA_CATEGORY_COURSES] = new area_category(
|
||||
self::SEARCH_AREA_CATEGORY_COURSES,
|
||||
get_string('core-courses', 'search'),
|
||||
2
|
||||
);
|
||||
|
||||
$categories[self::SEARCH_AREA_CATEGORY_USERS] = new area_category(
|
||||
self::SEARCH_AREA_CATEGORY_USERS,
|
||||
get_string('core-users', 'search'),
|
||||
3
|
||||
);
|
||||
|
||||
$categories[self::SEARCH_AREA_CATEGORY_OTHER] = new area_category(
|
||||
self::SEARCH_AREA_CATEGORY_OTHER,
|
||||
get_string('core-other', 'search'),
|
||||
4
|
||||
);
|
||||
|
||||
return $categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of additional search area categories.
|
||||
*
|
||||
* @return \core_search\area_category[]
|
||||
*/
|
||||
protected static function get_additional_search_area_categories() {
|
||||
$additionalcategories = [];
|
||||
|
||||
// Allow plugins to add custom search area categories.
|
||||
if ($pluginsfunction = get_plugins_with_function('search_area_categories')) {
|
||||
foreach ($pluginsfunction as $plugintype => $plugins) {
|
||||
foreach ($plugins as $pluginfunction) {
|
||||
$plugincategories = $pluginfunction();
|
||||
// We're expecting a list of valid area categories.
|
||||
if (is_array($plugincategories)) {
|
||||
foreach ($plugincategories as $plugincategory) {
|
||||
if (self::is_valid_area_category($plugincategory)) {
|
||||
$additionalcategories[] = $plugincategory;
|
||||
} else {
|
||||
throw new \coding_exception('Invalid search area category!');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new \coding_exception($pluginfunction . ' should return a list of search area categories!');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $additionalcategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if provided instance of area category is valid.
|
||||
*
|
||||
* @param mixed $areacategory Area category instance. Potentially could be anything.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function is_valid_area_category($areacategory) {
|
||||
return $areacategory instanceof area_category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all static caches.
|
||||
*
|
||||
@ -369,6 +555,7 @@ class manager {
|
||||
static::$enabledsearchareas = null;
|
||||
static::$allsearchareas = null;
|
||||
static::$instance = null;
|
||||
static::$searchareacategories = null;
|
||||
|
||||
base_block::clear_static();
|
||||
engine::clear_users_cache();
|
||||
@ -671,6 +858,19 @@ class manager {
|
||||
public function paged_search(\stdClass $formdata, $pagenum) {
|
||||
$out = new \stdClass();
|
||||
|
||||
if (self::is_search_area_categories_enabled() && !empty($formdata->cat)) {
|
||||
$cat = self::get_search_area_category_by_name($formdata->cat);
|
||||
if (empty($formdata->areaids)) {
|
||||
$formdata->areaids = array_keys($cat->get_areas());
|
||||
} else {
|
||||
foreach ($formdata->areaids as $key => $areaid) {
|
||||
if (!key_exists($areaid, $cat->get_areas())) {
|
||||
unset($formdata->areaids[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$perpage = static::DISPLAY_RESULTS_PER_PAGE;
|
||||
|
||||
// Make sure we only allow request up to max page.
|
||||
@ -1435,4 +1635,41 @@ class manager {
|
||||
}
|
||||
return microtime(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if search area categories functionality is enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_search_area_categories_enabled() {
|
||||
return !empty(get_config('core', 'searchenablecategories'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all results category should be hidden.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function should_hide_all_results_category() {
|
||||
return get_config('core', 'searchhideallcategory');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default search area category name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_default_area_category_name() {
|
||||
$default = get_config('core', 'searchdefaultcategory');
|
||||
|
||||
if (empty($default)) {
|
||||
$default = self::SEARCH_AREA_CATEGORY_ALL;
|
||||
}
|
||||
|
||||
if ($default == self::SEARCH_AREA_CATEGORY_ALL && self::should_hide_all_results_category()) {
|
||||
$default = self::SEARCH_AREA_CATEGORY_COURSE_CONTENT;
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,13 @@ class search extends \moodleform {
|
||||
global $USER, $DB, $OUTPUT;
|
||||
|
||||
$mform =& $this->_form;
|
||||
|
||||
if (\core_search\manager::is_search_area_categories_enabled() && !empty($this->_customdata['cat'])) {
|
||||
$mform->addElement('hidden', 'cat');
|
||||
$mform->setType('cat', PARAM_NOTAGS);
|
||||
$mform->setDefault('cat', $this->_customdata['cat']);
|
||||
}
|
||||
|
||||
$mform->disable_form_change_checker();
|
||||
$mform->addElement('header', 'search', get_string('search', 'search'));
|
||||
|
||||
@ -72,11 +79,21 @@ class search extends \moodleform {
|
||||
$mform->setType('title', PARAM_TEXT);
|
||||
|
||||
$search = \core_search\manager::instance(true);
|
||||
|
||||
$searchareas = \core_search\manager::get_search_areas_list(true);
|
||||
$enabledsearchareas = \core_search\manager::get_search_areas_list(true);
|
||||
$areanames = array();
|
||||
foreach ($searchareas as $areaid => $searcharea) {
|
||||
$areanames[$areaid] = $searcharea->get_visible_name();
|
||||
|
||||
if (\core_search\manager::is_search_area_categories_enabled() && !empty($this->_customdata['cat'])) {
|
||||
$searchareacategory = \core_search\manager::get_search_area_category_by_name($this->_customdata['cat']);
|
||||
$searchareas = $searchareacategory->get_areas();
|
||||
foreach ($searchareas as $areaid => $searcharea) {
|
||||
if (key_exists($areaid, $enabledsearchareas)) {
|
||||
$areanames[$areaid] = $searcharea->get_visible_name();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($enabledsearchareas as $areaid => $searcharea) {
|
||||
$areanames[$areaid] = $searcharea->get_visible_name();
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the array by the text.
|
||||
|
@ -53,13 +53,32 @@ class renderer extends \plugin_renderer_base {
|
||||
* @param int $page Zero based page number.
|
||||
* @param int $totalcount Total number of results available.
|
||||
* @param \moodle_url $url
|
||||
* @param \core_search\area_category|null $cat Selected search are category or null if category functionality is disabled.
|
||||
* @return string HTML
|
||||
*/
|
||||
public function render_results($results, $page, $totalcount, $url) {
|
||||
public function render_results($results, $page, $totalcount, $url, $cat = null) {
|
||||
$content = '';
|
||||
|
||||
if (\core_search\manager::is_search_area_categories_enabled() && !empty($cat)) {
|
||||
$toprow = [];
|
||||
foreach (\core_search\manager::get_search_area_categories() as $category) {
|
||||
$taburl = clone $url;
|
||||
$taburl->param('cat', $category->get_name());
|
||||
$taburl->param('page', 0);
|
||||
$taburl->remove_params(['page', 'areaids']);
|
||||
$toprow[$category->get_name()] = new \tabobject($category->get_name(), $taburl, $category->get_visiblename());
|
||||
}
|
||||
|
||||
if (\core_search\manager::should_hide_all_results_category()) {
|
||||
unset($toprow[\core_search\manager::SEARCH_AREA_CATEGORY_ALL]);
|
||||
}
|
||||
|
||||
$content .= $this->tabtree($toprow, $cat->get_name());
|
||||
}
|
||||
|
||||
// Paging bar.
|
||||
$perpage = \core_search\manager::DISPLAY_RESULTS_PER_PAGE;
|
||||
$content = $this->output->paging_bar($totalcount, $page, $perpage, $url);
|
||||
$content .= $this->output->paging_bar($totalcount, $page, $perpage, $url);
|
||||
|
||||
// Results.
|
||||
$resultshtml = array();
|
||||
|
@ -28,6 +28,12 @@ $page = optional_param('page', 0, PARAM_INT);
|
||||
$q = optional_param('q', '', PARAM_NOTAGS);
|
||||
$title = optional_param('title', '', PARAM_NOTAGS);
|
||||
$contextid = optional_param('context', 0, PARAM_INT);
|
||||
$cat = optional_param('cat', '', PARAM_NOTAGS);
|
||||
|
||||
if (\core_search\manager::is_search_area_categories_enabled()) {
|
||||
$cat = \core_search\manager::get_search_area_category_by_name($cat);
|
||||
}
|
||||
|
||||
// Moving areaids, courseids, timestart, and timeend further down as they might come as an array if they come from the form.
|
||||
|
||||
$context = context_system::instance();
|
||||
@ -80,6 +86,10 @@ if ($contextid) {
|
||||
// Get available ordering options from search engine.
|
||||
$customdata['orderoptions'] = $search->get_engine()->get_supported_orders($context);
|
||||
|
||||
if ($cat instanceof \core_search\area_category) {
|
||||
$customdata['cat'] = $cat->get_name();
|
||||
}
|
||||
|
||||
$mform = new \core_search\output\form\search(null, $customdata);
|
||||
|
||||
$data = $mform->get_data();
|
||||
@ -125,6 +135,10 @@ if (!empty($context) && $data) {
|
||||
$data->context = $context;
|
||||
}
|
||||
|
||||
if ($data && $cat instanceof \core_search\area_category) {
|
||||
$data->cat = $cat->get_name();
|
||||
}
|
||||
|
||||
// Set the page URL.
|
||||
$urlparams = array('page' => $page);
|
||||
if ($data) {
|
||||
@ -139,6 +153,11 @@ if ($data) {
|
||||
$urlparams['timestart'] = $data->timestart;
|
||||
$urlparams['timeend'] = $data->timeend;
|
||||
}
|
||||
|
||||
if ($cat instanceof \core_search\area_category) {
|
||||
$urlparams['cat'] = $cat->get_name();
|
||||
}
|
||||
|
||||
$url = new moodle_url('/search/index.php', $urlparams);
|
||||
$PAGE->set_url($url);
|
||||
|
||||
@ -160,7 +179,7 @@ if ($errorstr = $search->get_engine()->get_query_error()) {
|
||||
$mform->display();
|
||||
|
||||
if (!empty($results)) {
|
||||
echo $searchrenderer->render_results($results->results, $results->actualpage, $results->totalcount, $url);
|
||||
echo $searchrenderer->render_results($results->results, $results->actualpage, $results->totalcount, $url, $cat);
|
||||
|
||||
\core_search\manager::trigger_search_results_viewed([
|
||||
'q' => $data->q,
|
||||
|
120
search/tests/area_category_test.php
Normal file
120
search/tests/area_category_test.php
Normal file
@ -0,0 +1,120 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Area category unit tests.
|
||||
*
|
||||
* @package core_search
|
||||
* @copyright 2018 Dmitrii Metelkin <dmitriim@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Area category unit tests.
|
||||
*
|
||||
* @package core_search
|
||||
* @copyright 2018 Dmitrii Metelkin <dmitriim@catalyst-au.net>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class search_area_category_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* A helper function to get a mocked search area.
|
||||
* @param string $areaid
|
||||
*
|
||||
* @return \PHPUnit\Framework\MockObject\MockObject
|
||||
*/
|
||||
protected function get_mocked_area($areaid) {
|
||||
$builder = $this->getMockBuilder('\core_search\base');
|
||||
$builder->disableOriginalConstructor();
|
||||
$builder->setMethods(array('get_area_id'));
|
||||
$area = $builder->getMockForAbstractClass();
|
||||
$area->method('get_area_id')->willReturn($areaid);
|
||||
|
||||
return $area;
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper function to get a list of search areas.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_areas() {
|
||||
$areas = [];
|
||||
$areas[] = $this->get_mocked_area('area1');
|
||||
$areas[] = 'String';
|
||||
$areas[] = 1;
|
||||
$areas[] = '12';
|
||||
$areas[] = true;
|
||||
$areas[] = false;
|
||||
$areas[] = null;
|
||||
$areas[] = [$this->get_mocked_area('area2')];
|
||||
$areas[] = $this;
|
||||
$areas[] = new stdClass();
|
||||
$areas[] = $this->get_mocked_area('area3');
|
||||
$areas[] = $this->get_mocked_area('area4');
|
||||
|
||||
return $areas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test default values.
|
||||
*/
|
||||
public function test_default_values() {
|
||||
$category = new \core_search\area_category('test_name', 'test_visiblename');
|
||||
|
||||
$this->assertEquals('test_name', $category->get_name());
|
||||
$this->assertEquals('test_visiblename', $category->get_visiblename());
|
||||
$this->assertEquals(0, $category->get_order());
|
||||
$this->assertEquals([], $category->get_areas());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that all get functions work as expected.
|
||||
*/
|
||||
public function test_getters() {
|
||||
$category = new \core_search\area_category('test_name', 'test_visiblename', 4, $this->get_areas());
|
||||
|
||||
$this->assertEquals('test_name', $category->get_name());
|
||||
$this->assertEquals('test_visiblename', $category->get_visiblename());
|
||||
$this->assertEquals(4, $category->get_order());
|
||||
|
||||
$this->assertTrue(is_array($category->get_areas()));
|
||||
$this->assertCount(3, $category->get_areas());
|
||||
$this->assertTrue(key_exists('area1', $category->get_areas()));
|
||||
$this->assertTrue(key_exists('area3', $category->get_areas()));
|
||||
$this->assertTrue(key_exists('area4', $category->get_areas()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a list of areas could be set correctly.
|
||||
*/
|
||||
public function test_list_of_areas_could_be_set() {
|
||||
$category = new \core_search\area_category('test_name', 'test_visiblename');
|
||||
$this->assertEquals([], $category->get_areas());
|
||||
|
||||
$category->set_areas($this->get_areas());
|
||||
|
||||
$this->assertTrue(is_array($category->get_areas()));
|
||||
$this->assertCount(3, $category->get_areas());
|
||||
$this->assertTrue(key_exists('area1', $category->get_areas()));
|
||||
$this->assertTrue(key_exists('area3', $category->get_areas()));
|
||||
$this->assertTrue(key_exists('area4', $category->get_areas()));
|
||||
}
|
||||
|
||||
}
|
@ -157,4 +157,16 @@ class search_base_testcase extends advanced_testcase {
|
||||
$this->assertEquals('i/empty', $result->get_name());
|
||||
$this->assertEquals('moodle', $result->get_component());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test base search area category names.
|
||||
*/
|
||||
public function test_get_category_names() {
|
||||
$builder = $this->getMockBuilder('\core_search\base');
|
||||
$builder->disableOriginalConstructor();
|
||||
$stub = $builder->getMockForAbstractClass();
|
||||
|
||||
$expected = ['core-course-content'];
|
||||
$this->assertEquals($expected, $stub->get_category_names());
|
||||
}
|
||||
}
|
||||
|
@ -1210,4 +1210,83 @@ class search_manager_testcase extends advanced_testcase {
|
||||
// Confirm request table is now empty.
|
||||
$this->assertEquals(0, $DB->count_records('search_index_requests'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test search area categories.
|
||||
*/
|
||||
public function test_get_search_area_categories() {
|
||||
$categories = \core_search\manager::get_search_area_categories();
|
||||
|
||||
$this->assertTrue(is_array($categories));
|
||||
$this->assertTrue(count($categories) >= 4); // We always should have 4 core categories.
|
||||
$this->assertArrayHasKey('core-all', $categories);
|
||||
$this->assertArrayHasKey('core-course-content', $categories);
|
||||
$this->assertArrayHasKey('core-courses', $categories);
|
||||
$this->assertArrayHasKey('core-users', $categories);
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$this->assertInstanceOf('\core_search\area_category', $category);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can find out if search area categories functionality is enabled.
|
||||
*/
|
||||
public function test_is_search_area_categories_enabled() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->assertFalse(\core_search\manager::is_search_area_categories_enabled());
|
||||
set_config('searchenablecategories', 1);
|
||||
$this->assertTrue(\core_search\manager::is_search_area_categories_enabled());
|
||||
set_config('searchenablecategories', 0);
|
||||
$this->assertFalse(\core_search\manager::is_search_area_categories_enabled());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can find out if hiding all results category is enabled.
|
||||
*/
|
||||
public function test_should_hide_all_results_category() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->assertEquals(0, \core_search\manager::should_hide_all_results_category());
|
||||
set_config('searchhideallcategory', 1);
|
||||
$this->assertEquals(1, \core_search\manager::should_hide_all_results_category());
|
||||
set_config('searchhideallcategory', 0);
|
||||
$this->assertEquals(0, \core_search\manager::should_hide_all_results_category());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can get default search category name.
|
||||
*/
|
||||
public function test_get_default_area_category_name() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$expected = 'core-all';
|
||||
$this->assertEquals($expected, \core_search\manager::get_default_area_category_name());
|
||||
|
||||
set_config('searchhideallcategory', 1);
|
||||
$expected = 'core-course-content';
|
||||
$this->assertEquals($expected, \core_search\manager::get_default_area_category_name());
|
||||
|
||||
set_config('searchhideallcategory', 0);
|
||||
$expected = 'core-all';
|
||||
$this->assertEquals($expected, \core_search\manager::get_default_area_category_name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can get correct search area category by its name.
|
||||
*/
|
||||
public function test_get_search_area_category_by_name() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$testcategory = \core_search\manager::get_search_area_category_by_name('test_random_name');
|
||||
$this->assertEquals('core-all', $testcategory->get_name());
|
||||
|
||||
$testcategory = \core_search\manager::get_search_area_category_by_name('core-courses');
|
||||
$this->assertEquals('core-courses', $testcategory->get_name());
|
||||
|
||||
set_config('searchhideallcategory', 1);
|
||||
$testcategory = \core_search\manager::get_search_area_category_by_name('test_random_name');
|
||||
$this->assertEquals('core-course-content', $testcategory->get_name());
|
||||
}
|
||||
}
|
||||
|
@ -216,4 +216,13 @@ class user extends \core_search\base {
|
||||
return new \core_search\document_icon('i/user');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of category names associated with the area.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_category_names() {
|
||||
return [\core_search\manager::SEARCH_AREA_CATEGORY_USERS];
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -229,4 +229,14 @@ class user_search_testcase extends advanced_testcase {
|
||||
$this->assertEquals('i/user', $result->get_name());
|
||||
$this->assertEquals('moodle', $result->get_component());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test assigned search categories.
|
||||
*/
|
||||
public function test_get_category_names() {
|
||||
$searcharea = \core_search\manager::get_search_area($this->userareaid);
|
||||
|
||||
$expected = ['core-users'];
|
||||
$this->assertEquals($expected, $searcharea->get_category_names());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user