���ѧۧݧ�ӧ�� �ާ֧ߧ֧էا֧� - ���֧էѧܧ�ڧ��ӧѧ�� - /home3/cpr76684/public_html/question.tar
���ѧ٧ѧ�
bank/question_name_text_column.php 0000644 00000004034 15152170444 0013464 0 ustar 00 <?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/>. namespace mod_quiz\question\bank; /** * A column type for the name followed by the start of the question text. * * @package mod_quiz * @category question * @copyright 2009 Tim Hunt * @author 2021 Safat Shahin <safatshahin@catalyst-au.net> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class question_name_text_column extends question_name_column { public function get_name(): string { return 'questionnametext'; } protected function display_content($question, $rowclasses): void { echo \html_writer::start_tag('div'); $labelfor = $this->label_for($question); if ($labelfor) { echo \html_writer::start_tag('label', ['for' => $labelfor]); } echo quiz_question_tostring($question, false, true, true, $question->tags); if ($labelfor) { echo \html_writer::end_tag('label'); } echo \html_writer::end_tag('div'); } public function get_required_fields(): array { $fields = parent::get_required_fields(); $fields[] = 'q.questiontext'; $fields[] = 'q.questiontextformat'; $fields[] = 'qbe.idnumber'; return $fields; } public function load_additional_data(array $questions) { parent::load_additional_data($questions); parent::load_question_tags($questions); } } bank/qbank_helper.php 0000644 00000027465 15152170444 0010644 0 ustar 00 <?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/>. namespace mod_quiz\question\bank; use core_question\local\bank\question_version_status; use core_question\local\bank\random_question_loader; use qubaid_condition; defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot . '/mod/quiz/accessmanager.php'); require_once($CFG->dirroot . '/mod/quiz/attemptlib.php'); /** * Helper class for question bank and its associated data. * * @package mod_quiz * @category question * @copyright 2021 Catalyst IT Australia Pty Ltd * @author Safat Shahin <safatshahin@catalyst-au.net> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class qbank_helper { /** * Get the available versions of a question where one of the version has the given question id. * * @param int $questionid id of a question. * @return \stdClass[] other versions of this question. Each object has fields versionid, * version and questionid. Array is returned most recent version first. */ public static function get_version_options(int $questionid): array { global $DB; return $DB->get_records_sql(" SELECT allversions.id AS versionid, allversions.version, allversions.questionid FROM {question_versions} allversions WHERE allversions.questionbankentryid = ( SELECT givenversion.questionbankentryid FROM {question_versions} givenversion WHERE givenversion.questionid = ? ) AND allversions.status <> ? ORDER BY allversions.version DESC ", [$questionid, question_version_status::QUESTION_STATUS_DRAFT]); } /** * Get the information about which questions should be used to create a quiz attempt. * * Each element in the returned array is indexed by slot.slot (slot number) an each object hass: * - All the field of the slot table. * - contextid for where the question(s) come from. * - category id for where the questions come from. * - For non-random questions, All the fields of the question table (but id is in questionid). * Also question version and question bankentryid. * - For random questions, filtercondition, which is also unpacked into category, randomrecurse, * randomtags, and note that these also have a ->name set and ->qtype set to 'random'. * * @param int $quizid the id of the quiz to load the data for. * @param \context_module $quizcontext the context of this quiz. * @param int|null $slotid optional, if passed only load the data for this one slot (if it is in this quiz). * @return array indexed by slot, with information about the content of each slot. */ public static function get_question_structure(int $quizid, \context_module $quizcontext, int $slotid = null): array { global $DB; $params = [ 'draft' => question_version_status::QUESTION_STATUS_DRAFT, 'quizcontextid' => $quizcontext->id, 'quizcontextid2' => $quizcontext->id, 'quizcontextid3' => $quizcontext->id, 'quizid' => $quizid, 'quizid2' => $quizid, ]; $slotidtest = ''; $slotidtest2 = ''; if ($slotid !== null) { $params['slotid'] = $slotid; $params['slotid2'] = $slotid; $slotidtest = ' AND slot.id = :slotid'; $slotidtest2 = ' AND lslot.id = :slotid2'; } // Load all the data about each slot. $slotdata = $DB->get_records_sql(" SELECT slot.slot, slot.id AS slotid, slot.page, slot.maxmark, slot.requireprevious, qsr.filtercondition, qv.status, qv.id AS versionid, qv.version, qr.version AS requestedversion, qv.questionbankentryid, q.id AS questionid, q.*, qc.id AS category, COALESCE(qc.contextid, qsr.questionscontextid) AS contextid FROM {quiz_slots} slot -- case where a particular question has been added to the quiz. LEFT JOIN {question_references} qr ON qr.usingcontextid = :quizcontextid AND qr.component = 'mod_quiz' AND qr.questionarea = 'slot' AND qr.itemid = slot.id LEFT JOIN {question_bank_entries} qbe ON qbe.id = qr.questionbankentryid -- This way of getting the latest version for each slot is a bit more complicated -- than we would like, but the simpler SQL did not work in Oracle 11.2. -- (It did work fine in Oracle 19.x, so once we have updated our min supported -- version we could consider digging the old code out of git history from -- just before the commit that added this comment. -- For relevant question_bank_entries, this gets the latest non-draft slot number. LEFT JOIN ( SELECT lv.questionbankentryid, MAX(CASE WHEN lv.status <> :draft THEN lv.version END) AS usableversion, MAX(lv.version) AS anyversion FROM {quiz_slots} lslot JOIN {question_references} lqr ON lqr.usingcontextid = :quizcontextid2 AND lqr.component = 'mod_quiz' AND lqr.questionarea = 'slot' AND lqr.itemid = lslot.id JOIN {question_versions} lv ON lv.questionbankentryid = lqr.questionbankentryid WHERE lslot.quizid = :quizid2 $slotidtest2 AND lqr.version IS NULL GROUP BY lv.questionbankentryid ) latestversions ON latestversions.questionbankentryid = qr.questionbankentryid LEFT JOIN {question_versions} qv ON qv.questionbankentryid = qbe.id -- Either specified version, or latest usable version, or a draft version. AND qv.version = COALESCE(qr.version, latestversions.usableversion, latestversions.anyversion) LEFT JOIN {question_categories} qc ON qc.id = qbe.questioncategoryid LEFT JOIN {question} q ON q.id = qv.questionid -- Case where a random question has been added. LEFT JOIN {question_set_references} qsr ON qsr.usingcontextid = :quizcontextid3 AND qsr.component = 'mod_quiz' AND qsr.questionarea = 'slot' AND qsr.itemid = slot.id WHERE slot.quizid = :quizid $slotidtest ORDER BY slot.slot ", $params); // Unpack the random info from question_set_reference. foreach ($slotdata as $slot) { // Ensure the right id is the id. $slot->id = $slot->slotid; if ($slot->filtercondition) { // Unpack the information about a random question. $filtercondition = json_decode($slot->filtercondition); $slot->questionid = 's' . $slot->id; // Sometimes this is used as an array key, so needs to be unique. $slot->category = $filtercondition->questioncategoryid; $slot->randomrecurse = (bool) $filtercondition->includingsubcategories; $slot->randomtags = isset($filtercondition->tags) ? (array) $filtercondition->tags : []; $slot->qtype = 'random'; $slot->name = get_string('random', 'quiz'); $slot->length = 1; } else if ($slot->qtype === null) { // This question must have gone missing. Put in a placeholder. $slot->questionid = 's' . $slot->id; // Sometimes this is used as an array key, so needs to be unique. $slot->category = 0; $slot->qtype = 'missingtype'; $slot->name = get_string('missingquestion', 'quiz'); $slot->questiontext = ' '; $slot->questiontextformat = FORMAT_HTML; $slot->length = 1; } else if (!\question_bank::qtype_exists($slot->qtype)) { // Question of unknown type found in the database. Set to placeholder question types instead. $slot->qtype = 'missingtype'; } else { $slot->_partiallyloaded = 1; } } return $slotdata; } /** * Get this list of random selection tag ids from one of the slots returned by get_question_structure. * * @param \stdClass $slotdata one of the array elements returned by get_question_structure. * @return array list of tag ids. */ public static function get_tag_ids_for_slot(\stdClass $slotdata): array { $tagids = []; foreach ($slotdata->randomtags as $taginfo) { [$id] = explode(',', $taginfo, 2); $tagids[] = $id; } return $tagids; } /** * Given a slot from the array returned by get_question_structure, describe the random question it represents. * * @param \stdClass $slotdata one of the array elements returned by get_question_structure. * @return string that can be used to display the random slot. */ public static function describe_random_question(\stdClass $slotdata): string { global $DB; $category = $DB->get_record('question_categories', ['id' => $slotdata->category]); return \question_bank::get_qtype('random')->question_name( $category, $slotdata->randomrecurse, $slotdata->randomtags); } /** * Choose question for redo in a particular slot. * * @param int $quizid the id of the quiz to load the data for. * @param \context_module $quizcontext the context of this quiz. * @param int $slotid optional, if passed only load the data for this one slot (if it is in this quiz). * @param qubaid_condition $qubaids attempts to consider when avoiding picking repeats of random questions. * @return int the id of the question to use. */ public static function choose_question_for_redo(int $quizid, \context_module $quizcontext, int $slotid, qubaid_condition $qubaids): int { $slotdata = self::get_question_structure($quizid, $quizcontext, $slotid); $slotdata = reset($slotdata); // Non-random question. if ($slotdata->qtype != 'random') { return $slotdata->questionid; } // Random question. $randomloader = new random_question_loader($qubaids, []); $newqusetionid = $randomloader->get_next_question_id($slotdata->category, $slotdata->randomrecurse, self::get_tag_ids_for_slot($slotdata)); if ($newqusetionid === null) { throw new \moodle_exception('notenoughrandomquestions', 'quiz'); } return $newqusetionid; } } bank/add_action_column.php 0000644 00000003142 15152170444 0011635 0 ustar 00 <?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/>. namespace mod_quiz\question\bank; /** * A column type for the add this question to the quiz action. * * @package mod_quiz * @category question * @copyright 2009 Tim Hunt * @author 2021 Safat Shahin <safatshahin@catalyst-au.net> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class add_action_column extends \core_question\local\bank\action_column_base { /** @var string caches a lang string used repeatedly. */ protected $stradd; public function init(): void { parent::init(); $this->stradd = get_string('addtoquiz', 'quiz'); } public function get_name() { return 'addtoquizaction'; } protected function display_content($question, $rowclasses) { if (!question_has_capability_on($question, 'use')) { return; } $this->print_icon('t/add', $this->stradd, $this->qbank->add_to_quiz_url($question->id)); } } bank/question_name_column.php 0000644 00000004256 15152170444 0012426 0 ustar 00 <?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/>. namespace mod_quiz\question\bank; /** * A column type for the name of the question name. * * @package mod_quiz * @category question * @copyright 2009 Tim Hunt * @author 2021 Safat Shahin <safatshahin@catalyst-au.net> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class question_name_column extends \core_question\local\bank\column_base { /** * @var null $checkboxespresent */ protected $checkboxespresent = null; public function get_name(): string { return 'questionname'; } public function get_title(): string { return get_string('question'); } protected function label_for($question): string { if (is_null($this->checkboxespresent)) { $this->checkboxespresent = $this->qbank->has_column('core_question\local\bank\checkbox_column'); } if ($this->checkboxespresent) { return 'checkq' . $question->id; } else { return ''; } } protected function display_content($question, $rowclasses): void { $labelfor = $this->label_for($question); if ($labelfor) { echo \html_writer::start_tag('label', ['for' => $labelfor]); } echo format_string($question->name); if ($labelfor) { echo \html_writer::end_tag('label'); } } public function get_required_fields(): array { return ['q.id', 'q.name']; } public function is_sortable() { return 'q.name'; } } bank/custom_view.php 0000644 00000032216 15152170444 0010543 0 ustar 00 <?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/>. /** * Defines the custom question bank view used on the Edit quiz page. * * @package mod_quiz * @category question * @copyright 1999 onwards Martin Dougiamas and others {@link http://moodle.com} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace mod_quiz\question\bank; use core_question\local\bank\question_version_status; use mod_quiz\question\bank\filter\custom_category_condition; /** * Subclass to customise the view of the question bank for the quiz editing screen. * * @copyright 2009 Tim Hunt * @author 2021 Safat Shahin <safatshahin@catalyst-au.net> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class custom_view extends \core_question\local\bank\view { /** @var int number of questions per page to show in the add from question bank modal. */ const DEFAULT_PAGE_SIZE = 20; /** @var bool $quizhasattempts whether the quiz this is used by has been attemptd. */ protected $quizhasattempts = false; /** @var \stdClass $quiz the quiz settings. */ protected $quiz = false; /** @var int The maximum displayed length of the category info. */ const MAX_TEXT_LENGTH = 200; /** * Constructor. * @param \core_question\local\bank\question_edit_contexts $contexts * @param \moodle_url $pageurl * @param \stdClass $course course settings * @param \stdClass $cm activity settings. * @param \stdClass $quiz quiz settings. */ public function __construct($contexts, $pageurl, $course, $cm, $quiz) { parent::__construct($contexts, $pageurl, $course, $cm); $this->quiz = $quiz; $this->pagesize = self::DEFAULT_PAGE_SIZE; } protected function get_question_bank_plugins(): array { $questionbankclasscolumns = []; $corequestionbankcolumns = [ 'add_action_column', 'checkbox_column', 'question_type_column', 'question_name_text_column', 'preview_action_column' ]; if (question_get_display_preference('qbshowtext', 0, PARAM_INT, new \moodle_url(''))) { $corequestionbankcolumns[] = 'question_text_row'; } foreach ($corequestionbankcolumns as $fullname) { $shortname = $fullname; if (class_exists('mod_quiz\\question\\bank\\' . $fullname)) { $fullname = 'mod_quiz\\question\\bank\\' . $fullname; $questionbankclasscolumns[$shortname] = new $fullname($this); } else if (class_exists('core_question\\local\\bank\\' . $fullname)) { $fullname = 'core_question\\local\\bank\\' . $fullname; $questionbankclasscolumns[$shortname] = new $fullname($this); } else { $questionbankclasscolumns[$shortname] = ''; } } $plugins = \core_component::get_plugin_list_with_class('qbank', 'plugin_feature', 'plugin_feature.php'); foreach ($plugins as $componentname => $plugin) { $pluginentrypointobject = new $plugin(); $plugincolumnobjects = $pluginentrypointobject->get_question_columns($this); // Don't need the plugins without column objects. if (empty($plugincolumnobjects)) { unset($plugins[$componentname]); continue; } foreach ($plugincolumnobjects as $columnobject) { $columnname = $columnobject->get_column_name(); foreach ($corequestionbankcolumns as $key => $corequestionbankcolumn) { if (!\core\plugininfo\qbank::is_plugin_enabled($componentname)) { unset($questionbankclasscolumns[$columnname]); continue; } // Check if it has custom preference selector to view/hide. if ($columnobject->has_preference() && !$columnobject->get_preference()) { continue; } if ($corequestionbankcolumn === $columnname) { $questionbankclasscolumns[$columnname] = $columnobject; } } } } // Mitigate the error in case of any regression. foreach ($questionbankclasscolumns as $shortname => $questionbankclasscolumn) { if (empty($questionbankclasscolumn)) { unset($questionbankclasscolumns[$shortname]); } } return $questionbankclasscolumns; } protected function heading_column(): string { return 'mod_quiz\\question\\bank\\question_name_text_column'; } protected function default_sort(): array { // Using the extended class for quiz specific sort. return [ 'qbank_viewquestiontype\\question_type_column' => 1, 'mod_quiz\\question\\bank\\question_name_text_column' => 1, ]; } /** * Let the question bank display know whether the quiz has been attempted, * hence whether some bits of UI, like the add this question to the quiz icon, * should be displayed. * * @param bool $quizhasattempts whether the quiz has attempts. */ public function set_quiz_has_attempts($quizhasattempts): void { $this->quizhasattempts = $quizhasattempts; if ($quizhasattempts && isset($this->visiblecolumns['addtoquizaction'])) { unset($this->visiblecolumns['addtoquizaction']); } } /** * Question preview url. * * @param \stdClass $question * @return \moodle_url */ public function preview_question_url($question) { return quiz_question_preview_url($this->quiz, $question); } /** * URL of add to quiz. * * @param $questionid * @return \moodle_url */ public function add_to_quiz_url($questionid) { $params = $this->baseurl->params(); $params['addquestion'] = $questionid; $params['sesskey'] = sesskey(); return new \moodle_url('/mod/quiz/edit.php', $params); } /** * Renders the html question bank (same as display, but returns the result). * * Note that you can only output this rendered result once per page, as * it contains IDs which must be unique. * * @param array $pagevars * @param string $tabname * @return string HTML code for the form */ public function render($pagevars, $tabname): string { ob_start(); $this->display($pagevars, $tabname); $out = ob_get_contents(); ob_end_clean(); return $out; } protected function display_bottom_controls(\context $catcontext): void { $cmoptions = new \stdClass(); $cmoptions->hasattempts = !empty($this->quizhasattempts); $canuseall = has_capability('moodle/question:useall', $catcontext); echo \html_writer::start_tag('div', ['class' => 'pt-2']); if ($canuseall) { // Add selected questions to the quiz. $params = array( 'type' => 'submit', 'name' => 'add', 'class' => 'btn btn-primary', 'value' => get_string('addselectedquestionstoquiz', 'quiz'), 'data-action' => 'toggle', 'data-togglegroup' => 'qbank', 'data-toggle' => 'action', 'disabled' => true, ); echo \html_writer::empty_tag('input', $params); } echo \html_writer::end_tag('div'); } protected function create_new_question_form($category, $canadd): void { // Don't display this. } /** * Override the base implementation in \core_question\local\bank\view * because we don't want to print the headers in the fragment * for the modal. */ protected function display_question_bank_header(): void { } /** * Override the base implementation in \core_question\bank\view * because we don't want it to read from the $_POST global variables * for the sort parameters since they are not present in a fragment. * * Unfortunately the best we can do is to look at the URL for * those parameters (only marginally better really). */ protected function init_sort_from_params(): void { $this->sort = []; for ($i = 1; $i <= self::MAX_SORTS; $i++) { if (!$sort = $this->baseurl->param('qbs' . $i)) { break; } // Work out the appropriate order. $order = 1; if ($sort[0] == '-') { $order = -1; $sort = substr($sort, 1); if (!$sort) { break; } } // Deal with subsorts. list($colname) = $this->parse_subsort($sort); $this->get_column_type($colname); $this->sort[$sort] = $order; } } protected function build_query(): void { // Get the required tables and fields. $joins = []; $fields = ['qv.status', 'qc.id as categoryid', 'qv.version', 'qv.id as versionid', 'qbe.id as questionbankentryid']; if (!empty($this->requiredcolumns)) { foreach ($this->requiredcolumns as $column) { $extrajoins = $column->get_extra_joins(); foreach ($extrajoins as $prefix => $join) { if (isset($joins[$prefix]) && $joins[$prefix] != $join) { throw new \coding_exception('Join ' . $join . ' conflicts with previous join ' . $joins[$prefix]); } $joins[$prefix] = $join; } $fields = array_merge($fields, $column->get_required_fields()); } } $fields = array_unique($fields); // Build the order by clause. $sorts = []; foreach ($this->sort as $sort => $order) { list($colname, $subsort) = $this->parse_subsort($sort); $sorts[] = $this->requiredcolumns[$colname]->sort_expression($order < 0, $subsort); } // Build the where clause. $latestversion = 'qv.version = (SELECT MAX(v.version) FROM {question_versions} v JOIN {question_bank_entries} be ON be.id = v.questionbankentryid WHERE be.id = qbe.id)'; $readyonly = "qv.status = '" . question_version_status::QUESTION_STATUS_READY . "' "; $tests = ['q.parent = 0', $latestversion, $readyonly]; $this->sqlparams = []; foreach ($this->searchconditions as $searchcondition) { if ($searchcondition->where()) { $tests[] = '((' . $searchcondition->where() .'))'; } if ($searchcondition->params()) { $this->sqlparams = array_merge($this->sqlparams, $searchcondition->params()); } } // Build the SQL. $sql = ' FROM {question} q ' . implode(' ', $joins); $sql .= ' WHERE ' . implode(' AND ', $tests); $this->countsql = 'SELECT count(1)' . $sql; $this->loadsql = 'SELECT ' . implode(', ', $fields) . $sql . ' ORDER BY ' . implode(', ', $sorts); } public function wanted_filters($cat, $tagids, $showhidden, $recurse, $editcontexts, $showquestiontext): void { global $CFG; list(, $contextid) = explode(',', $cat); $catcontext = \context::instance_by_id($contextid); $thiscontext = $this->get_most_specific_context(); // Category selection form. $this->display_question_bank_header(); // Display tag filter if usetags setting is enabled/enablefilters is true. if ($this->enablefilters) { if (is_array($this->customfilterobjects)) { foreach ($this->customfilterobjects as $filterobjects) { $this->searchconditions[] = $filterobjects; } } else { if ($CFG->usetags) { array_unshift($this->searchconditions, new \core_question\bank\search\tag_condition([$catcontext, $thiscontext], $tagids)); } array_unshift($this->searchconditions, new \core_question\bank\search\hidden_condition(!$showhidden)); array_unshift($this->searchconditions, new custom_category_condition( $cat, $recurse, $editcontexts, $this->baseurl, $this->course)); } } $this->display_options_form($showquestiontext); } } bank/filter/custom_category_condition_helper.php 0000644 00000013307 15152170444 0016300 0 ustar 00 <?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/>. namespace mod_quiz\question\bank\filter; use core_question\local\bank\question_version_status; /** * A custom filter condition helper for quiz to select question categories. * * This is required as quiz will only use ready questions and the count should show according to that. * * @package mod_quiz * @category question * @copyright 2021 Catalyst IT Australia Pty Ltd * @author Safat Shahin <safatshahin@catalyst-au.net> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class custom_category_condition_helper extends \qbank_managecategories\helper { public static function question_category_options(array $contexts, bool $top = false, int $currentcat = 0, bool $popupform = false, int $nochildrenof = -1, bool $escapecontextnames = true): array { global $CFG; $pcontexts = []; foreach ($contexts as $context) { $pcontexts[] = $context->id; } $contextslist = join(', ', $pcontexts); $categories = self::get_categories_for_contexts($contextslist, 'parent, sortorder, name ASC', $top); if ($top) { $categories = self::question_fix_top_names($categories); } $categories = self::question_add_context_in_key($categories); $categories = self::add_indented_names($categories, $nochildrenof); // Sort cats out into different contexts. $categoriesarray = []; foreach ($pcontexts as $contextid) { $context = \context::instance_by_id($contextid); $contextstring = $context->get_context_name(true, true, $escapecontextnames); foreach ($categories as $category) { if ($category->contextid == $contextid) { $cid = $category->id; if ($currentcat != $cid || $currentcat == 0) { $a = new \stdClass; $a->name = format_string($category->indentedname, true, ['context' => $context]); if ($category->idnumber !== null && $category->idnumber !== '') { $a->idnumber = s($category->idnumber); } if (!empty($category->questioncount)) { $a->questioncount = $category->questioncount; } if (isset($a->idnumber) && isset($a->questioncount)) { $formattedname = get_string('categorynamewithidnumberandcount', 'question', $a); } else if (isset($a->idnumber)) { $formattedname = get_string('categorynamewithidnumber', 'question', $a); } else if (isset($a->questioncount)) { $formattedname = get_string('categorynamewithcount', 'question', $a); } else { $formattedname = $a->name; } $categoriesarray[$contextstring][$cid] = $formattedname; } } } } if ($popupform) { $popupcats = []; foreach ($categoriesarray as $contextstring => $optgroup) { $group = []; foreach ($optgroup as $key => $value) { $key = str_replace($CFG->wwwroot, '', $key); $group[$key] = $value; } $popupcats[] = [$contextstring => $group]; } return $popupcats; } else { return $categoriesarray; } } public static function get_categories_for_contexts($contexts, string $sortorder = 'parent, sortorder, name ASC', bool $top = false, int $showallversions = 0): array { global $DB; $topwhere = $top ? '' : 'AND c.parent <> 0'; $statuscondition = "AND qv.status = '". question_version_status::QUESTION_STATUS_READY . "' "; $sql = "SELECT c.*, (SELECT COUNT(1) FROM {question} q JOIN {question_versions} qv ON qv.questionid = q.id JOIN {question_bank_entries} qbe ON qbe.id = qv.questionbankentryid WHERE q.parent = '0' $statuscondition AND c.id = qbe.questioncategoryid AND ($showallversions = 1 OR (qv.version = (SELECT MAX(v.version) FROM {question_versions} v JOIN {question_bank_entries} be ON be.id = v.questionbankentryid WHERE be.id = qbe.id) ) ) ) AS questioncount FROM {question_categories} c WHERE c.contextid IN ($contexts) $topwhere ORDER BY $sortorder"; return $DB->get_records_sql($sql); } } bank/filter/custom_category_condition.php 0000644 00000003610 15152170444 0014735 0 ustar 00 <?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/>. namespace mod_quiz\question\bank\filter; /** * A custom filter condition for quiz to select question categories. * * This is required as quiz will only use ready questions and the count should show according to that. * * @package mod_quiz * @category question * @copyright 2021 Catalyst IT Australia Pty Ltd * @author Safat Shahin <safatshahin@catalyst-au.net> * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class custom_category_condition extends \core_question\bank\search\category_condition { public function display_options() { global $PAGE; $displaydata = []; $catmenu = custom_category_condition_helper::question_category_options($this->contexts, true, 0, true, -1, false); $displaydata['categoryselect'] = \html_writer::select($catmenu, 'category', $this->cat, [], ['class' => 'searchoptions custom-select', 'id' => 'id_selectacategory']); $displaydata['categorydesc'] = ''; if ($this->category) { $displaydata['categorydesc'] = $this->print_category_info($this->category); } return $PAGE->get_renderer('core_question', 'bank')->render_category_condition($displaydata); } } qubaids_for_users_attempts.php 0000644 00000005141 15152170444 0012721 0 ustar 00 <?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/>. /** * A {@link qubaid_condition} representing all the attempts by one user at a given quiz. * * @package mod_quiz * @category question * @copyright 2015 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace mod_quiz\question; defined('MOODLE_INTERNAL') || die(); require_once($CFG->dirroot.'/mod/quiz/attemptlib.php'); /** * A {@link qubaid_condition} representing all the attempts by one user at a given quiz. * * @copyright 2015 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class qubaids_for_users_attempts extends \qubaid_join { /** * Constructor. * * This takes the same arguments as {@link quiz_get_user_attempts()}. * * @param int $quizid the quiz id. * @param int $userid the userid. * @param string $status 'all', 'finished' or 'unfinished' to control * @param bool $includepreviews defaults to false. */ public function __construct($quizid, $userid, $status = 'finished', $includepreviews = false) { $where = 'quiza.quiz = :quizaquiz AND quiza.userid = :userid'; $params = array('quizaquiz' => $quizid, 'userid' => $userid); if (!$includepreviews) { $where .= ' AND preview = 0'; } switch ($status) { case 'all': break; case 'finished': $where .= ' AND state IN (:state1, :state2)'; $params['state1'] = \quiz_attempt::FINISHED; $params['state2'] = \quiz_attempt::ABANDONED; break; case 'unfinished': $where .= ' AND state IN (:state1, :state2)'; $params['state1'] = \quiz_attempt::IN_PROGRESS; $params['state2'] = \quiz_attempt::OVERDUE; break; } parent::__construct('{quiz_attempts} quiza', 'quiza.uniqueid', $where, $params); } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | ���֧ߧ֧�ѧ�ڧ� ����ѧߧڧ��: 0 |
proxy
|
phpinfo
|
���ѧ����ۧܧ�