first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,112 @@
<?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 core_question\output;
use core_question\local\bank\navigation_node_base;
use core_question\local\bank\plugin_features_base;
use moodle_url;
use renderer_base;
use templatable;
use renderable;
use url_select;
/**
* Rendered HTML elements for tertiary nav for Question bank.
*
* Provides a menu of links for question bank tertiary navigation, based on get_navigation_node() implemented by each plugin.
* Optionally includes and additional action button to display alongside the menu.
*
* @package core_question
* @copyright 2021 Sujith Haridasan <sujith@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class qbank_action_menu implements templatable, renderable {
/** @var moodle_url */
private $currenturl;
/** @var ?moodle_url $actionurl URL for additional action button */
protected ?moodle_url $actionurl = null;
/** @var ?string $actionlabel Label for additional action button */
protected ?string $actionlabel = null;
/**
* qbank_actionbar constructor.
*
* @param moodle_url $currenturl The current URL.
*/
public function __construct(moodle_url $currenturl) {
$this->currenturl = $currenturl;
}
/**
* Set the properties of an additional action button specific to the current page.
*
* @param moodle_url $url
* @param string $label
* @return void
*/
public function set_action_button(moodle_url $url, string $label): void {
$this->actionurl = $url;
$this->actionlabel = $label;
}
/**
* Provides the data for the template.
*
* @param renderer_base $output renderer_base object.
* @return array data for the template
*/
public function export_for_template(renderer_base $output): array {
$questionslink = new moodle_url('/question/edit.php', $this->currenturl->params());
$menu = [
$questionslink->out(false) => get_string('questions', 'question'),
];
$plugins = \core_component::get_plugin_list_with_class('qbank', 'plugin_feature', 'plugin_feature.php');
foreach ($plugins as $componentname => $pluginfeaturesclass) {
if (!\core\plugininfo\qbank::is_plugin_enabled($componentname)) {
continue;
}
/** @var plugin_features_base $pluginfeatures */
$pluginfeatures = new $pluginfeaturesclass();
$navigationnode = $pluginfeatures->get_navigation_node();
if (is_null($navigationnode)) {
continue;
}
/** @var moodle_url $url */
$url = $navigationnode->get_navigation_url();
$url->params($this->currenturl->params());
$menu[$url->out(false)] = $navigationnode->get_navigation_title();
}
$actionbutton = null;
if ($this->actionurl) {
$actionbutton = [
'url' => $this->actionurl->out(false),
'label' => $this->actionlabel,
];
}
$urlselect = new url_select($menu, $this->currenturl->out(false), null, 'questionbankaction');
$urlselect->set_label(get_string('questionbanknavigation', 'question'), ['class' => 'accesshide']);
return [
'questionbankselect' => $urlselect->export_for_template($output),
'actionbutton' => $actionbutton
];
}
}
@@ -0,0 +1,142 @@
<?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 core_question\output;
use core\output\datafilter;
use renderer_base;
use stdClass;
/**
* Class for rendering filters on the base view.
*
* @package core_question
* @copyright 2021 Catalyst IT Australia Pty Ltd
* @author Tomo Tsuyuki <tomotsuyuki@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class question_bank_filter_ui extends datafilter {
/** @var int $perpage number of records per page. */
protected $perpage = 0;
/** @var array Parameters for the page URL. */
protected $pagevars;
/** @var array $searchconditions Searchconditions for the filter. */
/** @var array $additionalparams Conditino objects for the current filter. */
/** @var string $component Component for calling the fragment callback. */
/** @var string $callback Fragment callback. */
/** @var string $view View class name. */
/** @var int|null $cmid if in an activity, the cmid. */
/** @var array $extraparams Additional parameters used by view classes. */
/**
* Create a new datafilter
*
* @param \context $context The context of the course being displayed
* @param array $searchconditions Array of condition objects for the current filters
* @param array $additionalparams Additional display parameters
* @param string $component the component for the fragment
* @param string $callback the callback for the fragment
* @param string $view the view class
* @param ?string $tableregionid The ID of the region to update with the fragment
* @param ?int $cmid if in an activity, the cmid.
* @param array $pagevars current filter parameters
* @param array $extraparams additional parameters required for a particular view class.
*/
public function __construct(
\context $context,
protected array $searchconditions,
protected array $additionalparams,
protected string $component,
protected string $callback,
protected string $view,
?string $tableregionid = null,
protected ?int $cmid = null,
array $pagevars = [],
protected array $extraparams = []
) {
parent::__construct($context, $tableregionid);
if (array_key_exists('sortData', $pagevars)) {
foreach ($pagevars['sortData'] as $sortname => $sortorder) {
unset($pagevars['sortData'][$sortname]);
$pagevars['sortData'][str_replace('\\', '\\\\', $sortname)] = $sortorder;
}
}
$this->pagevars = $pagevars;
}
/**
* Get data for all filter types.
*
* @return array
*/
protected function get_filtertypes(): array {
$filtertypes = [];
foreach ($this->searchconditions as $searchcondition) {
$filtertypes[] = $this->get_filter_object(
$searchcondition->get_condition_key(),
$searchcondition->get_title(),
$searchcondition->allow_custom(),
$searchcondition->allow_multiple(),
$searchcondition->get_filter_class(),
$searchcondition->get_initial_values(),
$searchcondition->allow_empty(),
$searchcondition->get_filteroptions(),
$searchcondition->is_required(),
$searchcondition->get_join_list(),
);
}
return $filtertypes;
}
/**
* Export the renderer data in a mustache template friendly format.
*
* @param renderer_base $output Unused.
* @return stdClass Data in a format compatible with a mustache template.
*/
public function export_for_template(renderer_base $output): stdClass {
$defaultcategory = question_get_default_category($this->context->id);
$courseid = null;
if ($this->context->contextlevel == CONTEXT_COURSE) {
$courseid = $this->context->instanceid;
}
if (empty($courseid)) {
$courseid = $this->searchconditions['category']->get_course_id();
}
return (object) [
'tableregionid' => $this->tableregionid,
'courseid' => $courseid,
'filtertypes' => $this->get_filtertypes(),
'selected' => 'category',
'rownumber' => 1,
'categoryid' => $defaultcategory->id,
'perpage' => $this->additionalparams['perpage'] ?? 0,
'contextid' => $this->context->id,
'component' => $this->component,
'callback' => $this->callback,
'view' => str_replace('\\', '\\\\', $this->view),
'cmid' => $this->cmid ?? 0,
'pagevars' => json_encode($this->pagevars),
'extraparams' => json_encode($this->extraparams),
];
}
}
@@ -0,0 +1,115 @@
<?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 core_question\output;
use renderer_base;
/**
* Track and display question version information.
*
* This class handles rendering the question version information (the current version of the question, the total number of versions,
* and if the current version is the latest). It also tracks loaded question definitions that don't yet have the latest version
* loaded, and handles loading the latest version of all pending questions.
*
* @package core_question
* @copyright 2023 onwards Catalyst IT EU {@link https://catalyst-eu.net}
* @author Mark Johnson <mark.johnson@catalyst-eu.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class question_version_info implements \renderable, \templatable {
/**
* @var array List of definitions that don't know whether they are the latest version yet.
*/
public static array $pendingdefinitions = [];
/**
* @var int $version The current version number.
*/
public int $version;
/**
* @var ?int $latestversion The latest version number of this question.
*/
public ?int $latestversion;
/**
* @var bool $shortversion Are we displaying an abbreviation for "version" rather than the full word?
*/
protected bool $shortversion;
/**
* Store the current and latest versions of the question, and whether we want to abbreviate the output string.
*
* @param \question_definition $question
* @param bool $shortversion
*/
public function __construct(\question_definition $question, bool $shortversion = false) {
$this->version = $question->version;
$this->latestversion = $question->latestversion;
$this->shortversion = $shortversion;
}
/**
* Find and set the latest version of all pending question_definition objects.
*
* This will update all pending objects in one go, saving us having to do a query for each question.
*
* @return void
*/
public static function populate_latest_versions(): void {
global $DB;
$pendingentryids = array_map(fn($definition) => $definition->questionbankentryid, self::$pendingdefinitions);
[$insql, $params] = $DB->get_in_or_equal($pendingentryids);
$sql = "SELECT questionbankentryid, MAX(version) AS latestversion
FROM {question_versions}
WHERE questionbankentryid $insql
GROUP BY questionbankentryid";
$latestversions = $DB->get_records_sql_menu($sql, $params);
array_walk(self::$pendingdefinitions, function($definition) use ($latestversions) {
if (!isset($latestversions[$definition->questionbankentryid])) {
return;
}
$definition->set_latest_version($latestversions[$definition->questionbankentryid]);
unset(self::$pendingdefinitions[$definition->id]);
});
}
/**
* Return the question version info as a string, including the version number and whether this is the latest version.
*
* @param renderer_base $output
* @return array
* @throws \coding_exception
*/
public function export_for_template(renderer_base $output): array {
if (is_null($this->latestversion)) {
return [];
}
$identifier = 'versioninfo';
if ($this->version === $this->latestversion) {
$identifier .= 'latest';
}
if ($this->shortversion) {
$identifier = 'short' . $identifier;
}
return [
'versioninfo' => get_string($identifier, 'question', $this)
];
}
}
@@ -0,0 +1,91 @@
<?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 core_question\output;
use renderer_base;
use templatable;
use renderable;
use question_bank;
require_once($CFG->dirroot . '/question/engine/bank.php');
/**
* A UI widget to select other versions of a particular question.
*
* It will help plugins to enable version selection in locations like modal, page etc.
*
* @package core_question
* @copyright 2022 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 question_version_selection implements templatable, renderable {
/** @var string */
private $uniqueidentifier;
/** @var int */
private $currentselectedquestionid = null;
/**
* Constructor.
*
* @param string $uniqueidentifier unique identifier for the api usage.
* @param int $currentlyselectedquestionid selected question id in dropdown.
*/
protected function __construct(string $uniqueidentifier, int $currentlyselectedquestionid) {
$this->uniqueidentifier = $uniqueidentifier;
$this->currentselectedquestionid = $currentlyselectedquestionid;
}
/**
* Set the selected question id for the currently selected question.
*
* @param string $uniqueidentifier unique identifier for the api usage.
* @param int $currentlyselectedquestionid selected question id in dropdown.
* @return self an instance of this UI widget for the given question.
*/
public static function make_for_question(string $uniqueidentifier, int $currentlyselectedquestionid): self {
return new self($uniqueidentifier, $currentlyselectedquestionid);
}
/**
* Export the data for version selection mustache.
*
* @param renderer_base $output renderer of the output
* @return array
*/
public function export_for_template(renderer_base $output): array {
$displaydata = [];
$versionsoptions = question_bank::get_all_versions_of_question($this->currentselectedquestionid);
foreach ($versionsoptions as $versionsoption) {
$versionsoption->selected = false;
$a = new \stdClass();
$a->version = $versionsoption->version;
$versionsoption->name = get_string('version_selection', 'core_question', $a);
if ($versionsoption->questionid == $this->currentselectedquestionid) {
$versionsoption->selected = true;
}
$displaydata[] = $versionsoption;
}
return [
'options' => $displaydata,
'uniqueidentifier' => $this->uniqueidentifier,
];
}
}