MDL-60913 search: add search area categories
[moodle.git] / search / classes / output / form / search.php
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/>.
17 /**
18  * Global search search form definition
19  *
20  * @package   core_search
21  * @copyright Prateek Sachan {@link http://prateeksachan.com}
22  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 namespace core_search\output\form;
27 defined('MOODLE_INTERNAL') || die;
29 require_once($CFG->libdir . '/formslib.php');
30 require_once($CFG->libdir . '/externallib.php');
32 class search extends \moodleform {
34     /**
35      * Form definition.
36      *
37      * @return void
38      */
39     function definition() {
40         global $USER, $DB, $OUTPUT;
42         $mform =& $this->_form;
44         if (\core_search\manager::is_search_area_categories_enabled() && !empty($this->_customdata['cat'])) {
45             $mform->addElement('hidden', 'cat');
46             $mform->setType('cat', PARAM_NOTAGS);
47             $mform->setDefault('cat', $this->_customdata['cat']);
48         }
50         $mform->disable_form_change_checker();
51         $mform->addElement('header', 'search', get_string('search', 'search'));
53         // Help info depends on the selected search engine.
54         $mform->addElement('text', 'q', get_string('enteryoursearchquery', 'search'));
55         $mform->addHelpButton('q', 'searchinfo', $this->_customdata['searchengine']);
56         $mform->setType('q', PARAM_TEXT);
57         $mform->addRule('q', get_string('required'), 'required', null, 'client');
59         // Show the 'search within' option if the user came from a particular context.
60         if (!empty($this->_customdata['searchwithin'])) {
61             $mform->addElement('select', 'searchwithin', get_string('searchwithin', 'search'),
62                     $this->_customdata['searchwithin']);
63             $mform->setDefault('searchwithin', '');
64         }
66         // If the search engine provides multiple ways to order results, show options.
67         if (!empty($this->_customdata['orderoptions']) &&
68                 count($this->_customdata['orderoptions']) > 1) {
70             $mform->addElement('select', 'order', get_string('order', 'search'),
71                     $this->_customdata['orderoptions']);
72             $mform->setDefault('order', 'relevance');
73         }
75         $mform->addElement('header', 'filtersection', get_string('filterheader', 'search'));
76         $mform->setExpanded('filtersection', false);
78         $mform->addElement('text', 'title', get_string('title', 'search'));
79         $mform->setType('title', PARAM_TEXT);
81         $search = \core_search\manager::instance(true);
82         $enabledsearchareas = \core_search\manager::get_search_areas_list(true);
83         $areanames = array();
85         if (\core_search\manager::is_search_area_categories_enabled() && !empty($this->_customdata['cat'])) {
86             $searchareacategory = \core_search\manager::get_search_area_category_by_name($this->_customdata['cat']);
87             $searchareas = $searchareacategory->get_areas();
88             foreach ($searchareas as $areaid => $searcharea) {
89                 if (key_exists($areaid, $enabledsearchareas)) {
90                     $areanames[$areaid] = $searcharea->get_visible_name();
91                 }
92             }
93         } else {
94             foreach ($enabledsearchareas as $areaid => $searcharea) {
95                 $areanames[$areaid] = $searcharea->get_visible_name();
96             }
97         }
99         // Sort the array by the text.
100         \core_collator::asort($areanames);
102         $options = array(
103             'multiple' => true,
104             'noselectionstring' => get_string('allareas', 'search'),
105         );
106         $mform->addElement('autocomplete', 'areaids', get_string('searcharea', 'search'), $areanames, $options);
108         $options = array(
109             'multiple' => true,
110             'limittoenrolled' => !is_siteadmin(),
111             'noselectionstring' => get_string('allcourses', 'search'),
112         );
113         $mform->addElement('course', 'courseids', get_string('courses', 'core'), $options);
114         $mform->setType('courseids', PARAM_INT);
116         // If the search engine can search by user, and the user is logged in (so we have
117         // permission to call the user-listing web service) then show the user selector.
118         if ($search->get_engine()->supports_users() && isloggedin()) {
119             $options = [
120                 'ajax' => 'core_search/form-search-user-selector',
121                 'multiple' => true,
122                 'noselectionstring' => get_string('allusers', 'search'),
123                 'valuehtmlcallback' => function($value) {
124                     global $DB, $OUTPUT;
125                     $user = $DB->get_record('user', ['id' => (int)$value], '*', IGNORE_MISSING);
126                     if (!$user || !user_can_view_profile($user)) {
127                         return false;
128                     }
129                     $details = user_get_user_details($user);
130                     return $OUTPUT->render_from_template(
131                             'core_search/form-user-selector-suggestion', $details);
132                 }
133             ];
134             if (!empty($this->_customdata['withincourseid'])) {
135                 $options['withincourseid'] = $this->_customdata['withincourseid'];
136             }
138             $mform->addElement('autocomplete', 'userids', get_string('users'), [], $options);
139         }
141         if (!empty($this->_customdata['searchwithin'])) {
142             // Course options should be hidden if we choose to search within a specific location.
143             $mform->hideIf('courseids', 'searchwithin', 'ne', '');
145             // Get groups on course (we don't show group selector if there aren't any).
146             $courseid = $this->_customdata['withincourseid'];
147             $allgroups = groups_get_all_groups($courseid);
148             if ($allgroups && $search->get_engine()->supports_group_filtering()) {
149                 $groupnames = [];
150                 foreach ($allgroups as $group) {
151                     $groupnames[$group->id] = $group->name;
152                 }
154                 // Create group autocomplete option.
155                 $options = array(
156                         'multiple' => true,
157                         'noselectionstring' => get_string('allgroups'),
158                 );
159                 $mform->addElement('autocomplete', 'groupids', get_string('groups'), $groupnames, $options);
161                 // Is the second 'search within' option a cm?
162                 if (!empty($this->_customdata['withincmid'])) {
163                     // Find out if the cm supports groups.
164                     $modinfo = get_fast_modinfo($courseid);
165                     $cm = $modinfo->get_cm($this->_customdata['withincmid']);
166                     if ($cm->effectivegroupmode != NOGROUPS) {
167                         // If it does, group ids are available when you have course or module selected.
168                         $mform->hideIf('groupids', 'searchwithin', 'eq', '');
169                     } else {
170                         // Group ids are only available if you have course selected.
171                         $mform->hideIf('groupids', 'searchwithin', 'ne', 'course');
172                     }
173                 } else {
174                     $mform->hideIf('groupids', 'searchwithin', 'eq', '');
175                 }
176             }
177         }
179         $mform->addElement('date_time_selector', 'timestart', get_string('fromtime', 'search'), array('optional' => true));
180         $mform->setDefault('timestart', 0);
182         $mform->addElement('date_time_selector', 'timeend', get_string('totime', 'search'), array('optional' => true));
183         $mform->setDefault('timeend', 0);
185         // Source context i.e. the page they came from when they clicked search.
186         $mform->addElement('hidden', 'context');
187         $mform->setType('context', PARAM_INT);
189         $this->add_action_buttons(false, get_string('search', 'search'));
190     }