mirror of
https://github.com/moodle/moodle.git
synced 2025-04-22 00:42:54 +02:00
Merge branch 'MDL-30592' of git://github.com/timhunt/moodle
This commit is contained in:
commit
12727710d4
@ -7770,35 +7770,48 @@ function get_list_of_plugins($directory='mod', $exclude='', $basedir='') {
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* invoke plugin's callback functions
|
||||
*
|
||||
* @param string $type Plugin type e.g. 'mod'
|
||||
* @param string $name Plugin name
|
||||
* @param string $feature Feature name
|
||||
* @param string $action Feature's action
|
||||
* @param array $params parameters of callback function, should be an array
|
||||
* @param mixed $default default value if callback function hasn't been defined, or if it retursn null.
|
||||
* @return mixed
|
||||
*/
|
||||
function plugin_callback($type, $name, $feature, $action, $params = null, $default = null) {
|
||||
return component_callback($type . '_' . $name, $feature . '_' . $action, (array) $params, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* invoke plugin's callback functions
|
||||
*
|
||||
* @param string $type Plugin type e.g. 'mod'
|
||||
* @param string $name Plugin name
|
||||
* @param string $feature Feature name
|
||||
* @param string $action Feature's action
|
||||
* @param string $options parameters of callback function, should be an array
|
||||
* @param mixed $default default value if callback function hasn't been defined
|
||||
* @param string $component frankenstyle component name, e.g. 'mod_quiz'
|
||||
* @param string $function the rest of the function name, e.g. 'cron' will end up calling 'mod_quiz_cron'
|
||||
* @param array $params parameters of callback function
|
||||
* @param mixed $default default value if callback function hasn't been defined, or if it retursn null.
|
||||
* @return mixed
|
||||
*/
|
||||
function plugin_callback($type, $name, $feature, $action, $options = null, $default=null) {
|
||||
function component_callback($component, $function, array $params = array(), $default = null) {
|
||||
global $CFG; // this is needed for require_once() bellow
|
||||
|
||||
$component = clean_param($type . '_' . $name, PARAM_COMPONENT);
|
||||
if (empty($component)) {
|
||||
throw new coding_exception('Invalid component used in plugin_callback():' . $type . '_' . $name);
|
||||
$cleancomponent = clean_param($component, PARAM_COMPONENT);
|
||||
if (empty($cleancomponent)) {
|
||||
throw new coding_exception('Invalid component used in plugin_callback():' . $component);
|
||||
}
|
||||
$component = $cleancomponent;
|
||||
|
||||
list($type, $name) = normalize_component($component);
|
||||
$component = $type . '_' . $name;
|
||||
|
||||
$function = $component.'_'.$feature.'_'.$action;
|
||||
$oldfunction = $name.'_'.$feature.'_'.$action;
|
||||
$oldfunction = $name.'_'.$function;
|
||||
$function = $component.'_'.$function;
|
||||
|
||||
$dir = get_component_directory($component);
|
||||
if (empty($dir)) {
|
||||
throw new coding_exception('Invalid component used in plugin_callback():' . $type . '_' . $name);
|
||||
throw new coding_exception('Invalid component used in plugin_callback():' . $component);
|
||||
}
|
||||
|
||||
// Load library and look for function
|
||||
@ -7815,7 +7828,7 @@ function plugin_callback($type, $name, $feature, $action, $options = null, $defa
|
||||
|
||||
if (function_exists($function)) {
|
||||
// Function exists, so just return function result
|
||||
$ret = call_user_func_array($function, (array)$options);
|
||||
$ret = call_user_func_array($function, $params);
|
||||
if (is_null($ret)) {
|
||||
return $default;
|
||||
} else {
|
||||
|
@ -1636,10 +1636,7 @@ class question_edit_contexts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite question url, file_rewrite_pluginfile_urls always build url by
|
||||
* $file/$contextid/$component/$filearea/$itemid/$pathname_in_text, so we cannot add
|
||||
* extra questionid and attempted in url by it, so we create quiz_rewrite_question_urls
|
||||
* to build url here
|
||||
* Helps call file_rewrite_pluginfile_urls with the right parameters.
|
||||
*
|
||||
* @param string $text text being processed
|
||||
* @param string $file the php script used to serve files
|
||||
@ -1653,32 +1650,59 @@ class question_edit_contexts {
|
||||
*/
|
||||
function question_rewrite_question_urls($text, $file, $contextid, $component,
|
||||
$filearea, array $ids, $itemid, array $options=null) {
|
||||
global $CFG;
|
||||
|
||||
$options = (array)$options;
|
||||
if (!isset($options['forcehttps'])) {
|
||||
$options['forcehttps'] = false;
|
||||
}
|
||||
|
||||
if (!$CFG->slasharguments) {
|
||||
$file = $file . '?file=';
|
||||
}
|
||||
|
||||
$baseurl = "$CFG->wwwroot/$file/$contextid/$component/$filearea/";
|
||||
|
||||
$idsstr = '';
|
||||
if (!empty($ids)) {
|
||||
$baseurl .= (implode('/', $ids) . '/');
|
||||
$idsstr .= implode('/', $ids);
|
||||
}
|
||||
|
||||
if ($itemid !== null) {
|
||||
$baseurl .= "$itemid/";
|
||||
$idsstr .= '/' . $itemid;
|
||||
}
|
||||
return file_rewrite_pluginfile_urls($text, $file, $contextid, $component,
|
||||
$filearea, $idsstr, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite the PLUGINFILE urls in the questiontext, when viewing the question
|
||||
* text outside and attempt (for example, in the question bank listing or in the
|
||||
* quiz statistics report).
|
||||
*
|
||||
* @param string $questiontext the question text.
|
||||
* @param int $contextid the context the text is being displayed in.
|
||||
* @param string $component component
|
||||
* @param array $ids other IDs will be used to check file permission
|
||||
* @param array $options
|
||||
* @return string $questiontext with URLs rewritten.
|
||||
*/
|
||||
function question_rewrite_questiontext_preview_urls($questiontext, $contextid,
|
||||
$component, $questionid, $options=null) {
|
||||
|
||||
return file_rewrite_pluginfile_urls($questiontext, 'pluginfile.php', $contextid,
|
||||
'question', 'questiontext_preview', "$component/$questionid", $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a file from the question text of a question.
|
||||
* @param int $questionid the question id
|
||||
* @param array $args the remaining file arguments (file path).
|
||||
* @param bool $forcedownload whether the user must be forced to download the file.
|
||||
*/
|
||||
function question_send_questiontext_file($questionid, $args, $forcedownload) {
|
||||
global $DB;
|
||||
|
||||
$question = $DB->get_record_sql('
|
||||
SELECT q.id, qc.contextid
|
||||
FROM {question} q
|
||||
JOIN {question_categories} qc ON qc.id = q.category
|
||||
WHERE q.id = :id', array('id' => $questionid), MUST_EXIST);
|
||||
|
||||
$fs = get_file_storage();
|
||||
$fullpath = "/$question->contextid/question/questiontext/$question->id/" . implode('/', $args);
|
||||
if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
if ($options['forcehttps']) {
|
||||
$baseurl = str_replace('http://', 'https://', $baseurl);
|
||||
}
|
||||
|
||||
return str_replace('@@PLUGINFILE@@/', $baseurl, $text);
|
||||
send_stored_file($file, 0, 0, $forcedownload);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1704,6 +1728,16 @@ function question_rewrite_question_urls($text, $file, $contextid, $component,
|
||||
function question_pluginfile($course, $context, $component, $filearea, $args, $forcedownload) {
|
||||
global $DB, $CFG;
|
||||
|
||||
if ($filearea === 'questiontext_preview') {
|
||||
$component = array_shift($args);
|
||||
$questionid = array_shift($args);
|
||||
|
||||
component_callback($component, 'questiontext_preview_pluginfile', array(
|
||||
$context, $questionid, $args, $forcedownload));
|
||||
|
||||
send_file_not_found();
|
||||
}
|
||||
|
||||
list($context, $course, $cm) = get_context_info_array($context->id);
|
||||
require_login($course, false, $cm);
|
||||
|
||||
@ -1793,6 +1827,33 @@ function question_pluginfile($course, $context, $component, $filearea, $args, $f
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serve questiontext files in the question text when they are displayed in this report.
|
||||
* @param context $context the context
|
||||
* @param int $questionid the question id
|
||||
* @param array $args remaining file args
|
||||
* @param bool $forcedownload
|
||||
*/
|
||||
function core_question_questiontext_preview_pluginfile($context, $questionid, $args, $forcedownload) {
|
||||
global $DB;
|
||||
|
||||
// Verify that contextid matches the question.
|
||||
$question = $DB->get_record_sql('
|
||||
SELECT q.*, qc.contextid
|
||||
FROM {question} q
|
||||
JOIN {question_categories} qc ON qc.id = q.category
|
||||
WHERE q.id = :id AND qc.contextid = :contextid',
|
||||
array('id' => $questionid, 'contextid' => $context->id), MUST_EXIST);
|
||||
|
||||
// Check the capability.
|
||||
list($context, $course, $cm) = get_context_info_array($context->id);
|
||||
require_login($course, false, $cm);
|
||||
|
||||
question_require_capability_on($question, 'use');
|
||||
|
||||
question_send_questiontext_file($questionid, $args, $forcedownload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create url for question export
|
||||
*
|
||||
|
46
mod/quiz/report/statistics/lib.php
Normal file
46
mod/quiz/report/statistics/lib.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Standard plugin entry points of the quiz statistics report.
|
||||
*
|
||||
* @package quiz
|
||||
* @subpackage statistics
|
||||
* @copyright 2011 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Serve questiontext files in the question text when they are displayed in this report.
|
||||
* @param context $context the context
|
||||
* @param int $questionid the question id
|
||||
* @param array $args remaining file args
|
||||
* @param bool $forcedownload
|
||||
*/
|
||||
function quiz_statistics_questiontext_preview_pluginfile($context, $questionid, $args, $forcedownload) {
|
||||
global $CFG;
|
||||
require_once($CFG->dirroot . '/mod/quiz/locallib.php');
|
||||
|
||||
list($context, $course, $cm) = get_context_info_array($context->id);
|
||||
require_login($course, false, $cm);
|
||||
|
||||
// Assume only trusted people can see this report. There is no real way to
|
||||
// validate questionid, becuase of the complexity of random quetsions.
|
||||
require_capability('quiz/statistics:view', $context);
|
||||
|
||||
question_send_questiontext_file($questionid, $args, $forcedownload);
|
||||
}
|
@ -54,7 +54,7 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
public function display($quiz, $cm, $course) {
|
||||
global $CFG, $DB, $OUTPUT, $PAGE;
|
||||
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
$this->context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
|
||||
// Work out the display options.
|
||||
$download = optional_param('download', '', PARAM_ALPHA);
|
||||
@ -97,7 +97,7 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
|
||||
} else {
|
||||
// All users who can attempt quizzes and who are in the currently selected group
|
||||
$groupstudents = get_users_by_capability($context,
|
||||
$groupstudents = get_users_by_capability($this->context,
|
||||
array('mod/quiz:reviewmyattempts', 'mod/quiz:attempt'),
|
||||
'', '', '', '', $currentgroup, '', false);
|
||||
if (!$groupstudents) {
|
||||
@ -163,7 +163,7 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
}
|
||||
|
||||
if (!quiz_questions_in_quiz($quiz->questions)) {
|
||||
echo quiz_no_questions_message($quiz, $cm, $context);
|
||||
echo quiz_no_questions_message($quiz, $cm, $this->context);
|
||||
} else if (!$this->table->is_downloading() && $s == 0) {
|
||||
echo $OUTPUT->notification(get_string('noattempts', 'quiz'));
|
||||
}
|
||||
@ -320,15 +320,33 @@ class quiz_statistics_report extends quiz_default_report {
|
||||
echo $OUTPUT->heading(get_string('questionstatistics', 'quiz_statistics'));
|
||||
echo html_writer::table($questionstatstable);
|
||||
}
|
||||
public function format_text($text, $format, $qa, $component, $filearea, $itemid,
|
||||
$clean = false) {
|
||||
$formatoptions = new stdClass();
|
||||
$formatoptions->noclean = !$clean;
|
||||
$formatoptions->para = false;
|
||||
$text = $qa->rewrite_pluginfile_urls($text, $component, $filearea, $itemid);
|
||||
return format_text($text, $format, $formatoptions);
|
||||
}
|
||||
|
||||
/** @return the result of applying {@link format_text()} to the question text. */
|
||||
public function format_questiontext($qa) {
|
||||
return $this->format_text($this->questiontext, $this->questiontextformat,
|
||||
$qa, 'question', 'questiontext', $this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $question question data.
|
||||
* @return string HTML of question text, ready for display.
|
||||
*/
|
||||
protected function render_question_text($question){
|
||||
protected function render_question_text($question) {
|
||||
global $OUTPUT;
|
||||
return $OUTPUT->box(format_text($question->questiontext, $question->questiontextformat,
|
||||
array('overflowdiv' => true)),
|
||||
|
||||
$text = question_rewrite_questiontext_preview_urls($question->questiontext,
|
||||
$this->context->id, 'quiz_statistics', $question->id);
|
||||
|
||||
return $OUTPUT->box(format_text($text, $question->questiontextformat,
|
||||
array('noclean' => true, 'para' => false, 'overflowdiv' => true)),
|
||||
'questiontext boxaligncenter generalbox boxwidthnormal mdl-align');
|
||||
}
|
||||
|
||||
|
@ -791,16 +791,22 @@ class question_bank_question_text_row extends question_bank_row_base {
|
||||
}
|
||||
|
||||
protected function display_content($question, $rowclasses) {
|
||||
$text = format_text($question->questiontext, $question->questiontextformat,
|
||||
$this->formatoptions, $this->qbank->get_courseid());
|
||||
$text = question_rewrite_questiontext_preview_urls($question->questiontext,
|
||||
$question->contextid, 'question', $question->id);
|
||||
$text = format_text($text, $question->questiontextformat,
|
||||
$this->formatoptions);
|
||||
if ($text == '') {
|
||||
$text = ' ';
|
||||
}
|
||||
echo $text;
|
||||
}
|
||||
|
||||
public function get_extra_joins() {
|
||||
return array('qc' => 'JOIN {question_categories} qc ON qc.id = q.category');
|
||||
}
|
||||
|
||||
public function get_required_fields() {
|
||||
return array('q.questiontext', 'q.questiontextformat');
|
||||
return array('q.id', 'q.questiontext', 'q.questiontextformat', 'qc.contextid');
|
||||
}
|
||||
}
|
||||
|
||||
@ -1100,10 +1106,10 @@ class question_bank_view {
|
||||
}
|
||||
|
||||
/// Build the where clause.
|
||||
$tests = array('parent = 0');
|
||||
$tests = array('q.parent = 0');
|
||||
|
||||
if (!$showhidden) {
|
||||
$tests[] = 'hidden = 0';
|
||||
$tests[] = 'q.hidden = 0';
|
||||
}
|
||||
|
||||
if ($recurse) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user