Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | 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 core_question;
18
 
19
use core_question\local\bank\question_version_status;
20
 
21
/**
22
 * This class should provide an API for managing question_references.
23
 *
24
 * Unfortunately, question_references were introduced in the DB structure
25
 * without an nice API. This class is being added later, and is currently
26
 * terribly incomplete, but hopefully it can be improved in time.
27
 *
28
 * @package    core_question
29
 * @copyright  2023 The Open University
30
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
31
 */
32
class question_reference_manager {
33
    /**
34
     * Return a list of those questions from the list passed in, which are referenced.
35
     *
36
     * A question is referenced if either:
37
     * - There is a question_reference pointing at exactly that version of that question; or
38
     * - There is an 'always latest' reference, and the question id is the latest non-draft version
39
     *   of that question_bank_entry.
40
     *
41
     * @param array $questionids a list of question ids to check.
42
     * @return array a list of the question ids from the input array which are referenced.
43
     */
44
    public static function questions_with_references(array $questionids): array {
45
        global $DB;
46
 
47
        if (empty($questionids)) {
48
            return [];
49
        }
50
 
51
        [$qidtest, $params] = $DB->get_in_or_equal($questionids, SQL_PARAMS_NAMED, 'outerqid');
52
        [$lqidtest, $lparams] = $DB->get_in_or_equal($questionids, SQL_PARAMS_NAMED, 'innerqid');
53
 
54
        return $DB->get_fieldset_sql("
55
            SELECT qv.questionid
56
 
57
              FROM {question_versions} qv
58
 
59
         -- This is a performant to get the latest non-draft version for each
60
         -- question_bank_entry that relates to one of our questionids.
61
         LEFT JOIN (
62
                       SELECT lqv.questionbankentryid,
63
                              MAX(lv.version) AS latestusableversion
64
                         FROM {question_versions} lqv
65
                         JOIN {question_versions} lv ON lv.questionbankentryid = lqv.questionbankentryid
66
                        WHERE lqv.questionid $lqidtest
67
                          AND lv.status <> :draft
68
                     GROUP BY lqv.questionbankentryid
69
                   ) latestversions ON latestversions.questionbankentryid = qv.questionbankentryid
70
 
71
              JOIN {question_references} qr ON qr.questionbankentryid = qv.questionbankentryid
72
                       AND (qr.version = qv.version OR qr.version IS NULL AND qv.version = latestversions.latestusableversion)
73
 
74
             WHERE qv.questionid $qidtest
75
            ", array_merge($params, $lparams, ['draft' => question_version_status::QUESTION_STATUS_DRAFT]));
76
    }
77
 
78
    /**
79
     * This will transform set reference filter conditions to use the new filter structure.
80
     *
81
     * Previously filterconditions had questioncategoryid, includesubcategories and tags options.
82
     * These have been replaced by the new category and tags filters. This function convers the old
83
     * pre-4.3 filter condition structure to the new one.
84
     *
85
     * @param array $filtercondition Pre-4.3 filter condition.
86
     * @return array Post-4.3 filter condition.
87
     */
88
    public static function convert_legacy_set_reference_filter_condition(array $filtercondition): array {
1441 ariadna 89
        global $DB;
1 efrain 90
        if (!isset($filtercondition['filter'])) {
91
            $filtercondition['filter'] = [];
92
 
93
            // Question category filter.
94
            if (isset($filtercondition['questioncategoryid'])) {
95
                $filtercondition['filter']['category'] = [
96
                    'jointype' => \qbank_managecategories\category_condition::JOINTYPE_DEFAULT,
97
                    'values' => [$filtercondition['questioncategoryid']],
98
                    'filteroptions' => ['includesubcategories' => $filtercondition['includingsubcategories']],
99
                ];
100
            }
101
 
102
            // Tag filters.
103
            if (isset($filtercondition['tags'])) {
104
                // Get the names of the tags in the condition. Find or create corresponding tags,
105
                // and set their ids in the new condition.
106
                $oldtags = array_map(fn($oldtag) => explode(',', $oldtag)[1], $filtercondition['tags']);
1441 ariadna 107
                $questiontagcollid = \core_tag_area::get_collection('core_question', 'question');
108
                $newtags = \core_tag_tag::create_if_missing($questiontagcollid, $oldtags);
1 efrain 109
                $newtagids = array_map(fn($newtag) => $newtag->id, $newtags);
110
 
111
                $filtercondition['filter']['qtagids'] = [
112
                    'jointype' => \qbank_tagquestion\tag_condition::JOINTYPE_DEFAULT,
113
                    'values' => array_values($newtagids),
114
                ];
115
                unset($filtercondition['tags']);
116
            }
117
            // Add additional default properties to the filtercondition.
1441 ariadna 118
            if (isset($filtercondition['questioncategoryid'])) {
119
                $category = $DB->get_record('question_categories', ['id' => $filtercondition['questioncategoryid']]);
120
                if ($category) {
121
                    $filtercondition['cat'] = "{$category->id},{$category->contextid}";
122
                } else {
123
                    $filtercondition['cat'] = '';
124
                }
125
            }
1 efrain 126
            $filtercondition['tabname'] = 'questions';
127
            $filtercondition['qpage'] = 0;
128
            $filtercondition['qperpage'] = 100;
129
            $filtercondition['jointype'] = \core\output\datafilter::JOINTYPE_ALL;
1441 ariadna 130
            unset($filtercondition['questioncategoryid']);
131
            unset($filtercondition['includingsubcategories']);
1 efrain 132
        } else if (isset($filtercondition['filter']['category']['includesubcategories'])) {
133
            $filtercondition['filter']['category']['filteroptions'] =
134
                ['includesubcategories' => $filtercondition['filter']['category']['includesubcategories']];
135
            unset($filtercondition['filter']['category']['includesubcategories']);
136
        }
137
        return $filtercondition;
138
    }
139
}