Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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/>.
16
 
17
namespace qbank_managecategories;
18
 
19
use core\output\datafilter;
20
use core_question\local\bank\condition;
21
use core_question\local\bank\view;
22
 
23
/**
24
 * This class controls from which category questions are listed.
25
 *
26
 * @package   qbank_managecategories
27
 * @copyright 2013 Ray Morris
28
 * @author    2021 Safat Shahin <safatshahin@catalyst-au.net>
29
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30
 */
31
class category_condition extends condition {
32
    /** @var \stdClass The course record. */
33
    protected $course;
34
 
35
    /** @var \stdClass The category record. */
36
    protected $category;
37
 
38
    /** @var array of contexts. */
39
    protected $contexts;
40
 
41
    /** @var string categoryID,contextID as used with question_bank_view->display(). */
42
    protected $cat;
43
 
44
    /** @var int The maximum displayed length of the category info. */
45
    public $maxinfolength;
46
 
47
    /** @var bool Include questions in subcategories of the specified category? */
48
    public $includesubcategories;
49
 
50
    /**
51
     * Constructor to initialize the category filter condition.
52
     *
53
     * @param view $qbank qbank view
54
     */
55
    public function __construct(view $qbank = null) {
56
        if (is_null($qbank)) {
57
            return;
58
        }
59
        $this->cat = $qbank->get_pagevars('cat');
60
        $this->contexts = $qbank->contexts->having_one_edit_tab_cap($qbank->get_pagevars('tabname'));
61
        $this->course = $qbank->course;
62
 
63
        [$categoryid, $contextid] = self::validate_category_param($this->cat);
64
        if (is_null($categoryid)) {
65
            return;
66
        }
67
 
68
        $this->category = self::get_category_record($categoryid, $contextid);
69
 
70
        parent::__construct($qbank);
71
        $this->includesubcategories = $this->filter['filteroptions']['includesubcategories'] ?? false;
72
    }
73
 
74
    /**
75
     * Return default category
76
     *
77
     * @return \stdClass default category
78
     */
79
    public function get_default_category(): \stdClass {
80
        if (empty($this->category)) {
81
            return question_get_default_category(\context_course::instance($this->course->id)->id);
82
        }
83
 
84
        return $this->category;
85
    }
86
 
87
    public static function get_condition_key() {
88
        return 'category';
89
    }
90
 
91
    /**
92
     * Returns course id.
93
     *
94
     * @return string Course id.
95
     */
96
    public function get_course_id() {
97
        return $this->course->id;
98
    }
99
 
100
    /**
101
     * Called by question_bank_view to display the GUI for selecting a category
102
     * @deprecated since Moodle 4.3 MDL-72321 - please do not use this function any more.
103
     * @todo Final deprecation on Moodle 4.7 MDL-78090
104
     */
105
    public function display_options() {
106
        debugging('Function display_options() is deprecated, please use filtering objects', DEBUG_DEVELOPER);
107
        global $PAGE;
108
        $displaydata = [];
109
        $catmenu = helper::question_category_options($this->contexts, true, 0,
110
                true, -1, false);
111
        $displaydata['categoryselect'] = \html_writer::select($catmenu, 'category', $this->cat, [],
112
                array('class' => 'searchoptions custom-select', 'id' => 'id_selectacategory'));
113
        $displaydata['categorydesc'] = '';
114
        if ($this->category) {
115
            $displaydata['categorydesc'] = $this->print_category_info($this->category);
116
        }
117
        return $PAGE->get_renderer('qbank_managecategories')->render_category_condition($displaydata);
118
    }
119
 
120
    /**
121
     * Displays the recursion checkbox GUI.
122
     * question_bank_view places this within the section that is hidden by default
123
     * @deprecated since Moodle 4.3 MDL-72321 - please do not use this function any more.
124
     * @todo Final deprecation on Moodle 4.7 MDL-78090
125
     */
126
    public function display_options_adv() {
127
        debugging('Function display_options_adv() is deprecated, please use filtering objects', DEBUG_DEVELOPER);
128
        global $PAGE;
129
        $displaydata = [];
130
        if ($this->recurse) {
131
            $displaydata['checked'] = 'checked';
132
        }
133
        return $PAGE->get_renderer('qbank_managecategories')->render_category_condition_advanced($displaydata);
134
    }
135
 
136
    /**
137
     * Display the drop down to select the category.
138
     *
139
     * @param array $contexts of contexts that can be accessed from here.
140
     * @param \moodle_url $pageurl the URL of this page.
141
     * @param string $current 'categoryID,contextID'.
142
     * @deprecated since Moodle 4.3
143
     * @todo Final deprecation on Moodle 4.7 MDL-78090
144
     */
145
    protected function display_category_form($contexts, $pageurl, $current) {
146
        debugging(
147
            'Function display_category_form() is deprecated, please use the core_question renderer instead.',
148
            DEBUG_DEVELOPER
149
        );
150
        echo \html_writer::start_div('choosecategory');
151
        $catmenu = question_category_options($contexts, true, 0, true, -1, false);
152
        echo \html_writer::label(get_string('selectacategory', 'question'), 'id_selectacategory', true, ["class" => "mr-1"]);
153
        echo \html_writer::select($catmenu, 'category', $current, [],
154
                array('class' => 'searchoptions custom-select', 'id' => 'id_selectacategory'));
155
        echo \html_writer::end_div() . "\n";
156
    }
157
 
158
    /**
159
     * Print the text if category id not available.
160
     * @deprecated since Moodle 4.3
161
     * @todo Final deprecation in Moodle 4.7 MDL-78090
162
     */
163
    public static function print_choose_category_message(): void {
164
        debugging(
165
            'Function print_choose_category_message() is deprecated, please use ' .
166
                'qbank_managecategories/choose_category template instead.',
167
            DEBUG_DEVELOPER
168
        );
169
        global $OUTPUT;
170
        echo $OUTPUT->render_from_template('qbank_managecategories/choose_category', []);
171
    }
172
 
173
    /**
174
     * Look up the category record based on category ID and context
175
     * @param string $categoryandcontext categoryID,contextID as used with question_bank_view->display()
176
     * @return \stdClass The category record
177
     * @deprecated since Moodle 4.3
178
     * @todo Final deprecation in Moodle 4.7 MDL-78090
179
     */
180
    public static function get_current_category($categoryandcontext) {
181
        debugging('Function get_current_category() is deprecated. Please do not use it anymore.', DEBUG_DEVELOPER);
182
        global $DB, $OUTPUT;
183
        [$categoryid, $contextid] = explode(',', $categoryandcontext);
184
        if (!$categoryid) {
185
            self::print_choose_category_message();
186
            return false;
187
        }
188
 
189
        if (!$category = $DB->get_record('question_categories', ['id' => $categoryid, 'contextid' => $contextid])) {
190
            echo $OUTPUT->box_start('generalbox questionbank');
191
            echo $OUTPUT->notification('Category not found!');
192
            echo $OUTPUT->box_end();
193
            return false;
194
        }
195
 
196
        return $category;
197
    }
198
 
199
    /**
200
     * Return category and context ID from compound parameter.
201
     *
202
     * @param string $categoryandcontext Comma-separated list of category and context IDs.
203
     * @return int[]|null[]
204
     */
205
    public static function validate_category_param(string $categoryandcontext): array {
206
        [$categoryid, $contextid] = explode(',', $categoryandcontext);
207
        if (!$categoryid) {
208
            return [null, null];
209
        }
210
        return [clean_param($categoryid, PARAM_INT), clean_param($contextid, PARAM_INT)];
211
    }
212
 
213
    /**
214
     * Fetch the question category record matching the provided category and context IDs.
215
     *
216
     * @param int $categoryid
217
     * @param int $contextid
218
     * @return \stdClass
219
     * @throws \dml_exception
220
     */
221
    public static function get_category_record($categoryid, $contextid): \stdClass {
222
        global $DB;
223
        return $DB->get_record('question_categories',
224
                ['id' => $categoryid, 'contextid' => $contextid],
225
                '*',
226
                MUST_EXIST);
227
    }
228
 
229
    /**
230
     * Print the category description
231
     * @param \stdClass $category the category information form the database.
232
     * @deprecated since Moodle 4.3 MDL-72321 - please do not use this function any more.
233
     * @todo Final deprecation on Moodle 4.7 MDL-78090
234
     */
235
    protected function print_category_info($category): string {
236
        debugging('Function print_category_info() is deprecated. Please do not use it anymore', DEBUG_DEVELOPER);
237
        $formatoptions = new \stdClass();
238
        $formatoptions->noclean = true;
239
        $formatoptions->overflowdiv = true;
240
        if (isset($this->maxinfolength)) {
241
            return shorten_text(format_text($category->info, $category->infoformat, $formatoptions, $this->course->id),
242
                    $this->maxinfolength);
243
        }
244
 
245
        return format_text($category->info, $category->infoformat, $formatoptions, $this->course->id);
246
    }
247
 
248
    public static function build_query_from_filter(array $filter): array {
249
        global $DB;
250
        $recursive = false;
251
        if (isset($filter['filteroptions']['includesubcategories'])) {
252
            $recursive = (bool)$filter['filteroptions']['includesubcategories'];
253
        }
254
 
255
        // Sub categories.
256
        if ($recursive) {
257
            $categories = $filter['values'];
258
            $categoriesandsubcategories = [];
259
            foreach ($categories as $categoryid) {
260
                $categoriesandsubcategories += question_categorylist($categoryid);
261
            }
262
        } else {
263
            $categoriesandsubcategories = $filter['values'];
264
        }
265
 
266
        $jointype = $filter['jointype'] ?? self::JOINTYPE_DEFAULT;
267
        $equal = !($jointype === datafilter::JOINTYPE_NONE);
268
        [$insql, $params] = $DB->get_in_or_equal($categoriesandsubcategories, SQL_PARAMS_NAMED, 'cat', $equal);
269
        $where = 'qbe.questioncategoryid ' . $insql;
270
        return [$where, $params];
271
    }
272
 
273
    public function get_title() {
274
        return get_string('category', 'core_question');
275
    }
276
 
277
    public function get_filter_class() {
278
        return 'qbank_managecategories/datafilter/filtertypes/categories';
279
    }
280
 
281
    public function allow_custom() {
282
        return false;
283
    }
284
 
285
    public function allow_multiple() {
286
        return false;
287
    }
288
 
289
    public function allow_empty() {
290
        return false;
291
    }
292
 
293
    public function get_join_list(): array {
294
        return [
295
                datafilter::JOINTYPE_ANY,
296
        ];
297
    }
298
 
299
    public function get_initial_values() {
300
        $catmenu = helper::question_category_options($this->contexts, true, 0, true, -1, false);
301
        $values = [];
302
        foreach ($catmenu as $menu) {
303
            foreach ($menu as $heading => $catlist) {
304
                $values[] = (object) [
305
                    // Add a list item for each question category context. This will serve as a "heading" within the list
306
                    // and we will use CSS to disable pointer events so it cannot be selected.
307
                    'value' => '',
308
                    'title' => $heading,
309
                    'disabled' => true,
310
                    'classes' => 'suggestions-heading',
311
                ];
312
                foreach ($catlist as $key => $value) {
313
                    $values[] = (object) [
314
                        // Remove contextid from value.
315
                        'value' => str_contains($key, ',') ? substr($key, 0, strpos($key, ',')) : $key,
316
                        'title' => $value,
317
                        'selected' => ($key === $this->cat),
318
                    ];
319
                }
320
            }
321
        }
322
        return $values;
323
    }
324
 
325
    public function get_filteroptions(): \stdClass {
326
        return (object)[
327
            'includesubcategories' => $this->includesubcategories,
328
        ];
329
    }
330
 
331
    public function is_required(): bool {
332
        return true;
333
    }
334
}