Commit b34c4321 authored by Astor Bizard's avatar Astor Bizard
Browse files

Cherry-pick of various fixes from original VPL 3.3.8. Date 04/12/2020

parent 9fec1c7d
This diff is collapsed.
This diff is collapsed.
......@@ -385,12 +385,12 @@ define(['jquery',
VPLUtil.delay('updateFileList', self.updateFileList);
return file;
} else {
showError(str('filenotadded').replace(/\{\$a\}/g, file.name));
showError(str('filenotadded', file.name));
return false;
}
}
if (fileNameIncluded(file.name) || twoBlockly('', file.name)) {
showError(str('filenotadded').replace(/\{\$a\}/g, file.name));
showError(str('filenotadded', file.name));
return false;
}
if (files.length >= maxNumberOfFiles) {
......@@ -443,7 +443,7 @@ define(['jquery',
}
files[pos].setFileName(newname);
} catch (e) {
showError(str('filenotrenamed').replace(/\{\$a\}/g, newname) + ': ' + e);
showError(str('filenotrenamed', newname) + ': ' + e);
return false;
}
self.setModified();
......@@ -454,11 +454,11 @@ define(['jquery',
this.deleteFile = function(name, ok, showError) {
var pos = this.fileNameExists(name);
if (pos == -1) {
showError(str('filenotdeleted').replace(/\{\$a\}/g, name));
showError(str('filenotdeleted', name));
return false;
}
if (pos < minNumberOfFiles) {
showError(str('filenotdeleted').replace(/\{\$a\}/g, name));
showError(str('filenotdeleted', name));
return false;
}
self.setModified();
......@@ -1392,7 +1392,7 @@ define(['jquery',
return;
}
var filename = file.getFileName();
var message = str('delete_file_fq').replace(/\{\$a\}/g, filename);
var message = str('delete_file_fq', filename);
showMessage(message, {
ok : function() {
fileManager.deleteFile(filename, showErrorMessage);
......
......@@ -436,11 +436,16 @@ define(['jquery',
};
(function() {
var i18n = {};
VPLUtil.str = function(key) {
var strreg = /\{\\*\$a\\*}/g;
VPLUtil.str = function(key, parm) {
if (!i18n[key]) {
return '{' + key + '}';
}
return i18n[key];
if (typeof parm != 'undefined') {
return i18n[key].replace(strreg, parm);
} else {
return i18n[key];
}
};
VPLUtil.setStr = function(newi18n) {
for (var key in newi18n) {
......
......@@ -35,7 +35,7 @@ abstract class base extends \core\event\base {
if (($this->relateduserid) && $this->relateduserid != $this->userid) {
$parms ['userid'] = $this->relateduserid;
}
return new \moodle_url( 'mod/vpl/' . $script, $parms );
return new \moodle_url( '/mod/vpl/' . $script, $parms );
}
public function get_description() {
return '';
......
<?php
// This file is part of VPL for Moodle - http://vpl.dis.ulpgc.es/
//
// VPL for 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.
//
// VPL for 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 VPL for Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A schedule task for VPL cron.
*
* @package mod_vpl
* @copyright 2020 onwards Juan Carlos Rodrguez-del-Pino
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Juan Carlos Rodrguez-del-Pino <jcrodriguez@dis.ulpgc.es>
*/
namespace mod_vpl\task;
defined( 'MOODLE_INTERNAL' ) || die();
class cron_task extends \core\task\scheduled_task {
/**
* Get a descriptive name for this task shown in admin screens.
*
* @return string
*/
public function get_name() {
return get_string('crontask', 'mod_vpl');
}
/**
* Run assignment cron.
*/
public function execute() {
global $CFG, $DB;
require_once($CFG->dirroot . '/mod/vpl/vpl.class.php');
$rebuilds = array ();
$now = time();
$sql = 'SELECT id, startdate, duedate, course, name FROM {vpl}
WHERE startdate > ?
and startdate <= ?
and (duedate > ? or duedate = 0)';
$parms = array (
$now - (2 * 3600),
$now,
$now
);
$vpls = $DB->get_records_sql( $sql, $parms );
foreach ($vpls as $instance) {
if (! instance_is_visible( VPL, $instance )) {
$vpl = new \mod_vpl( null, $instance->id );
echo 'Setting visible "' . s( $vpl->get_printable_name() ) . '"\n';
$cm = $vpl->get_course_module();
set_coursemodule_visible( $cm->id, true );
$rebuilds [$cm->course] = $cm->course;
}
}
foreach ($rebuilds as $courseid) {
rebuild_course_cache( $courseid );
}
return true;
}
}
\ No newline at end of file
......@@ -45,7 +45,7 @@ $capabilities = array (
'archetypes' => array (
'guest' => CAP_PROHIBIT,
'student' => CAP_ALLOW,
'teacher' => CAP_PREVENT,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'manager' => CAP_ALLOW
......
<?php
// This file is part of VPL for Moodle - http://vpl.dis.ulpgc.es/
//
// VPL for 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.
//
// VPL for 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 VPL for Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
*
* @package mod_vpl
* @copyright 2020 Juan Carlos Rodrguez-del-Pino
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Juan Carlos Rodrguez-del-Pino <jcrodriguez@dis.ulpgc.es>
*/
defined( 'MOODLE_INTERNAL' ) || die();
$tasks = [
[
'classname' => '\mod_vpl\task\cron_task',
'blocking' => 0,
'minute' => '*/5',
'hour' => '*',
'day' => '*',
'month' => '*',
'dayofweek' => '*'
]
];
\ No newline at end of file
......@@ -281,16 +281,19 @@ class mod_vpl_webservice extends external_api {
$vpl = self::initial_checks( $id, $password );
$vpl->require_capability( VPL_SUBMIT_CAPABILITY );
$instance = $vpl->get_instance();
if (! $vpl->is_submit_able()) {
if (! $vpl->is_submit_able() || $instance->example || ! $instance->evaluate) {
throw new Exception( get_string( 'notavailable' ) );
}
if ($instance->example or $instance->restrictededitor or ! $instance->evaluate) {
$res = mod_vpl_edit::execute( $vpl, $USER->id, 'evaluate' );
if ( empty($res->monitorPath) ) {
throw new Exception( get_string( 'notavailable' ) );
}
$ret = mod_vpl_edit::execute( $vpl, $USER->id, 'evaluate' );
return array (
'monitorURL' => $ret->monitorURL
);
$monitorurl = 'ws://' . $res->server . ':' . $res->port . '/' . $res->monitorPath;
$smonitorurl = 'wss://' . $res->server . ':' . $res->securePort . '/' . $res->monitorPath;
return array ( 'monitorURL' => $monitorurl, 'smonitorURL' => $smonitorurl );
}
public static function evaluate_returns() {
$desc = "URL to the service that monitor the evaluation in the jail server.
......@@ -304,7 +307,8 @@ The jail send information as text in this format:
'close': the conection is to be closed.
if the websocket client send something to the server then the evaluation is stopped.";
return new external_single_structure( array (
'monitorURL' => new external_value( PARAM_RAW, $desc )
'monitorURL' => new external_value( PARAM_RAW, $desc ),
'smonitorURL' => new external_value( PARAM_RAW, $desc )
) );
}
......
......@@ -200,6 +200,7 @@ class file_group_process {
foreach ($filelist as $f) {
$filehash [$f] = 1;
}
vpl_create_dir($this->dir);
foreach ($files as $filename => $data) {
if ( !isset($filehash[$filename]) ) {
$filelist[] = $filename;
......@@ -407,7 +408,7 @@ class file_group_process {
die();
}
}
/**
* return the directory file
* @return string
......
......@@ -62,12 +62,15 @@ try {
$userid = $USER->id;
$vpl->require_capability( VPL_SUBMIT_CAPABILITY );
$vpl->restrictions_check();
} else { // Make other user submission.
$vpl->require_capability( VPL_MANAGE_CAPABILITY );
} else { // Access other user submission.
$vpl->require_capability( VPL_GRADE_CAPABILITY );
}
$instance = $vpl->get_instance();
switch ($action) {
case 'save' :
if ($userid != $USER->id) {
$vpl->require_capability( VPL_MANAGE_CAPABILITY );
}
$files = mod_vpl_edit::filesfromide( $actiondata->files );
if (! isset($actiondata->comments) ) {
$actiondata->comments = '';
......@@ -78,13 +81,13 @@ try {
$files = mod_vpl_edit::get_requested_files( $vpl );
$outcome->response->files = mod_vpl_edit::filestoide( $files );
break;
case 'correctedfiles' :
$fgm = $vpl->get_fgm('corrected');
$files = $fgm->getallfiles();
$outcome->response->files = mod_vpl_edit::filestoide( $files );
break;
case 'correctedfiles' :
$fgm = $vpl->get_fgm('corrected');
$files = $fgm->getallfiles();
$outcome->response->files = mod_vpl_edit::filestoide( $files );
break;
case 'load' :
if ( $subid && $vpl->has_capability( VPL_MANAGE_CAPABILITY ) ) {
if ( $subid && $vpl->has_capability( VPL_GRADE_CAPABILITY ) ) {
$load = mod_vpl_edit::load( $vpl, $userid , $subid);
} else {
$load = mod_vpl_edit::load( $vpl, $userid );
......
......@@ -47,12 +47,11 @@ if (! $userid || $userid == $USER->id) { // Edit own submission.
$userid = $USER->id;
$vpl->require_capability( VPL_SUBMIT_CAPABILITY );
} else { // Edit other user submission.
$vpl->require_capability( VPL_MANAGE_CAPABILITY );
$vpl->require_capability( VPL_GRADE_CAPABILITY );
}
$vpl->restrictions_check();
$instance = $vpl->get_instance();
$manager = $vpl->has_capability(VPL_MANAGE_CAPABILITY);
$grader = $vpl->has_capability(VPL_GRADE_CAPABILITY);
// This code allow to edit previous versions (only managers).
......@@ -75,9 +74,9 @@ $options = Array();
$options ['id'] = $id;
$options ['restrictededitor'] = $instance->restrictededitor && ! $grader;
$options ['save'] = ! $instance->example;
$options ['run'] = ($instance->run || $manager);
$options ['debug'] = ($instance->debug || $manager);
$options ['evaluate'] = ($instance->evaluate || $manager);
$options ['run'] = ($instance->run || $grader);
$options ['debug'] = ($instance->debug || $grader);
$options ['evaluate'] = ($instance->evaluate || $grader);
$options ['example'] = true && $instance->example;
$options ['comments'] = ! $options ['example'];
$options ['description'] = $vpl->get_fulldescription_with_basedon();
......
......@@ -156,7 +156,7 @@ class mod_vpl_grade_form extends moodleform {
}
if (! empty( $CFG->enableoutcomes )) {
$gradinginfo = grade_get_grades( $vpl->get_course()->id, 'mod', 'vpl', $vplinstance->id, $userid );
$gradinginfo = grade_get_grades( $this->vpl->get_course()->id, 'mod', 'vpl', $vplinstance->id, $userid );
if (! empty( $gradinginfo->outcomes )) {
$mform->addElement('html', '<table border="0">' );
foreach ($gradinginfo->outcomes as $oid => $outcome) {
......
......@@ -31,11 +31,13 @@ defined('MOODLE_INTERNAL') || die();
*/
class vpl_running_processes {
const TABLE = 'vpl_running_processes';
static public function get($userid) {
static public function get($userid, $vplid = false) {
global $DB;
return $DB->get_record( self::TABLE, array (
'userid' => $userid
) );
$params = array ( 'userid' => $userid );
if ( $vplid !== false ) {
$params[ 'vpl' ] = $vplid;
}
return $DB->get_record( self::TABLE, $params );
}
static public function set($userid, $server, $vplid, $adminticket) {
global $DB;
......
......@@ -61,6 +61,7 @@ $string ['console'] = 'Console';
$string ['copy'] = 'Copy';
$string ['correctedfiles'] = 'Corrected files';
$string ['create_new_file'] = 'Create a new file';
$string ['crontask'] = 'Shows VPL activities that reach the "Available from" time';
$string ['currentstatus'] = 'Current status';
$string ['custom'] = 'Custom';
$string ['cut'] = 'Cut';
......@@ -246,7 +247,6 @@ $string ['running'] = 'Running';
$string ['runscript'] = 'Run script';
$string ['runscript_help'] = 'Select the run script to use in this activity';
$string ['save'] = 'Save';
$string ['save'] = 'Save';
$string ['savecontinue'] = 'Save and continue';
$string ['saved'] = 'Saved';
$string ['savedfile'] = "The '{\$a}' file has been saved";
......@@ -271,7 +271,7 @@ $string ['shortdescription'] = 'Short description';
$string ['shortcuts'] = 'Keyboard shortcuts';
$string ['similarity'] = 'Similarity';
$string ['similarto'] = 'Similar to';
$string ['startdate'] = 'Avaliable from';
$string ['startdate'] = 'Available from';
$string ['submission'] = 'Submission';
$string ['submissionperiod'] = 'Submission period';
$string ['submissionrestrictions'] = 'Submission restrictions';
......
......@@ -45,19 +45,17 @@ function vpl_grade_item_update($instance, $grades=null) {
if ( isset($instance->cmidnumber) ) {
$itemdetails['idnumber'] = $instance->cmidnumber;
}
if ($instance->grade > 0) {
if ($instance->grade == 0 || $instance->example != 0) {
$itemdetails['gradetype'] = GRADE_TYPE_NONE;
$itemdetails['deleted'] = 1;
} else if ($instance->grade > 0) {
$itemdetails['gradetype'] = GRADE_TYPE_VALUE;
$itemdetails['grademax'] = $instance->grade;
$itemdetails['grademin'] = 0;
} else if ($instance->grade < 0) {
} else {
$itemdetails['gradetype'] = GRADE_TYPE_SCALE;
$itemdetails['scaleid'] = -$instance->grade;
}
if ($instance->grade == 0 || $instance->example != 0) {
$itemdetails['gradetype'] = GRADE_TYPE_NONE;
$itemdetails['deleted'] = 1;
}
if ($grades === 'reset') {
......@@ -645,43 +643,6 @@ function vpl_extend_settings_navigation(settings_navigation $settings, navigatio
}
}
/**
* Run periodically to check for vpl visibility update
*
* @uses $CFG
* @return boolean
*
*/
function vpl_cron() {
global $DB;
$rebuilds = array ();
$now = time();
$sql = 'SELECT id, startdate, duedate, course, name
FROM {vpl}
WHERE startdate > ?
and startdate <= ?
and (duedate > ? or duedate = 0)';
$parms = array (
$now - (2 * 3600),
$now,
$now
);
$vpls = $DB->get_records_sql( $sql, $parms );
foreach ($vpls as $instance) {
if (! instance_is_visible( VPL, $instance )) {
$vpl = new mod_vpl( null, $instance->id );
echo 'Setting visible "' . s( $vpl->get_printable_name() ) . '"';
$cm = $vpl->get_course_module();
$rebuilds [$cm->id] = $cm;
}
}
foreach ($rebuilds as $cmid => $cm) {
set_coursemodule_visible( $cm->id, true );
rebuild_course_cache( $cm->course );
}
return true;
}
/**
* Must return an array of user records (all data) who are participants for a given instance
* of vpl. Must include every user involved in the instance, independient of his role
......@@ -835,7 +796,7 @@ function vpl_reset_userdata($data) {
'vpl' => $instance->id
) );
// Delete submission files.
fulldelete( $CFG->dataroot . '/vpl_data/' . $data->courseid . '/' . $instance->id . '/usersdata' );
fulldelete( $CFG->dataroot . '/vpl_data/' . $instance->id . '/usersdata' );
$status [] = array (
'component' => $componentstr,
'item' => get_string( 'resetvpl', VPL, $instance->name ),
......
......@@ -67,6 +67,20 @@ function vpl_get_set_session_var($varname, $default, $parname = null) {
return $res;
}
/**
* Create directory if not exist
*
* @param $dir string path to directory
*/
function vpl_create_dir($dir) {
global $CFG;
if (! file_exists( $dir )) { // Create dir?
if (! mkdir( $dir, $CFG->directorypermissions, true ) ) {
throw new file_exception('storedfileproblem', 'Error creating a directory to save files in VPL');
}
}
}
/**
* Open/create a file and its dir
*
......@@ -74,15 +88,14 @@ function vpl_get_set_session_var($varname, $default, $parname = null) {
* @return resource file descriptor
*/
function vpl_fopen($filename) {
global $CFG;
if (! file_exists( $filename )) { // Exists file?
$dir = dirname( $filename );
if (! file_exists( $dir )) { // Create dir?
mkdir( $dir, $CFG->directorypermissions, true );
}
vpl_create_dir($dir);
}
$fp = fopen( $filename, 'wb+' );
if ($fp === false) {
throw new file_exception('storedfileproblem', 'Error creating file in VPL');
}
return $fp;
}
......@@ -442,8 +455,8 @@ function vpl_get_select_time($maximum = null) {
function vpl_get_max_post_size() {
$maxs = trim( ini_get( 'post_max_size' ) );
$len = strlen( $maxs );
$max = ( int ) $maxs;
$last = strtolower( $maxs [$len - 1] );
$max = ( int ) substr( $maxs, 0, $len - 1 );
if ($last == 'k') {
$max *= 1024;
} else if ($last == 'm') {
......@@ -451,6 +464,9 @@ function vpl_get_max_post_size() {
} else if ($last == 'g') {
$max *= 1024 * 1024 * 1000;
}
if ($maxs === '0') {
$max = PHP_INT_MAX;
}
return $max;
}
......
......@@ -182,7 +182,7 @@ class vpl_clusters {
$files = array ();
$matrix = array ();
for ($i = 0; $i < $numfiles; $i ++) {
$matriz [] = array ();
$matrix [] = array ();
}
foreach ($cluster as $pair) {
$files [$pair->first->id] = $pair->first;
......
......@@ -79,7 +79,7 @@ class vpl_diff {
$limit = strlen( $ran1 );
if ($limit > 0) {
if ($limit > 3) {
$limite = 3;
$limit = 3;
}
if (strncmp( $ran1, self::removealphanum( $line2 ), $limit ) == 0) {
return 2;
......@@ -126,12 +126,12 @@ class vpl_diff {
// Update first column.
for ($i = 0; $i <= $nl1; $i ++) {
$matriz [$i] [0] = 0;
$matrix [$i] [0] = 0;
$prev [$i] [0] = - 1;
}
// Update first row.
for ($j = 1; $j <= $nl2; $j ++) {
$matriz [0] [$j] = 0;
$matrix [0] [$j] = 0;
$prev [0] [$j] = 1;
}
}
......@@ -170,6 +170,8 @@ class vpl_diff {
}
return $ret;
}
$matrix = [];
$prev = [];
self::initauxiliarmatrices( $matrix, $prev, $nl1, $nl2 );
// Matrix processing.
......@@ -311,7 +313,6 @@ class vpl_diff {
echo '</div>';
echo '<div style="clear:both;"></div>';
// Files.
$pre = '<pre clas="vpl_g">';
echo '<div style="float:left; text-align: right; width: 3em">';
$shower = vpl_sh_factory::get_sh( 'a.txt' );
$shower->print_file( 'a.txt', $datal1, false, count($diff) + 1, false );
......@@ -320,11 +321,11 @@ class vpl_diff {
$shower = vpl_sh_factory::get_sh( $filename1 );
$shower->print_file( $filename1, $data1, false, count($diff) + 1, false );
echo '</div>';
echo '<div style="float:left; width: 3em"">';
echo '<div style="float:left; width: 3em">';
$shower = vpl_sh_factory::get_sh( 'b.txt' );
$shower->print_file( 'b.txt', $diffl, false, count($diff) + 1, false );
echo '</div>';
echo '<div style="float:left; text-align: right; width: 3em"">';
echo '<div style="float:left; text-align: right; width: 3em">';
$shower = vpl_sh_factory::get_sh( 'b.txt' );
$shower->print_file( 'b.txt', $datal2, false, count($diff) + 1, false );
echo '</div>';
......@@ -370,7 +371,6 @@ class vpl_diff {
\mod_vpl\event\vpl_diff_viewed::log( $submission );
}
} else if ($type == 3) {
global $CFG;
$data = '';
$vplid = required_param( 'vplid' . $f, PARAM_INT );
$vpl = new mod_vpl( false, $vplid );
......
......@@ -28,6 +28,8 @@ require_once(dirname(__FILE__).'/../locallib.php');
require_once(dirname(__FILE__).'/../vpl.class.php');
require_once(dirname(__FILE__).'/diff.class.php');
global $COURSE, $PAGE, $OUTPUT;
require_course_login( $COURSE );
$strdiff = get_string( 'diff', VPL );
$PAGE->set_url( '/mod/vpl/similarity/diff.php' );
......@@ -36,9 +38,15 @@ $PAGE->set_pagelayout( 'popup' );
vpl_sh_factory::include_js();
echo $OUTPUT->header();
$htmlheader1 = '';
$filename1 = '';
$data1 = '';
// Get left file.
vpl_diff::vpl_get_similfile( '1', $htmlheader1, $filename1, $data1 );
$htmlheader2 = '';
$filename2 = '';
$data2 = '';
// Get right file.
vpl_diff::vpl_get_similfile( '2', $htmlheader2, $filename2, $data2 );
......