mirror of
https://github.com/moodle/moodle.git
synced 2025-03-22 00:20:37 +01:00
MDL-54945 workshop: Workshop portfolio API integration
Users can export their own submission Users can export feedback/assessment received from other users
This commit is contained in:
parent
d9520bc04e
commit
5fd75ed889
571
mod/workshop/classes/portfolio_caller.php
Normal file
571
mod/workshop/classes/portfolio_caller.php
Normal file
@ -0,0 +1,571 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Workshop portfolio caller class to integrate with portfolio API.
|
||||
*
|
||||
* @package mod_workshop
|
||||
* @copyright Loc Nguyen <ndloc1905@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
require_once($CFG->libdir . '/portfolio/caller.php');
|
||||
|
||||
|
||||
/**
|
||||
* Workshop portfolio caller subclass to handle export submission and assessment to portfolio.
|
||||
*
|
||||
* @package mod_workshop
|
||||
* @copyright Loc Nguyen <ndloc1905@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mod_workshop_portfolio_caller extends portfolio_module_caller_base {
|
||||
/**
|
||||
* @var int ID of submission.
|
||||
*/
|
||||
protected $submissionid;
|
||||
/**
|
||||
* @var int ID of assessment.
|
||||
*/
|
||||
protected $assessmentid;
|
||||
/**
|
||||
* @var stdClass Course module.
|
||||
*/
|
||||
protected $cm;
|
||||
/**
|
||||
* @var array Submission files list.
|
||||
*/
|
||||
protected $submissionfiles = array();
|
||||
/**
|
||||
* @var array Assessment files list.
|
||||
*/
|
||||
protected $assessmentfiles = array();
|
||||
|
||||
/**
|
||||
* @var stdClass Submission object load from DB.
|
||||
*/
|
||||
private $submission;
|
||||
/**
|
||||
* @var stdClass Assessment object.
|
||||
*/
|
||||
private $assessment;
|
||||
/**
|
||||
* @var stdClass User object.
|
||||
*/
|
||||
private $author;
|
||||
/**
|
||||
* @var boolean Show author permission.
|
||||
*/
|
||||
private $showauthor;
|
||||
|
||||
/**
|
||||
* Return array of expected call back arguments
|
||||
*
|
||||
* and whether they are required or not.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function expected_callbackargs() {
|
||||
return array(
|
||||
'submissionid' => false,
|
||||
'assessmentid' => false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load data required for the export.
|
||||
*
|
||||
* Load submission and assessment by submissionid, assessmentid.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function load_data() {
|
||||
global $DB;
|
||||
|
||||
$this->submission = $DB->get_record('workshop_submissions', array('id' => $this->submissionid), '*', MUST_EXIST);
|
||||
$this->cm = get_coursemodule_from_instance('workshop', $this->submission->workshopid, 0, false, MUST_EXIST);
|
||||
$this->author = $DB->get_record('user', array('id' => $this->submission->authorid));
|
||||
|
||||
$workshoprecord = $DB->get_record('workshop', array('id' => $this->cm->instance), '*', MUST_EXIST);
|
||||
$course = $DB->get_record('course', array('id' => $this->cm->course), '*', MUST_EXIST);
|
||||
$this->workshop = new workshop($workshoprecord, $this->cm, $course);
|
||||
|
||||
// Load data for export assessment.
|
||||
if ($this->submissionid && $this->assessmentid) {
|
||||
$assessments = $this->workshop->get_assessments_of_submission($this->submission->id);
|
||||
$this->assessment = new stdClass();
|
||||
$this->assessment = $assessments[$this->assessmentid];
|
||||
$fs = get_file_storage();
|
||||
$this->assessmentfiles = $fs->get_area_files($this->workshop->context->id, 'mod_workshop',
|
||||
'overallfeedback_attachment', $this->assessment->id);
|
||||
}
|
||||
// Load data for export submission.
|
||||
if ($this->submissionid && !$this->assessmentid) {
|
||||
$fs = get_file_storage();
|
||||
$submissioncontentfiles = $fs->get_area_files($this->workshop->context->id,
|
||||
'mod_workshop', 'submission_content', $this->submissionid);
|
||||
$submissionattachmentfiles = $fs->get_area_files($this->workshop->context->id,
|
||||
'mod_workshop', 'submission_attachment', $this->submissionid);
|
||||
$submissioninstructionfiles = $fs->get_area_files($this->workshop->context->id,
|
||||
'mod_workshop', 'instructauthors');
|
||||
$this->submissionfiles = array_merge($submissioncontentfiles, $submissionattachmentfiles, $submissioninstructionfiles);
|
||||
|
||||
// Check anonymity of exported, show author or not.
|
||||
$ispublished = ($this->workshop->phase == workshop::PHASE_CLOSED
|
||||
and $this->submission->published == 1
|
||||
and has_capability('mod/workshop:viewpublishedsubmissions', $this->workshop->context));
|
||||
$seenaspublished = false; // Is the submission seen as a published submission?
|
||||
|
||||
if ($ispublished) {
|
||||
$seenaspublished = true;
|
||||
}
|
||||
if ($seenaspublished) {
|
||||
$this->showauthor = has_capability('mod/workshop:viewauthorpublished', $this->workshop->context);
|
||||
} else {
|
||||
$this->showauthor = has_capability('mod/workshop:viewauthornames', $this->workshop->context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the package ready to be passed off to the portfolio plugin.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepare_package() {
|
||||
// Set up the leap2a writer if we need it.
|
||||
$writingleap = false;
|
||||
if ($this->exporter->get('formatclass') == PORTFOLIO_FORMAT_LEAP2A) {
|
||||
$leapwriter = $this->exporter->get('format')->leap2a_writer();
|
||||
$writingleap = true;
|
||||
}
|
||||
|
||||
if ($this->submissionid && $this->assessmentid) {
|
||||
$assessmenthtml = $this->prepare_assessment($this->assessment);
|
||||
$content = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $assessmenthtml);
|
||||
$name = 'assessment.html';
|
||||
if ($writingleap) {
|
||||
$this->prepare_assessment_leap2a($leapwriter, $this->assessment, $content);
|
||||
$content = $leapwriter->to_xml();
|
||||
$name = $this->exporter->get('format')->manifest_name();
|
||||
}
|
||||
}
|
||||
if ($this->submissionid && !$this->assessmentid) {
|
||||
$submissionhtml = $this->prepare_submission($this->submission);
|
||||
$content = $submissionhtml;
|
||||
$name = 'submission.html';
|
||||
if ($writingleap) {
|
||||
$this->prepare_submission_leap2a($leapwriter, $this->submission, $content);
|
||||
$content = $leapwriter->to_xml();
|
||||
$name = $this->exporter->get('format')->manifest_name();
|
||||
}
|
||||
}
|
||||
$manifest = ($this->exporter->get('format') instanceof PORTFOLIO_FORMAT_RICH);
|
||||
$this->get('exporter')->write_new_file($content, $name, $manifest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to output submission for export.
|
||||
*
|
||||
* This is cut down version of workshop submission renderer function.
|
||||
*
|
||||
* @param object $submission
|
||||
* @return string
|
||||
*/
|
||||
private function prepare_submission($submission) {
|
||||
global $CFG;
|
||||
$output = '';
|
||||
$output .= '<meta charset="UTF-8">';
|
||||
$output .= html_writer::tag("h2", $this->workshop->name);
|
||||
|
||||
// Write submission content.
|
||||
$output .= html_writer::start_tag('div', array('class' => 'submissionheader', 'style' => 'background-color: #ddd;'));
|
||||
$output .= html_writer::tag("h3", format_string($submission->title));
|
||||
if ($this->showauthor) {
|
||||
$output .= html_writer::tag('div', get_string('byfullnamewithoutlink', 'workshop', fullname($this->author)));
|
||||
}
|
||||
$created = get_string('userdatecreated', 'workshop', userdate($submission->timecreated));
|
||||
$output .= html_writer::tag("div", $created, array('style' => 'font-size:x-small'));
|
||||
|
||||
if ($submission->timemodified > $submission->timecreated) {
|
||||
$modified = get_string('userdatemodified', 'workshop', userdate($submission->timemodified));
|
||||
$output .= html_writer::tag("div", $modified, array('style' => 'font-size:x-small'));
|
||||
}
|
||||
$output .= html_writer::end_tag('div');
|
||||
$format = $this->get('exporter')->get('format');
|
||||
$content = portfolio_rewrite_pluginfile_urls($submission->content, $this->workshop->context->id, 'mod_workshop',
|
||||
'submission_content', $submission->id, $format);
|
||||
$content = format_text($content, $submission->contentformat);
|
||||
$output .= html_writer::tag("div", $content);
|
||||
if ($this->submissionfiles) {
|
||||
$outputfiles = '';
|
||||
foreach ($this->submissionfiles as $file) {
|
||||
if ($file->is_directory()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$filename = $file->get_filename();
|
||||
$filearea = $file->get_filearea();
|
||||
$type = $file->get_mimetype();
|
||||
$linkhtml = $format->file_output($file);
|
||||
|
||||
if ($filearea == "submission_attachment") {
|
||||
$outputfiles .= html_writer::tag('li', $linkhtml, array('class' => $type));
|
||||
}
|
||||
|
||||
if ($filename) {
|
||||
$this->get('exporter')->copy_existing_file($file);
|
||||
}
|
||||
|
||||
if (!empty($CFG->enableplagiarism)) {
|
||||
require_once($CFG->libdir . '/plagiarismlib.php');
|
||||
$outputfiles .= plagiarism_get_links(array('userid' => $file->get_userid(),
|
||||
'file' => $file,
|
||||
'cmid' => $this->cm->id,
|
||||
'course' => $this->cm->course));
|
||||
}
|
||||
}
|
||||
$output .= $outputfiles;
|
||||
}
|
||||
|
||||
// Write submission instruction.
|
||||
if (trim($this->workshop->instructauthors)) {
|
||||
$output .= html_writer::tag("h3", get_string('instructauthors', 'workshop'));
|
||||
$format = $this->get('exporter')->get('format');
|
||||
$instructauthorscontent = portfolio_rewrite_pluginfile_urls($this->workshop->instructauthors,
|
||||
$this->workshop->context->id, 'mod_workshop', 'instructauthors', 0, $format);
|
||||
$output .= $instructauthorscontent;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to add a leap2a entry element that corresponds to a submission,
|
||||
* including any attachments.
|
||||
*
|
||||
* The entry/ies are added directly to the leapwriter, which is passed by ref.
|
||||
*
|
||||
* @param portfolio_format_leap2a_writer $leapwriter writer object to add entries to
|
||||
* @param object $submission the stdclass object representing the database record
|
||||
* @param string $submissionhtml the content of the submission
|
||||
*
|
||||
* @return int id of new entry
|
||||
*/
|
||||
private function prepare_submission_leap2a(portfolio_format_leap2a_writer $leapwriter, $submission, $submissionhtml) {
|
||||
global $DB;
|
||||
$entry = new portfolio_format_leap2a_entry('workshopsubmission' . $submission->id, $submission->title,
|
||||
'resource', $submissionhtml);
|
||||
$entry->published = $submission->timecreated;
|
||||
$entry->updated = $submission->timemodified;
|
||||
$entry->author = $DB->get_record('user', array('id' => $submission->authorid), 'id,firstname,lastname,email');
|
||||
|
||||
if (is_array($this->submissionfiles) && array_key_exists($submission->id, $this->submissionfiles)
|
||||
&& is_array($this->submissionfiles[$submission->id])) {
|
||||
$leapwriter->link_files($entry, $this->submissionfiles[$submission->id], 'workshopsubmission'
|
||||
. $submission->id . 'attachment');
|
||||
}
|
||||
$entry->add_category('web', 'resource_type');
|
||||
$leapwriter->add_entry($entry);
|
||||
return $entry->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to output assessment for export.
|
||||
*
|
||||
* This is a cut down function of workshop assessment renderer function.
|
||||
*
|
||||
* @param object $assessment the stdclass object representing the database record
|
||||
* @return string
|
||||
*/
|
||||
private function prepare_assessment($assessment) {
|
||||
global $PAGE;
|
||||
global $CFG;
|
||||
global $USER;
|
||||
$strategy = $this->workshop->grading_strategy_instance();
|
||||
$mform = $strategy->get_assessment_form($PAGE->url, 'assessment', $assessment, false);
|
||||
$userassessment = $this->workshop->get_assessment_of_submission_by_user($assessment->submissionid, $USER->id);
|
||||
$isreviewer = !empty($userassessment);
|
||||
if ($isreviewer) {
|
||||
$showreviewer = true;
|
||||
} else {
|
||||
$showreviewer = has_capability('mod/workshop:viewreviewernames', $this->workshop->context);
|
||||
}
|
||||
|
||||
$fs = get_file_storage();
|
||||
$options = array(
|
||||
'showreviewer' => $showreviewer,
|
||||
'showauthor' => $this->showauthor,
|
||||
'showform' => !is_null($assessment->grade),
|
||||
'showweight' => true,
|
||||
);
|
||||
$displayassessment = $this->workshop->prepare_assessment($assessment, $mform, $options);
|
||||
|
||||
$output = '';
|
||||
$output .= '<meta charset="UTF-8">';
|
||||
|
||||
// Start write assessment content.
|
||||
$anonymous = is_null($displayassessment->reviewer);
|
||||
|
||||
$output .= html_writer::start_tag('div', array('class' => 'assessmentheader', 'style' => 'background-color: #ddd;'));
|
||||
|
||||
if (!empty($displayassessment->title)) {
|
||||
$title = s($displayassessment->title);
|
||||
} else {
|
||||
$title = get_string('assessmentbyyourself', 'workshop');
|
||||
}
|
||||
|
||||
$output .= html_writer::tag("div", $title);
|
||||
|
||||
if (!$anonymous) {
|
||||
$reviewer = $displayassessment->reviewer;
|
||||
$output .= html_writer::tag("div", get_string('byfullnamewithoutlink', 'workshop', fullname($reviewer)));
|
||||
}
|
||||
|
||||
if (is_null($displayassessment->realgrade)) {
|
||||
$output .= html_writer::tag("div", get_string('notassessed', 'workshop'));
|
||||
} else {
|
||||
$a = new stdClass();
|
||||
$a->max = $displayassessment->maxgrade;
|
||||
$a->received = $displayassessment->realgrade;
|
||||
$output .= html_writer::tag("div", get_string('gradeinfo', 'workshop', $a));
|
||||
|
||||
if (!is_null($displayassessment->weight) and $displayassessment->weight != 1) {
|
||||
$output .= html_writer::tag("div", get_string('weightinfo', 'workshop', $displayassessment->weight));
|
||||
}
|
||||
}
|
||||
$output .= html_writer::end_tag('div');
|
||||
|
||||
$dir = $this->get('exporter')->get('format')->get_file_directory();
|
||||
|
||||
if (!is_null($displayassessment->form)) {
|
||||
$output .= html_writer::tag("div", get_string('assessmentform', 'workshop'));
|
||||
$contentform = self::moodleform($displayassessment->form);
|
||||
$contentform = $this->portfolio_caller_rewrite_pluginfile_urls($contentform, $dir);
|
||||
$output .= html_writer::tag("div", $contentform);
|
||||
if (!$displayassessment->form->is_editable()) {
|
||||
$content = $displayassessment->get_overall_feedback_content();
|
||||
$content = $this->portfolio_caller_rewrite_pluginfile_urls($content, $dir);
|
||||
if ($content != '') {
|
||||
$output .= html_writer::tag("div", get_string('overallfeedback', 'workshop'));
|
||||
$output .= html_writer::tag("div", $content);
|
||||
}
|
||||
// Export overall feedback files.
|
||||
$overallfeedbackfiles = $fs->get_area_files($this->workshop->context->id,
|
||||
'mod_workshop', 'overallfeedback_content', $assessment->id);
|
||||
foreach ($overallfeedbackfiles as $file) {
|
||||
$this->get('exporter')->copy_existing_file($file);
|
||||
}
|
||||
}
|
||||
|
||||
// Export description files.
|
||||
$assessmentdescriptionfiles = $fs->get_area_files($this->workshop->context->id,
|
||||
'workshopform_' . $this->workshop->strategy, 'description');
|
||||
foreach ($assessmentdescriptionfiles as $file) {
|
||||
$this->get('exporter')->copy_existing_file($file);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->assessmentfiles) {
|
||||
$outputfiles = '';
|
||||
$format = $this->get('exporter')->get('format');
|
||||
foreach ($this->assessmentfiles as $file) {
|
||||
if ($file->is_directory()) {
|
||||
continue;
|
||||
}
|
||||
$type = $file->get_mimetype();
|
||||
$linkhtml = $format->file_output($file);
|
||||
$outputfiles .= html_writer::tag('li', $linkhtml, array('class' => $type));
|
||||
|
||||
$this->get('exporter')->copy_existing_file($file);
|
||||
|
||||
if (!empty($CFG->enableplagiarism)) {
|
||||
require_once($CFG->libdir.'/plagiarismlib.php');
|
||||
$outputfiles .= plagiarism_get_links(array('userid' => $file->get_userid(),
|
||||
'file' => $file,
|
||||
'cmid' => $this->cm->id,
|
||||
'course' => $this->cm->course));
|
||||
}
|
||||
}
|
||||
$output .= $outputfiles;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function to add a leap2a entry element that corresponds to a assessment,
|
||||
* including any attachments.
|
||||
*
|
||||
* The entry/ies are added directly to the leapwriter, which is passed by ref.
|
||||
*
|
||||
* @param portfolio_format_leap2a_writer $leapwriter writer object to add entries to
|
||||
* @param object $assessment the stdclass object representing the database record
|
||||
* @param string $assessmenthtml the content of the assessment
|
||||
*
|
||||
* @return int id of new entry
|
||||
*/
|
||||
private function prepare_assessment_leap2a(portfolio_format_leap2a_writer $leapwriter, $assessment, $assessmenthtml) {
|
||||
global $DB;
|
||||
$entry = new portfolio_format_leap2a_entry('workshopassessment' . $assessment->id,
|
||||
$assessment->title, 'resource', $assessmenthtml);
|
||||
$entry->published = $assessment->timecreated;
|
||||
$entry->updated = $assessment->timemodified;
|
||||
$entry->author = $DB->get_record('user', array('id' => $assessment->reviewerid), 'id,firstname,lastname,email');
|
||||
|
||||
if (is_array($this->assessmentfiles) && array_key_exists($assessment->id, $this->assessmentfiles)
|
||||
&& is_array($this->assessmentfiles[$assessment->id])) {
|
||||
$leapwriter->link_files($entry, $this->assessmentfiles[$assessment->id], 'workshopassessment'
|
||||
. $assessment->id . 'attachment');
|
||||
}
|
||||
$entry->add_category('web', 'resource_type');
|
||||
$leapwriter->add_entry($entry);
|
||||
return $entry->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return url for redirecting user when cancel or go back.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_return_url() {
|
||||
$returnurl = new moodle_url('/mod/workshop/submission.php',
|
||||
array('cmid' => $this->cm->id));
|
||||
return $returnurl->out();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get navigation that logically follows from the place the user was before.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_navigation() {
|
||||
$link = new moodle_url('/mod/workshop/submission.php',
|
||||
array('cmid' => $this->cm->id));
|
||||
$navlinks = array();
|
||||
$navlinks[] = array(
|
||||
'name' => format_string($this->submission->title),
|
||||
'link' => $link->out(),
|
||||
'type' => 'title'
|
||||
);
|
||||
return array($navlinks, $this->cm);
|
||||
}
|
||||
|
||||
/**
|
||||
* How long might we expect this export to take.
|
||||
*
|
||||
* @return constant one of PORTFOLIO_TIME_XX
|
||||
*/
|
||||
public function expected_time() {
|
||||
return PORTFOLIO_TIME_LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the current user is allowed to do the export.
|
||||
*
|
||||
* @uses CONTEXT_MODULE
|
||||
* @return boolean
|
||||
*/
|
||||
public function check_permissions() {
|
||||
$context = context_module::instance($this->cm->id);
|
||||
if ($this->submissionid && $this->assessmentid) {
|
||||
return has_capability('mod/workshop:exportownsubmission', $context)
|
||||
&& has_capability('mod/workshop:exportownsubmissionassessment', $context);
|
||||
}
|
||||
return has_capability('mod/workshop:exportownsubmission', $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sha1 of this content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_sha1() {
|
||||
if ($this->submissionid && $this->assessmentid) {
|
||||
return sha1($this->assessment->id . ',' . $this->assessment->title . ',' . $this->assessment->timecreated);
|
||||
}
|
||||
if ($this->submissionid && !$this->assessmentid) {
|
||||
return sha1($this->submission->id . ',' . $this->submission->title . ',' . $this->submission->timecreated);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a nice name to be displayed about this export location.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function display_name() {
|
||||
return get_string('modulename', 'workshop');
|
||||
}
|
||||
|
||||
/**
|
||||
* What formats this function *generally* supports.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function base_supported_formats() {
|
||||
return array(PORTFOLIO_FORMAT_FILE, PORTFOLIO_FORMAT_RICHHTML, PORTFOLIO_FORMAT_PLAINHTML, PORTFOLIO_FORMAT_LEAP2A);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method dealing with the fact we can not just fetch the output of moodleforms.
|
||||
*
|
||||
* @param moodleform $mform
|
||||
* @return string HTML
|
||||
*/
|
||||
protected static function moodleform(moodleform $mform) {
|
||||
ob_start();
|
||||
$mform->display();
|
||||
$o = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method dealing with the fact we can not just fetch the output of moodleforms.
|
||||
*
|
||||
* @param string $text HTML string to rewrite url
|
||||
* @param string $dir rewrite file directory
|
||||
* @return string HTML
|
||||
*/
|
||||
public static function portfolio_caller_rewrite_pluginfile_urls($text, $dir) {
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadHTML($text);
|
||||
|
||||
$imagetags = $doc->getElementsByTagName('img');
|
||||
foreach ($imagetags as $tag) {
|
||||
$src = $tag->getAttribute('src');
|
||||
if (strpos($src, 'pluginfile.php') !== false) {
|
||||
$rewriteurl = $dir . basename($src);
|
||||
$text = str_replace($src, $rewriteurl, $text);
|
||||
}
|
||||
}
|
||||
|
||||
$atags = $doc->getElementsByTagName('a');
|
||||
foreach ($atags as $atag) {
|
||||
$href = $atag->getAttribute('href');
|
||||
if (strpos($href, 'pluginfile.php') !== false) {
|
||||
$rewriteurl = $dir . basename($href);
|
||||
$text = str_replace($href, $rewriteurl, $text);
|
||||
}
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
@ -244,4 +244,22 @@ $capabilities = array(
|
||||
'manager' => CAP_ALLOW
|
||||
)
|
||||
),
|
||||
|
||||
// Ability to export to portfolio of submission only.
|
||||
'mod/workshop:exportownsubmission' => array(
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_MODULE,
|
||||
'archetypes' => array(
|
||||
'student' => CAP_ALLOW
|
||||
)
|
||||
),
|
||||
|
||||
// Ability to export to portfolio of submission's assessment.
|
||||
'mod/workshop:exportownsubmissionassessment' => array(
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_MODULE,
|
||||
'archetypes' => array(
|
||||
'student' => CAP_ALLOW
|
||||
)
|
||||
),
|
||||
);
|
||||
|
@ -73,6 +73,7 @@ $string['assignedassessments'] = 'Assigned submissions to assess';
|
||||
$string['assignedassessmentsnone'] = 'You have no assigned submission to assess';
|
||||
$string['backtoeditform'] = 'Back to editing form';
|
||||
$string['byfullname'] = 'by <a href="{$a->url}">{$a->name}</a>';
|
||||
$string['byfullnamewithoutlink'] = 'by {$a}';
|
||||
$string['calculategradinggrades'] = 'Calculate assessment grades';
|
||||
$string['calculategradinggradesdetails'] = 'expected: {$a->expected}<br />calculated: {$a->calculated}';
|
||||
$string['calculatesubmissiongrades'] = 'Calculate submission grades';
|
||||
@ -143,6 +144,8 @@ $string['examplesbeforesubmission'] = 'Examples must be assessed before own subm
|
||||
$string['examplesmode'] = 'Mode of examples assessment';
|
||||
$string['examplesubmissions'] = 'Example submissions';
|
||||
$string['examplesvoluntary'] = 'Assessment of example submission is voluntary';
|
||||
$string['exportsubmission'] = 'Export submission to portfolio';
|
||||
$string['exportsubmissionassessment'] = 'Export assessment to portfolio';
|
||||
$string['feedbackauthor'] = 'Feedback for the author';
|
||||
$string['feedbackauthorattachment'] = 'Attachment';
|
||||
$string['feedbackby'] = 'Feedback by {$a}';
|
||||
@ -331,6 +334,8 @@ $string['withoutsubmission'] = 'Reviewer without own submission';
|
||||
$string['workshop:addinstance'] = 'Add a new workshop';
|
||||
$string['workshop:allocate'] = 'Allocate submissions for review';
|
||||
$string['workshop:editdimensions'] = 'Edit assessment forms';
|
||||
$string['workshop:exportownsubmission'] = 'Export own submission only';
|
||||
$string['workshop:exportownsubmissionassessment'] = 'Export own assessment in submission';
|
||||
$string['workshop:deletesubmissions'] = 'Delete submissions';
|
||||
$string['workshop:ignoredeadlines'] = 'Ignore time restrictions';
|
||||
$string['workshop:manageexamples'] = 'Manage example submissions';
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@ -87,6 +86,12 @@ $canallocate = has_capability('mod/workshop:allocate', $workshop->context);
|
||||
$canpublish = has_capability('mod/workshop:publishsubmissions', $workshop->context);
|
||||
$canoverride = (($workshop->phase == workshop::PHASE_EVALUATION) and has_capability('mod/workshop:overridegrades', $workshop->context));
|
||||
$candeleteall = has_capability('mod/workshop:deletesubmissions', $workshop->context);
|
||||
$canexportownsubmission = !empty($CFG->enableportfolios)
|
||||
&& (has_capability('mod/workshop:exportownsubmission', $workshop->context)) && $ownsubmission && !empty($submission->id);
|
||||
$canexportownsubmissionassessment = !empty($CFG->enableportfolios)
|
||||
&& (has_capability('mod/workshop:exportownsubmission', $workshop->context))
|
||||
&& (has_capability('mod/workshop:exportownsubmissionassessment', $workshop->context))
|
||||
&& $ownsubmission && !empty($submission->id);
|
||||
$userassessment = $workshop->get_assessment_of_submission_by_user($submission->id, $USER->id);
|
||||
$isreviewer = !empty($userassessment);
|
||||
$editable = ($cansubmit and $ownsubmission);
|
||||
@ -139,6 +144,11 @@ if (!$candeleteall and $ownsubmission and $editable) {
|
||||
}
|
||||
}
|
||||
|
||||
// Load portfolio lib if user has capability to export.
|
||||
if ($canexportownsubmission || $canexportownsubmissionassessment) {
|
||||
require_once($CFG->libdir.'/portfoliolib.php');
|
||||
}
|
||||
|
||||
if ($submission->id and $delete and $confirm and $deletable) {
|
||||
require_sesskey();
|
||||
$workshop->delete_submission($submission);
|
||||
@ -386,6 +396,23 @@ if (!$delete) {
|
||||
$url = new moodle_url($PAGE->url, array('assess' => 1));
|
||||
echo $output->single_button($url, get_string('assess', 'workshop'), 'post');
|
||||
}
|
||||
|
||||
// Add portfolio export button for submission.
|
||||
if ($canexportownsubmission) {
|
||||
$button = new portfolio_add_button();
|
||||
$button->set_callback_options('mod_workshop_portfolio_caller', array('submissionid' => $submission->id), 'mod_workshop');
|
||||
$fs = get_file_storage();
|
||||
$files = array_merge($fs->get_area_files($workshop->context->id, 'mod_workshop', 'submission_attachment', $submission->id)
|
||||
, $fs->get_area_files($workshop->context->id, 'mod_workshop', 'submission_content', $submission->id));
|
||||
if ($files) {
|
||||
$button->set_formats(PORTFOLIO_FORMAT_RICHHTML);
|
||||
} else {
|
||||
$button->set_formats(PORTFOLIO_FORMAT_PLAINHTML);
|
||||
}
|
||||
echo html_writer::start_tag('div', array('class' => 'singlebutton'));
|
||||
echo $button->to_html(PORTFOLIO_ADD_FULL_FORM, get_string('exportsubmission', 'workshop'));
|
||||
echo html_writer::end_tag('div');
|
||||
}
|
||||
}
|
||||
|
||||
if (($workshop->phase == workshop::PHASE_CLOSED) and ($ownsubmission or $canviewall)) {
|
||||
@ -427,9 +454,31 @@ if ($isreviewer) {
|
||||
echo $output->render(new workshop_feedback_reviewer($userassessment));
|
||||
}
|
||||
}
|
||||
|
||||
// Add portfolio export button for assessment.
|
||||
if ($canexportownsubmissionassessment) {
|
||||
$button = new portfolio_add_button();
|
||||
$button->set_callback_options('mod_workshop_portfolio_caller', array('submissionid' => $submission->id,
|
||||
'assessmentid' => $assessment->id), 'mod_workshop');
|
||||
$fs = get_file_storage();
|
||||
$files = array_merge($fs->get_area_files($workshop->context->id, 'mod_workshop'
|
||||
, 'overallfeedback_attachment', $assessment->id)
|
||||
, $fs->get_area_files($workshop->context->id, 'workshopform_' . $workshop->strategy, 'description')
|
||||
, $fs->get_area_files($workshop->context->id, 'mod_workshop', 'overallfeedback', $assessment->id));
|
||||
|
||||
if ($files) {
|
||||
$button->set_formats(PORTFOLIO_FORMAT_RICHHTML);
|
||||
} else {
|
||||
$button->set_formats(PORTFOLIO_FORMAT_PLAINHTML);
|
||||
}
|
||||
echo html_writer::start_tag('div', array('class' => 'singlebutton'));
|
||||
echo $button->to_html(PORTFOLIO_ADD_FULL_FORM, get_string('exportsubmissionassessment', 'workshop'));
|
||||
echo html_writer::end_tag('div');
|
||||
}
|
||||
}
|
||||
|
||||
if (has_capability('mod/workshop:viewallassessments', $workshop->context) or ($ownsubmission and $workshop->assessments_available())) {
|
||||
if (has_capability('mod/workshop:viewallassessments', $workshop->context)
|
||||
or ($ownsubmission and $workshop->assessments_available())) {
|
||||
// other assessments
|
||||
$strategy = $workshop->grading_strategy_instance();
|
||||
$assessments = $workshop->get_assessments_of_submission($submission->id);
|
||||
@ -461,6 +510,27 @@ if (has_capability('mod/workshop:viewallassessments', $workshop->context) or ($o
|
||||
echo $output->render(new workshop_feedback_reviewer($assessment));
|
||||
}
|
||||
}
|
||||
|
||||
// Add portfolio export button for assessment.
|
||||
if ($canexportownsubmissionassessment) {
|
||||
$button = new portfolio_add_button();
|
||||
$button->set_callback_options('mod_workshop_portfolio_caller', array('submissionid' => $submission->id,
|
||||
'assessmentid' => $assessment->id), 'mod_workshop');
|
||||
$fs = get_file_storage();
|
||||
$files = array_merge($fs->get_area_files($workshop->context->id, 'mod_workshop'
|
||||
, 'overallfeedback_attachment', $assessment->id)
|
||||
, $fs->get_area_files($workshop->context->id, 'workshopform_' . $workshop->strategy, 'description')
|
||||
, $fs->get_area_files($workshop->context->id, 'mod_workshop', 'overallfeedback', $assessment->id));
|
||||
|
||||
if ($files) {
|
||||
$button->set_formats(PORTFOLIO_FORMAT_RICHHTML);
|
||||
} else {
|
||||
$button->set_formats(PORTFOLIO_FORMAT_PLAINHTML);
|
||||
}
|
||||
echo html_writer::start_tag('div', array('class' => 'singlebutton'));
|
||||
echo $button->to_html(PORTFOLIO_ADD_FULL_FORM, get_string('exportsubmissionassessment', 'workshop'));
|
||||
echo html_writer::end_tag('div');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,4 +160,18 @@ class behat_mod_workshop extends behat_base {
|
||||
}
|
||||
$this->find('xpath', $xpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure portfolio plugin, set value for portfolio instance
|
||||
*
|
||||
* @When /^I set portfolio instance "(?P<portfolioinstance_string>(?:[^"]|\\")*)" to "(?P<value_string>(?:[^"]|\\")*)"$/
|
||||
* @param string $portfolioinstance
|
||||
* @param string $value
|
||||
*/
|
||||
public function i_set_portfolio_instance_to($portfolioinstance, $value) {
|
||||
$xpath = "//table[contains(@class, 'generaltable')]//tr//td[contains(text(), '"
|
||||
. $portfolioinstance . "')]/following-sibling::td//select";
|
||||
$select = $this->find('xpath', $xpath);
|
||||
$select->selectOption($value);
|
||||
}
|
||||
}
|
||||
|
141
mod/workshop/tests/behat/export_assessment.feature
Normal file
141
mod/workshop/tests/behat/export_assessment.feature
Normal file
@ -0,0 +1,141 @@
|
||||
@mod @mod_workshop
|
||||
@javascript
|
||||
|
||||
Feature: Workshop submission's assessment export to portfolio
|
||||
In order to be able to reuse my assessment content in my submission
|
||||
As a student
|
||||
I need to be able to export my own submission's assessment from other people
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| student1 | Sam1 | Student1 | student1@example.com |
|
||||
| student2 | Sam2 | Student2 | student2@example.com |
|
||||
| teacher1 | Terry1 | Teacher1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname |
|
||||
| Course1 | c2 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | c2 | student |
|
||||
| student2 | c2 | student |
|
||||
| teacher1 | c2 | editingteacher |
|
||||
And the following "activities" exist:
|
||||
| activity | name | intro | course | idnumber |
|
||||
| workshop | TestWorkshop | Test workshop description | c2 | workshop1 |
|
||||
# Admin enable portfolio plugin
|
||||
And I log in as "admin"
|
||||
And I expand "Site administration" node
|
||||
And I follow "Advanced features"
|
||||
And I set the following administration settings values:
|
||||
| Enable portfolios | 1 |
|
||||
And I expand "Plugins" node
|
||||
And I expand "Portfolios" node
|
||||
And I follow "Manage portfolios"
|
||||
And I set portfolio instance "File download" to "Enabled and visible"
|
||||
And I click on "Save" "button"
|
||||
And I log out
|
||||
# Teacher sets up assessment form and changes the phase to submission.
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course1"
|
||||
And I edit assessment form in workshop "TestWorkshop" as:"
|
||||
| id_description__idx_0_editor | Aspect1 |
|
||||
| id_description__idx_1_editor | Aspect2 |
|
||||
| id_description__idx_2_editor | |
|
||||
And I change phase in workshop "TestWorkshop" to "Submission phase"
|
||||
And I log out
|
||||
# Student1 submits.
|
||||
And I log in as "student1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I add a submission in workshop "TestWorkshop" as:"
|
||||
| Title | Submission1 |
|
||||
| Submission content | Some content |
|
||||
And I log out
|
||||
# Student2 submits.
|
||||
And I log in as "student2"
|
||||
And I follow "Course1"
|
||||
And I add a submission in workshop "TestWorkshop" as:"
|
||||
| Title | Submission2 |
|
||||
| Submission content | Some content |
|
||||
And I log out
|
||||
# teacher1 allocates reviewers and changes the phase to assessment
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I allocate submissions in workshop "TestWorkshop" as:"
|
||||
| Participant | Reviewer |
|
||||
| Sam1 Student1 | Sam2 Student2 |
|
||||
| Sam2 Student2 | Sam1 Student1 |
|
||||
And I follow "TestWorkshop"
|
||||
And I change phase in workshop "TestWorkshop" to "Assessment phase"
|
||||
And I log out
|
||||
# student1 assesses work of student2
|
||||
And I log in as "student1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I assess submission "Sam2" in workshop "TestWorkshop" as:"
|
||||
| grade__idx_0 | 5 / 10 |
|
||||
| peercomment__idx_0 | You can do better |
|
||||
| grade__idx_1 | 10 / 10 |
|
||||
| peercomment__idx_1 | Amazing |
|
||||
| Feedback for the author | Good work |
|
||||
And I log out
|
||||
# student2 assesses work of student1
|
||||
And I log in as "student2"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I assess submission "Sam1" in workshop "TestWorkshop" as:"
|
||||
| grade__idx_0 | 6 / 10 |
|
||||
| peercomment__idx_0 | |
|
||||
| grade__idx_1 | 7 / 10 |
|
||||
| peercomment__idx_1 | |
|
||||
| Feedback for the author | Keep it up |
|
||||
And I log out
|
||||
|
||||
Scenario: Hide export to portfolio button of assessment if admin disable portfolio feature
|
||||
Given I log in as "admin"
|
||||
And I expand "Site administration" node
|
||||
And I follow "Advanced features"
|
||||
And I set the following administration settings values:
|
||||
| Enable portfolios | 0 |
|
||||
And I log out
|
||||
When I log in as "student1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I follow "My submission"
|
||||
Then I should see "Submission1"
|
||||
Then "Export assessment to portfolio" "button" should not exist
|
||||
And I log out
|
||||
|
||||
Scenario: Students can export to portfolio their own submission's assessments
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course1"
|
||||
And I change phase in workshop "TestWorkshop" to "Closed"
|
||||
And I log out
|
||||
When I log in as "student1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I follow "My submission"
|
||||
Then I should see "Submission1"
|
||||
Then "Export assessment to portfolio" "button" should exist
|
||||
And I click on "Export assessment to portfolio" "button"
|
||||
Then I should see "Available export formats"
|
||||
And I click on "Next" "button"
|
||||
Then I should see "Summary of your export"
|
||||
And I click on "Continue" "button"
|
||||
Then I should see "Return to where you were"
|
||||
And I log out
|
||||
|
||||
Scenario: Students can not export to portfolio the assessment content when viewing submission of other people
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course1"
|
||||
And I change phase in workshop "TestWorkshop" to "Closed"
|
||||
And I log out
|
||||
When I log in as "student2"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I follow "Submission1"
|
||||
Then I should see "Assessment"
|
||||
Then "Export assessment to portfolio" "button" should not exist
|
||||
And I log out
|
120
mod/workshop/tests/behat/export_submission.feature
Normal file
120
mod/workshop/tests/behat/export_submission.feature
Normal file
@ -0,0 +1,120 @@
|
||||
@mod @mod_workshop
|
||||
@javascript
|
||||
Feature: Workshop submission export to portfolio
|
||||
In order to be able to reuse my submission content
|
||||
As a student
|
||||
I need to be able to export my submission
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| student1 | Sam1 | Student1 | student1@example.com |
|
||||
| student2 | Sam2 | Student2 | student2@example.com |
|
||||
| teacher1 | Terry1 | Teacher1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname |
|
||||
| Course1 | c1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| student1 | c1 | student |
|
||||
| student2 | c1 | student |
|
||||
| teacher1 | c1 | editingteacher |
|
||||
And the following "activities" exist:
|
||||
| activity | name | intro | course | idnumber |
|
||||
| workshop | TestWorkshop | Test workshop description | c1 | workshop1 |
|
||||
# Admin enable portfolio plugin
|
||||
And I log in as "admin"
|
||||
And I expand "Site administration" node
|
||||
And I follow "Advanced features"
|
||||
And I set the following administration settings values:
|
||||
| Enable portfolios | 1 |
|
||||
And I expand "Plugins" node
|
||||
And I expand "Portfolios" node
|
||||
And I follow "Manage portfolios"
|
||||
And I set portfolio instance "File download" to "Enabled and visible"
|
||||
And I click on "Save" "button"
|
||||
And I log out
|
||||
# Teacher sets up assessment form and changes the phase to submission.
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course1"
|
||||
And I edit assessment form in workshop "TestWorkshop" as:"
|
||||
| id_description__idx_0_editor | Aspect1 |
|
||||
| id_description__idx_1_editor | Aspect2 |
|
||||
| id_description__idx_2_editor | |
|
||||
And I change phase in workshop "TestWorkshop" to "Submission phase"
|
||||
And I log out
|
||||
# Student1 submits.
|
||||
And I log in as "student1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I add a submission in workshop "TestWorkshop" as:"
|
||||
| Title | Submission1 |
|
||||
| Submission content | Some content |
|
||||
And I log out
|
||||
# Student2 submits.
|
||||
And I log in as "student2"
|
||||
And I follow "Course1"
|
||||
And I add a submission in workshop "TestWorkshop" as:"
|
||||
| Title | Submission2 |
|
||||
| Submission content | Some content |
|
||||
And I log out
|
||||
# teacher1 allocates reviewers and changes the phase to assessment
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I should see "to allocate: 2"
|
||||
Then I should see "Workshop submissions report"
|
||||
And I should see "Submitted (2) / not submitted (0)"
|
||||
And I should see "Submission1" in the "Sam1 Student1" "table_row"
|
||||
And I should see "Submission2" in the "Sam2 Student2" "table_row"
|
||||
And I allocate submissions in workshop "TestWorkshop" as:"
|
||||
| Participant | Reviewer |
|
||||
| Sam1 Student1 | Sam2 Student2 |
|
||||
| Sam2 Student2 | Sam1 Student1 |
|
||||
And I follow "TestWorkshop"
|
||||
And I should see "to allocate: 0"
|
||||
And I change phase in workshop "TestWorkshop" to "Assessment phase"
|
||||
And I log out
|
||||
|
||||
|
||||
Scenario: Hide export to portfolio button if admin disable portfolio feature
|
||||
Given I log in as "admin"
|
||||
And I expand "Site administration" node
|
||||
And I follow "Advanced features"
|
||||
And I set the following administration settings values:
|
||||
| Enable portfolios | 0 |
|
||||
And I log out
|
||||
When I log in as "student1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I follow "My submission"
|
||||
Then I should see "Submission1"
|
||||
Then "Export submission to portfolio" "button" should not exist
|
||||
And I log out
|
||||
|
||||
Scenario: Students can export to portfolio their own submission
|
||||
Given I log in as "student1"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
When I follow "My submission"
|
||||
Then I should see "Submission1"
|
||||
Then "Export submission to portfolio" "button" should exist
|
||||
And I click on "Export submission to portfolio" "button"
|
||||
Then I should see "Available export formats"
|
||||
And I click on "Next" "button"
|
||||
Then I should see "Summary of your export"
|
||||
And I click on "Continue" "button"
|
||||
Then I should see "Return to where you were"
|
||||
And I log out
|
||||
|
||||
Scenario: Students can not export to portfolio when viewing submission of other people
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course1"
|
||||
And I change phase in workshop "TestWorkshop" to "Closed"
|
||||
And I log out
|
||||
When I log in as "student2"
|
||||
And I follow "Course1"
|
||||
And I follow "TestWorkshop"
|
||||
And I follow "Submission1"
|
||||
Then "Export submission to portfolio" "button" should not exist
|
||||
And I log out
|
304
mod/workshop/tests/portfolio_caller_test.php
Normal file
304
mod/workshop/tests/portfolio_caller_test.php
Normal file
@ -0,0 +1,304 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for mod_workshop_portfolio_caller class defined in mod/workshop/classes/portfolio_caller.php
|
||||
*
|
||||
* @package mod_workshop
|
||||
* @copyright 2016 An Pham Van <an.phamvan@harveynash.vn>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/mod/workshop/locallib.php');
|
||||
require_once(__DIR__ . '/fixtures/testable.php');
|
||||
require_once($CFG->dirroot . '/mod/workshop/classes/portfolio_caller.php');
|
||||
|
||||
/**
|
||||
* Unit tests for mod_workshop_portfolio_caller class
|
||||
*
|
||||
* @package mod_workshop
|
||||
* @copyright 2016 An Pham Van <an.phamvan@harveynash.vn>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mod_workshop_porfolio_caller_testcase extends advanced_testcase {
|
||||
|
||||
/** @var stdClass $workshop Basic workshop data stored in an object. */
|
||||
protected $workshop;
|
||||
/** @var stdClass mod info */
|
||||
protected $cm;
|
||||
|
||||
/**
|
||||
* Setup testing environment.
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->setAdminUser();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$workshop = $this->getDataGenerator()->create_module('workshop', array('course' => $course));
|
||||
$this->cm = get_coursemodule_from_instance('workshop', $workshop->id, $course->id, false, MUST_EXIST);
|
||||
$this->workshop = new testable_workshop($workshop, $this->cm, $course);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tear down.
|
||||
*/
|
||||
protected function tearDown() {
|
||||
$this->workshop = null;
|
||||
$this->cm = null;
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function load_data()
|
||||
* Case 1: User exports the assessment of his/her own submission.
|
||||
* Assert that this function can load the correct assessment.
|
||||
*/
|
||||
public function test_load_data_for_own_submissionassessment() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$student1 = $this->getDataGenerator()->create_user();
|
||||
$student2 = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($student1->id, $this->workshop->course->id);
|
||||
$this->getDataGenerator()->enrol_user($student2->id, $this->workshop->course->id);
|
||||
$workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
|
||||
$subid1 = $workshopgenerator->create_submission($this->workshop->id, $student1->id);
|
||||
$asid1 = $workshopgenerator->create_assessment($subid1, $student2->id);
|
||||
|
||||
$portfoliocaller = new mod_workshop_portfolio_caller(array('submissionid' => $subid1, 'assessmentid' => $asid1));
|
||||
$portfoliocaller->load_data();
|
||||
|
||||
$reflector = new ReflectionObject($portfoliocaller);
|
||||
$assessment = $reflector->getProperty('assessment');
|
||||
$assessment->setAccessible(true);
|
||||
$result = $assessment->getValue($portfoliocaller);
|
||||
|
||||
$this->assertEquals($asid1, $result->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function load_data()
|
||||
* Case 2: User exports his/her own submission.
|
||||
* Assert that this function can load the correct submission.
|
||||
*/
|
||||
public function test_load_data_for_own_submission() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$student1 = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($student1->id, $this->workshop->course->id);
|
||||
$workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
|
||||
$subid1 = $workshopgenerator->create_submission($this->workshop->id, $student1->id);
|
||||
|
||||
$portfoliocaller = new mod_workshop_portfolio_caller(array('submissionid' => $subid1));
|
||||
$portfoliocaller->load_data();
|
||||
|
||||
$reflector = new ReflectionObject($portfoliocaller);
|
||||
$submission = $reflector->getProperty('submission');
|
||||
$submission->setAccessible(true);
|
||||
|
||||
$result = $submission->getValue($portfoliocaller);
|
||||
|
||||
$this->assertEquals($subid1, $result->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function get_return_url()
|
||||
* Assert that this function can return the correct url.
|
||||
*/
|
||||
public function test_get_return_url() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$student1 = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($student1->id, $this->workshop->course->id);
|
||||
$workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
|
||||
$subid1 = $workshopgenerator->create_submission($this->workshop->id, $student1->id);
|
||||
|
||||
$portfoliocaller = new mod_workshop_portfolio_caller(array('submissionid' => $subid1));
|
||||
|
||||
$reflector = new ReflectionObject($portfoliocaller);
|
||||
$cm = $reflector->getProperty('cm');
|
||||
$cm->setAccessible(true);
|
||||
$cm->setValue($portfoliocaller, $this->cm);
|
||||
|
||||
$expected = 'http://www.example.com/moodle/mod/workshop/submission.php?cmid='.$this->cm->id;
|
||||
$this->assertEquals($expected, $portfoliocaller->get_return_url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function get_navigation()
|
||||
* Assert that this function can return the navigation array.
|
||||
*/
|
||||
public function test_get_navigation() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$student1 = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($student1->id, $this->workshop->course->id);
|
||||
$workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
|
||||
$subid1 = $workshopgenerator->create_submission($this->workshop->id, $student1->id);
|
||||
|
||||
$portfoliocaller = new mod_workshop_portfolio_caller(array('submissionid' => $subid1));
|
||||
$portfoliocaller->load_data();
|
||||
|
||||
$reflector = new ReflectionObject($portfoliocaller);
|
||||
$cm = $reflector->getProperty('cm');
|
||||
$cm->setAccessible(true);
|
||||
$cm->setValue($portfoliocaller, $this->cm);
|
||||
|
||||
$this->assertTrue(is_array($portfoliocaller->get_navigation()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function check_permissions()
|
||||
* Case 1: User exports assessment.
|
||||
* Assert that this function can return a boolean value
|
||||
* to indicate that the user has capability to export the assessment.
|
||||
*/
|
||||
public function test_check_permissions_exportownsubmissionassessment() {
|
||||
global $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$context = context_module::instance($this->cm->id);
|
||||
$student1 = $this->getDataGenerator()->create_user();
|
||||
$student2 = $this->getDataGenerator()->create_user();
|
||||
$roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
|
||||
$this->getDataGenerator()->enrol_user($student1->id, $this->workshop->course->id, $roleids['student']);
|
||||
$this->getDataGenerator()->enrol_user($student2->id, $this->workshop->course->id, $roleids['student']);
|
||||
$workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
|
||||
$subid1 = $workshopgenerator->create_submission($this->workshop->id, $student1->id);
|
||||
$asid1 = $workshopgenerator->create_assessment($subid1, $student2->id);
|
||||
$this->setUser($student1);
|
||||
|
||||
$portfoliocaller = new mod_workshop_portfolio_caller(array('submissionid' => $subid1, 'assessmentid' => $asid1));
|
||||
|
||||
$reflector = new ReflectionObject($portfoliocaller);
|
||||
$cm = $reflector->getProperty('cm');
|
||||
$cm->setAccessible(true);
|
||||
$cm->setValue($portfoliocaller, $this->cm);
|
||||
|
||||
// Case 1: If user has capabilities exportownsubmission prevented and exportownsubmissionassessment prevented
|
||||
// then check_permissions should return false.
|
||||
role_change_permission($roleids['student'], $context, 'mod/workshop:exportownsubmission', CAP_PREVENT);
|
||||
role_change_permission($roleids['student'], $context, 'mod/workshop:exportownsubmissionassessment', CAP_PREVENT);
|
||||
$this->assertFalse($portfoliocaller->check_permissions());
|
||||
|
||||
// Case 2: If user has capabilities exportownsubmission allowed and exportownsubmissionassessment prevented
|
||||
// then check_permissions should return false.
|
||||
role_change_permission($roleids['student'], $context, 'mod/workshop:exportownsubmission', CAP_ALLOW);
|
||||
role_change_permission($roleids['student'], $context, 'mod/workshop:exportownsubmissionassessment', CAP_PREVENT);
|
||||
$this->assertFalse($portfoliocaller->check_permissions());
|
||||
|
||||
// Case 3: If user has capabilities exportownsubmission prevented and exportownsubmissionassessment allowed
|
||||
// then check_permissions should return false.
|
||||
role_change_permission($roleids['student'], $context, 'mod/workshop:exportownsubmission', CAP_PREVENT);
|
||||
role_change_permission($roleids['student'], $context, 'mod/workshop:exportownsubmissionassessment', CAP_ALLOW);
|
||||
$this->assertFalse($portfoliocaller->check_permissions());
|
||||
|
||||
// Case 4: If user has capabilities exportownsubmission allowed and exportownsubmissionassessment allowed
|
||||
// then check_permissions should return true.
|
||||
role_change_permission($roleids['student'], $context, 'mod/workshop:exportownsubmission', CAP_ALLOW);
|
||||
role_change_permission($roleids['student'], $context, 'mod/workshop:exportownsubmissionassessment', CAP_ALLOW);
|
||||
$this->assertTrue($portfoliocaller->check_permissions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function check_permissions()
|
||||
* Case 2: User exports submission.
|
||||
* Assert that this function can return a boolean value
|
||||
* to indicate that the user has capability to export submission.
|
||||
*/
|
||||
public function test_check_permissions_exportownsubmission() {
|
||||
global $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$context = context_module::instance($this->cm->id);
|
||||
$student1 = $this->getDataGenerator()->create_user();
|
||||
$roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
|
||||
$this->getDataGenerator()->enrol_user($student1->id, $this->workshop->course->id, $roleids['student']);
|
||||
$workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
|
||||
$subid1 = $workshopgenerator->create_submission($this->workshop->id, $student1->id);
|
||||
$this->setUser($student1);
|
||||
|
||||
$portfoliocaller = new mod_workshop_portfolio_caller(array('submissionid' => $subid1));
|
||||
$reflector = new ReflectionObject($portfoliocaller);
|
||||
$cm = $reflector->getProperty('cm');
|
||||
$cm->setAccessible(true);
|
||||
$cm->setValue($portfoliocaller, $this->cm);
|
||||
|
||||
// Case 1: If user has capability to export submission then check_permissions should return true.
|
||||
role_change_permission($roleids['student'], $context, 'mod/workshop:exportownsubmission', CAP_ALLOW);
|
||||
$this->assertTrue($portfoliocaller->check_permissions());
|
||||
|
||||
// Case 2: If user doesn't have capability to export submission then check_permissions should return false.
|
||||
role_change_permission($roleids['student'], $context, 'mod/workshop:exportownsubmission', CAP_PREVENT);
|
||||
$this->assertFalse($portfoliocaller->check_permissions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function get_sha1()
|
||||
* Case 1: User exports the assessment of his/her own submission.
|
||||
* Assert that this function can return a hash string.
|
||||
*/
|
||||
public function test_get_sha1_assessment() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$student1 = $this->getDataGenerator()->create_user();
|
||||
$student2 = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($student1->id, $this->workshop->course->id);
|
||||
$this->getDataGenerator()->enrol_user($student2->id, $this->workshop->course->id);
|
||||
$workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
|
||||
$subid1 = $workshopgenerator->create_submission($this->workshop->id, $student1->id);
|
||||
$asid1 = $workshopgenerator->create_assessment($subid1, $student2->id);
|
||||
|
||||
$portfoliocaller = new mod_workshop_portfolio_caller(array('submissionid' => $subid1, 'assessmentid' => $asid1));
|
||||
$portfoliocaller->load_data();
|
||||
|
||||
$this->assertTrue(is_string($portfoliocaller->get_sha1()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function get_sha1()
|
||||
* Case 2: User exports his/her own submission.
|
||||
* Assert that this function can return a hash string.
|
||||
*/
|
||||
public function test_get_sha1_submission() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$student1 = $this->getDataGenerator()->create_user();
|
||||
$student2 = $this->getDataGenerator()->create_user();
|
||||
$this->getDataGenerator()->enrol_user($student1->id, $this->workshop->course->id);
|
||||
$this->getDataGenerator()->enrol_user($student2->id, $this->workshop->course->id);
|
||||
$workshopgenerator = $this->getDataGenerator()->get_plugin_generator('mod_workshop');
|
||||
$subid1 = $workshopgenerator->create_submission($this->workshop->id, $student1->id);
|
||||
|
||||
$portfoliocaller = new mod_workshop_portfolio_caller(array('submissionid' => $subid1));
|
||||
$portfoliocaller->load_data();
|
||||
|
||||
$this->assertTrue(is_string($portfoliocaller->get_sha1()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test function display_name()
|
||||
* Assert that this function can return the name of the module ('Workshop').
|
||||
*/
|
||||
public function test_display_name() {
|
||||
$this->resetAfterTest(true);
|
||||
$this->assertEquals('Workshop', mod_workshop_portfolio_caller::display_name());
|
||||
}
|
||||
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2016052300; // The current module version (YYYYMMDDXX)
|
||||
$plugin->version = 2016062901; // The current module version (YYYYMMDDXX)
|
||||
$plugin->requires = 2016051900; // Requires this Moodle version.
|
||||
$plugin->component = 'mod_workshop';
|
||||
$plugin->cron = 60; // Give as a chance every minute.
|
||||
|
Loading…
x
Reference in New Issue
Block a user