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 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 {
89
        if (!isset($filtercondition['filter'])) {
90
            $filtercondition['filter'] = [];
91
 
92
            // Question category filter.
93
            if (isset($filtercondition['questioncategoryid'])) {
94
                $filtercondition['filter']['category'] = [
95
                    'jointype' => \qbank_managecategories\category_condition::JOINTYPE_DEFAULT,
96
                    'values' => [$filtercondition['questioncategoryid']],
97
                    'filteroptions' => ['includesubcategories' => $filtercondition['includingsubcategories']],
98
                ];
99
                unset($filtercondition['questioncategoryid']);
100
                unset($filtercondition['includingsubcategories']);
101
            }
102
 
103
            // Tag filters.
104
            if (isset($filtercondition['tags'])) {
105
                // Get the names of the tags in the condition. Find or create corresponding tags,
106
                // and set their ids in the new condition.
107
                $oldtags = array_map(fn($oldtag) => explode(',', $oldtag)[1], $filtercondition['tags']);
108
                $newtags = \core_tag_tag::create_if_missing(1, $oldtags);
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.
118
            $filtercondition['tabname'] = 'questions';
119
            $filtercondition['qpage'] = 0;
120
            $filtercondition['qperpage'] = 100;
121
            $filtercondition['jointype'] = \core\output\datafilter::JOINTYPE_ALL;
122
        } else if (isset($filtercondition['filter']['category']['includesubcategories'])) {
123
            $filtercondition['filter']['category']['filteroptions'] =
124
                ['includesubcategories' => $filtercondition['filter']['category']['includesubcategories']];
125
            unset($filtercondition['filter']['category']['includesubcategories']);
126
        }
127
        return $filtercondition;
128
    }
129
}