diff --git a/admin/tool/uploadcourse/README.txt b/admin/tool/uploadcourse/README.txt deleted file mode 100644 index 5ee935491a0..00000000000 --- a/admin/tool/uploadcourse/README.txt +++ /dev/null @@ -1,196 +0,0 @@ -moodle-tool_uploadcourse -======================== - -Is a Moodle admin/tools plugin for uploading course outlines -in much the same way that admin/tools/uploaduser works for users. -These plugins became available from Moodle 2.2x and onwards, as -this is when the admin/tools framework first appeared. - -https://gitorious.org/moodle-tool_uploadcourse - -There is also a bulk course category upload function available at https://gitorious.org/moodle-tool_uploadcoursecategory - -If you need to manage course enrolments via bulk upload then you should look at -the core user upload facility - http://docs.moodle.org/22/en/Upload_users - -This takes CSV files as input and enables override or augmentation -with default parameter values. - -All the usual add,updated,rename, and delete functions. - - -Thanks to Moshe Golden for help with getting the command line interface going. - - -!!!! NOTE !!!! -=============== - -This plugin used to come with the full directory structure -admin/tool/uploadcourse - this is nolonger the case so the -installation proceedure has changed! - -General installation proceedures are here: -http://docs.moodle.org/20/en/Installing_contributed_modules_or_plugins - -The basic process is: -Download https://gitorious.org/moodle-tool_uploadcourse/moodle-tool_uploadcourse/archive-tarball/master -unpack the file (probably called master) with tar -xzvf master -This will give you a directory called moodle-tool_uploadcourse-moodle-tool_uploadcourse -Move this directory and rename it into it's final position: -mv moodle-tool_uploadcourse-moodle-tool_uploadcourse /admin/tool/uploadcourse - -Alternatively you can use git: -cd /admin/tool -git clone git@gitorious.org:moodle-tool_uploadcourse/moodle-tool_uploadcourse.git uploadcourse - -Be careful about leaving the .git directory in your live environment. - - -CSV File format -=============== - -Possible column names are: -fullname, shortname, category, idnumber, summary, -format, showgrades, newsitems, teacher, editingteacher, student, modinfo, -manager, coursecreator, guest, user, startdate, numsections, maxbytes, visible, groupmode, restrictmodules, -enablecompletion, completionstartonenrol, completionnotify, hiddensections, groupmodeforce, lang, theme, -cost, showreports, notifystudents, expirynotify, expirythreshold, requested, -deleted, // 1 means delete course -oldshortname, // for renaming -backupfile, // for restoring a course template after creation -templatename, // course to use as a template - the shortname -reset, // reset the course contents after upload - this resets everything - - so you loose groups, roles, logs, grades etc. Be Careful!!! - -An example file is: - -fullname,shortname,category,idnumber,summary,backupfile -Computer Science 101,CS101,Cat1,CS101,The first thing you will ever know,/path/to/backup-moodle2-course-cs101-20120213-0748-nu.mbz - -As a general rule, the input values for fields are what you find on the data entry form if you inspect the HTML element. - -Format -====== -The options for the format value are 'scorm', 'social', weeks', and 'topics'. - -Role Names -=========== - 'teacher', 'editingteacher', 'student', 'manager', -'coursecreator', 'guest', 'user' are - where config permitting - you can -substitute your own name for these roles (string value). - -Category -======== -For category you must supply the category name as it is in Moodle and this -field is case sensitive. If Sub Categories are involved then the full -category hierarchy needs to be specified as a '/' delimited string eg: -'Miscellaneous / Sub Cat / Sub Sub Cat'. The delimiter can be escaped with -a back slash eg: 'some\/category'. - -Course Templating -================= -add column backupfile which has the fully qualified path name to a file on -the server that has a a Moodle course backup in it. - -Add a column templatename which is the shortname of an existing course that -will be copied over the top of the new course. - -Course Enrolment Methods -========================= - -Enrolment methods need special CSV columns as there can be many per course, and the fields for each -method are flexible. The following is an example with two enrolment methods - manual, and self - firstly you need -the column identifying the enrolment method enrolmethod_, and then add the corresponding field values subscripted with _. -eg: -fullname,shortname,category,idnumber,summary,enrolmethod_1,status_1,enrolmethod_2,name_2,password_2,customtext1_2 -Parent,Parent,,Parent,Parent,manual,1,self,self1,letmein,this is a custom message 1 -Students,Students,,Students,Students,manual,0,self,self2,letmein,this is a custom message 2 -Teachers,Teachers,,Teachers,Teachers,manual,0,self,self3,letmein,this is a custom message 3 - -add the special columns for: - * delete - delete_ with value 1 - * disable - disable_ with value 1 - -startdate enrol_startdate enrol_enddate -======================================= -For startdate enrolstartdate, and enrolenddate the values should be supplied in the form like 31.01.2012 or -31/01/2012 that can be consumed by strtotime() (http://php.net/manual/en/function.strtotime.php) - check -your PHP locale settings for the fine tuning eg: m/d/y vs d/m/y. - -Enrolment method field 'enrolperiod' must be in seconds. If this is supplied then enrolenddate will be calculated -as enrolstartdate + enrolperiod. - -enrolperiod should be supplied in multiples of enrolment period measurements - 1 hour = 3600, 1 day = 86400 -and so on. OR - you can pass a text string that php strtotime() can recognise eg: '2 weeks' or '10 days' - -Enrolment Method Role -===================== -Default Role for an enrolment method is supplied by adding the 'role_' column. The expected value is the -descriptive label for the given role eg: 'Student', or "Teacher'. - -Enrolment example: -fullname,shortname,category,idnumber,summary,enrolmethod_1,enrolperiod_1,role_1 -a name,short1,Miscellaneous,id1,a summary,manual,864000,Manager - -Update Course: -================= -Make sure you have shortname in the csv. After uploading the file, select: -Upload type: one of the update existing related options -Existing course details: Overide with file -Allow Renames: Yes - -Update example: -fullname,shortname -new full name,short1 - - -Run it in batch mode -===================== -Execute Course Upload in batch mode - this must be run as the www-data user (or the equivalent user that the web server runs under). - -Options: --v, --verbose Print verbose progress information --h, --help Print out this help --a, --action Action to perform - addnew, addupdate, update, forceadd --m, --mode Mode of execution - delete, rename, nochange, file, filedefaults, missing --f, --file CSV File --d, --delimiter delimiter - colon,semicolon,tab,cfg,comma --e, --encoding File encoding - utf8 etc --c, --category Course category --s, --templateshortname Template course by shortname --t, --template Template course by backup file --g, --format Course format - weeks,scorm,social,topics --n, --numsections Number of sections - - -Example: -sudo -u www-data /usr/bin/php admin/tool/uploadcourse/cli/uploadcourse.php --action=addupdate \ - --mode=delete --file=./courses.csv --delimiter=comma - - - -Installation -================= -git clone this repository into /admin/tools/uploadcourse directory. - -Point your browser at Moodle, and login as admin. This should kick off -the upgrade so that Moodle can now recognise the new plugin. - -This was inspired in part by a need for a complimentary function for uploading -courses (as for users) for the the NZ MLE tools for Identity and -Access Managment (synchronising users with the School SMS): -https://gitorious.org/pla-udi -and -https://gitorious.org/pla-udi/mle_ide_tools - -Copyright (C) Piers Harding 2011 and beyond, All rights reserved - -moodle-tool_uploadcourse free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. diff --git a/admin/tool/uploadcourse/classes/base_form.php b/admin/tool/uploadcourse/classes/base_form.php index 8d4e796077f..fc0ddf9a3db 100644 --- a/admin/tool/uploadcourse/classes/base_form.php +++ b/admin/tool/uploadcourse/classes/base_form.php @@ -55,18 +55,19 @@ class tool_uploadcourse_base_form extends moodleform { $mform->setExpanded('importoptionshdr', true); $choices = array( - tool_uploadcourse_processor::MODE_CREATE_NEW => get_string('ccoptype_addnew', 'tool_uploadcourse'), - tool_uploadcourse_processor::MODE_CREATE_ALL => get_string('ccoptype_addinc', 'tool_uploadcourse'), - tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE => get_string('ccoptype_addupdate', 'tool_uploadcourse'), - tool_uploadcourse_processor::MODE_UPDATE_ONLY => get_string('ccoptype_update', 'tool_uploadcourse') + tool_uploadcourse_processor::MODE_CREATE_NEW => get_string('createnew', 'tool_uploadcourse'), + tool_uploadcourse_processor::MODE_CREATE_ALL => get_string('createall', 'tool_uploadcourse'), + tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE => get_string('createorupdate', 'tool_uploadcourse'), + tool_uploadcourse_processor::MODE_UPDATE_ONLY => get_string('updateonly', 'tool_uploadcourse') ); $mform->addElement('select', 'options[mode]', get_string('mode', 'tool_uploadcourse'), $choices); $choices = array( tool_uploadcourse_processor::UPDATE_NOTHING => get_string('nochanges', 'tool_uploadcourse'), - tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY => get_string('ccupdatefromfile', 'tool_uploadcourse'), - tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_OR_DEFAUTLS => get_string('ccupdateall', 'tool_uploadcourse'), - tool_uploadcourse_processor::UPDATE_MISSING_WITH_DATA_OR_DEFAUTLS => get_string('ccupdatemissing', 'tool_uploadcourse') + tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY => get_string('updatewithdataonly', 'tool_uploadcourse'), + tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_OR_DEFAUTLS => + get_string('updatewithdataordefaults', 'tool_uploadcourse'), + tool_uploadcourse_processor::UPDATE_MISSING_WITH_DATA_OR_DEFAUTLS => get_string('updatemissing', 'tool_uploadcourse') ); $mform->addElement('select', 'options[updatemode]', get_string('updatemode', 'tool_uploadcourse'), $choices); $mform->setDefault('options[updatemode]', tool_uploadcourse_processor::UPDATE_NOTHING); diff --git a/admin/tool/uploadcourse/classes/course.php b/admin/tool/uploadcourse/classes/course.php index 27817458bf7..48ccc313e3b 100644 --- a/admin/tool/uploadcourse/classes/course.php +++ b/admin/tool/uploadcourse/classes/course.php @@ -206,8 +206,11 @@ class tool_uploadcourse_course { * @return bool */ public function can_update() { - return in_array($this->mode, array(tool_uploadcourse_processor::MODE_UPDATE_ONLY, - tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE)) && $this->updatemode != tool_uploadcourse_processor::UPDATE_NOTHING; + return in_array($this->mode, + array( + tool_uploadcourse_processor::MODE_UPDATE_ONLY, + tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE) + ) && $this->updatemode != tool_uploadcourse_processor::UPDATE_NOTHING; } /** @@ -227,7 +230,8 @@ class tool_uploadcourse_course { */ protected function delete() { global $DB; - $this->id = $DB->get_field_select('course', 'id', 'shortname = :shortname', array('shortname' => $this->shortname), MUST_EXIST); + $this->id = $DB->get_field_select('course', 'id', 'shortname = :shortname', + array('shortname' => $this->shortname), MUST_EXIST); return delete_course($this->id, false); } @@ -248,6 +252,7 @@ class tool_uploadcourse_course { /** * Return whether the course exists or not. * + * @param string $shortname the shortname to use to check if the course exists. Falls back on $this->shortname if empty. * @return bool */ protected function exists($shortname = null) { @@ -424,7 +429,8 @@ class tool_uploadcourse_course { // Can we create/update the course under those conditions? if ($exists) { if ($this->mode === tool_uploadcourse_processor::MODE_CREATE_NEW) { - $this->error('courseexistsanduploadnotallowed', new lang_string('courseexistsanduploadnotallowed', 'tool_uploadcourse')); + $this->error('courseexistsanduploadnotallowed', + new lang_string('courseexistsanduploadnotallowed', 'tool_uploadcourse')); return false; } } else { @@ -520,7 +526,8 @@ class tool_uploadcourse_course { new lang_string('cannotgenerateshortnameupdatemode', 'tool_uploadcourse')); return false; } else { - $newshortname = tool_uploadcourse_helper::generate_shortname($coursedata, $this->importoptions['shortnametemplate']); + $newshortname = tool_uploadcourse_helper::generate_shortname($coursedata, + $this->importoptions['shortnametemplate']); if (is_null($newshortname)) { $this->error('generatedshortnameinvalid', new lang_string('generatedshortnameinvalid', 'tool_uploadcourse')); return false; @@ -639,7 +646,7 @@ class tool_uploadcourse_course { // TODO log warnings. $this->restoredata = $this->get_restore_content_dir(); - // We cannot + // We can only reset courses when allowed and we are updating the course. if ($this->importoptions['reset'] || $this->options['reset']) { if ($this->do !== self::DO_UPDATE) { $this->error('canonlyresetcourseinupdatemode', @@ -837,6 +844,7 @@ class tool_uploadcourse_course { * * This does not reset any of the content of the activities. * + * @param stdClass $course the course object of the course to reset. * @return array status array of array component, item, error. */ protected function reset($course) { diff --git a/admin/tool/uploadcourse/classes/helper.php b/admin/tool/uploadcourse/classes/helper.php index c5f51563fb0..ad1e36d917a 100644 --- a/admin/tool/uploadcourse/classes/helper.php +++ b/admin/tool/uploadcourse/classes/helper.php @@ -29,10 +29,13 @@ require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php'); /** * Class containing a set of helpers. + * + * @package tool_uploadcourse + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tool_uploadcourse_helper { - /** @var array category idnumber cache. */ static protected $categoryidnumbercache = array(); diff --git a/admin/tool/uploadcourse/classes/processor.php b/admin/tool/uploadcourse/classes/processor.php index 3fd57fe420b..94ab8a7ec7e 100644 --- a/admin/tool/uploadcourse/classes/processor.php +++ b/admin/tool/uploadcourse/classes/processor.php @@ -257,7 +257,6 @@ class tool_uploadcourse_processor { /** * Get the directory of the object to restore. * - * @param string $default directory to use if none found. * @return string subdirectory in $CFG->tempdir/backup/... */ protected function get_restore_content_dir() { diff --git a/admin/tool/uploadcourse/classes/step2_form.php b/admin/tool/uploadcourse/classes/step2_form.php index 502000730d6..711dd6322e2 100644 --- a/admin/tool/uploadcourse/classes/step2_form.php +++ b/admin/tool/uploadcourse/classes/step2_form.php @@ -51,7 +51,8 @@ class tool_uploadcourse_step2_form extends tool_uploadcourse_base_form { $mform->addElement('header', 'courseoptionshdr', get_string('courseprocess', 'tool_uploadcourse')); $mform->setExpanded('courseoptionshdr', true); - $mform->addElement('text', 'options[shortnametemplate]', get_string('shortnametemplate', 'tool_uploadcourse'), 'maxlength="100" size="20"'); + $mform->addElement('text', 'options[shortnametemplate]', get_string('shortnametemplate', 'tool_uploadcourse'), + 'maxlength="100" size="20"'); $mform->setType('options[shortnametemplate]', PARAM_RAW); $mform->addHelpButton('options[shortnametemplate]', 'shortnametemplate', 'tool_uploadcourse'); $mform->disabledIf('options[shortnametemplate]', 'options[mode]', 'eq', tool_uploadcourse_processor::MODE_CREATE_OR_UPDATE); @@ -113,7 +114,7 @@ class tool_uploadcourse_step2_form extends tool_uploadcourse_base_form { $mform->addElement('select', 'defaults[theme]', get_string('forcetheme'), $themes); } - $languages[] = array(); + $languages = array(); $languages[''] = get_string('forceno'); $languages += get_string_manager()->get_list_of_translations(); $mform->addElement('select', 'defaults[lang]', get_string('forcelanguage'), $languages); @@ -162,8 +163,8 @@ class tool_uploadcourse_step2_form extends tool_uploadcourse_base_form { $mform->setDefault('defaults[groupmodeforce]', $courseconfig->groupmodeforce); // Hidden fields. - $mform->addElement('hidden', 'iid'); - $mform->setType('iid', PARAM_INT); + $mform->addElement('hidden', 'importid'); + $mform->setType('importid', PARAM_INT); $mform->addElement('hidden', 'previewrows'); $mform->setType('previewrows', PARAM_INT); @@ -180,7 +181,7 @@ class tool_uploadcourse_step2_form extends tool_uploadcourse_base_form { * @param string $submitlabel label for submit button, defaults to get_string('savechanges') * @return void */ - function add_action_buttons($cancel = true, $submitlabel = null){ + public function add_action_buttons($cancel = true, $submitlabel = null) { $mform =& $this->_form; $buttonarray = array(); $buttonarray[] = &$mform->createElement('submit', 'showpreview', get_string('preview', 'tool_uploadcourse')); diff --git a/admin/tool/uploadcourse/classes/tracker.php b/admin/tool/uploadcourse/classes/tracker.php index 4c307ea221f..23374f60b88 100644 --- a/admin/tool/uploadcourse/classes/tracker.php +++ b/admin/tool/uploadcourse/classes/tracker.php @@ -207,7 +207,8 @@ class tool_uploadcourse_tracker { echo html_writer::start_tag('table', array('class' => 'generaltable boxaligncenter flexible-wrap', 'summary' => get_string('uploadcoursesresult', 'tool_uploadcourse'))); echo html_writer::start_tag('tr', array('class' => 'heading r' . $this->rownb)); - echo html_writer::tag('th', get_string('csvline', 'tool_uploadcourse'), array('class' => 'c' . $ci++, 'scope' => 'col')); + echo html_writer::tag('th', get_string('csvline', 'tool_uploadcourse'), + array('class' => 'c' . $ci++, 'scope' => 'col')); echo html_writer::tag('th', get_string('result', 'tool_uploadcourse'), array('class' => 'c' . $ci++, 'scope' => 'col')); echo html_writer::tag('th', get_string('id', 'tool_uploadcourse'), array('class' => 'c' . $ci++, 'scope' => 'col')); echo html_writer::tag('th', get_string('shortname'), array('class' => 'c' . $ci++, 'scope' => 'col')); diff --git a/admin/tool/uploadcourse/cli/uploadcourse.php b/admin/tool/uploadcourse/cli/uploadcourse.php index 573af090d51..0e2fefc0441 100644 --- a/admin/tool/uploadcourse/cli/uploadcourse.php +++ b/admin/tool/uploadcourse/cli/uploadcourse.php @@ -25,7 +25,6 @@ define('CLI_SCRIPT', true); require(__DIR__ . '/../../../../config.php'); -require_once(__DIR__ . '/../locallib.php'); require_once($CFG->libdir . '/clilib.php'); require_once($CFG->libdir . '/coursecatlib.php'); require_once($CFG->libdir . '/csvlib.class.php'); @@ -188,8 +187,8 @@ cron_setup_user(); // Let's get started! $content = file_get_contents($options['file']); -$iid = csv_import_reader::get_new_iid('uploadcourse'); -$cir = new csv_import_reader($iid, 'uploadcourse'); +$importid = csv_import_reader::get_new_iid('uploadcourse'); +$cir = new csv_import_reader($importid, 'uploadcourse'); $readcount = $cir->load_csv_content($content, $options['encoding'], $options['delimiter']); unset($content); if ($readcount === false) { diff --git a/admin/tool/uploadcourse/index.php b/admin/tool/uploadcourse/index.php index 152579bb1f9..667551efd44 100644 --- a/admin/tool/uploadcourse/index.php +++ b/admin/tool/uploadcourse/index.php @@ -23,24 +23,22 @@ */ require(__DIR__ . '/../../../config.php'); -require_once(__DIR__ . '/locallib.php'); require_once($CFG->libdir . '/adminlib.php'); -require_once($CFG->libdir . '/clilib.php'); require_once($CFG->libdir . '/coursecatlib.php'); require_once($CFG->libdir . '/csvlib.class.php'); admin_externalpage_setup('tooluploadcourse'); -$iid = optional_param('iid', '', PARAM_INT); +$importid = optional_param('importid', '', PARAM_INT); $previewrows = optional_param('previewrows', 10, PARAM_INT); $returnurl = new moodle_url('/admin/tool/uploadcourse/index.php'); -if (empty($iid)) { +if (empty($importid)) { $mform1 = new tool_uploadcourse_step1_form(); if ($form1data = $mform1->get_data()) { - $iid = csv_import_reader::get_new_iid('uploadcourse'); - $cir = new csv_import_reader($iid, 'uploadcourse'); + $importid = csv_import_reader::get_new_iid('uploadcourse'); + $cir = new csv_import_reader($importid, 'uploadcourse'); $content = $mform1->get_file_content('coursefile'); $readcount = $cir->load_csv_content($content, $form1data->encoding, $form1data->delimiter_name); unset($content); @@ -57,11 +55,11 @@ if (empty($iid)) { die(); } } else { - $cir = new csv_import_reader($iid, 'uploadcourse'); + $cir = new csv_import_reader($importid, 'uploadcourse'); } // Data to set in the form. -$data = array('iid' => $iid, 'previewrows' => $previewrows); +$data = array('importid' => $importid, 'previewrows' => $previewrows); if (!empty($form1data)) { // Get options from the first form to pass it onto the second. foreach ($form1data->options as $key => $value) { diff --git a/admin/tool/uploadcourse/lang/en/tool_uploadcourse.php b/admin/tool/uploadcourse/lang/en/tool_uploadcourse.php index f9d634e9c68..691d2c816ff 100644 --- a/admin/tool/uploadcourse/lang/en/tool_uploadcourse.php +++ b/admin/tool/uploadcourse/lang/en/tool_uploadcourse.php @@ -15,11 +15,9 @@ // along with Moodle. If not, see . /** - * Strings for component 'tool_uploadcourse', language 'en', branch 'MOODLE_22_STABLE' + * Strings for component 'tool_uploadcourse'. * * @package tool_uploadcourse - * @subpackage uploadcourse - * @copyright 2011 Petr Skoda {@link http://skodak.org} * @copyright 2011 Piers Harding * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -61,6 +59,9 @@ $string['coursetemplatename'] = 'Restore from this course after upload'; $string['coursetemplatename_help'] = 'Enter an existing course shortname to use as a template for the creation of all courses.'; $string['coursetorestorefromdoesnotexist'] = 'The course to restore from does not exist'; $string['courseupdated'] = 'Course updated'; +$string['createall'] = 'Create all, increment shortname if needed'; +$string['createnew'] = 'Create new courses only, skip existing ones'; +$string['createorupdate'] = 'Create new courses, or update existing ones'; $string['csvdelimiter'] = 'CSV delimiter'; $string['csvfileerror'] = 'There is something wrong with the format of the CSV file. Please check the number of headings and columns match, and that the delimiter and file encoding are correct: {$a}'; $string['csvline'] = 'Line'; @@ -84,6 +85,8 @@ $string['invalidshortname'] = 'Invalid shortname'; $string['missingmandatoryfields'] = 'Missing value for mandatory fields: {$a}'; $string['missingshortnamenotemplate'] = 'Missing shortname and shortname template not set'; $string['mode'] = 'Upload mode'; +$string['nochanges'] = 'No changes'; +$string['pluginname'] = 'Course upload'; $string['preview'] = 'Preview'; $string['reset'] = 'Reset course after upload'; $string['result'] = 'Result'; @@ -94,8 +97,12 @@ $string['shortnametemplate_help'] = 'The short name of the course is displayed i $string['templatefile'] = 'Restore from this file after upload'; $string['templatefile_help'] = 'Select a file to use as a template for the creation of all courses.'; $string['unknownimportmode'] = 'Unknown import mode'; +$string['updatemissing'] = 'Fill in missing from CSV data and defaults'; $string['updatemode'] = 'Update mode'; $string['updatemodedoessettonothing'] = 'Update mode does not allow anything to be updated'; +$string['updateonly'] = 'Only update existing courses'; +$string['updatewithdataordefaults'] = 'Update with CSV data and defaults'; +$string['updatewithdataonly'] = 'Update with CSV data only'; $string['uploadcourses'] = 'Upload courses'; $string['uploadcourses_help'] = 'Courses may be uploaded via text file. The format of the file should be as follows: @@ -103,89 +110,5 @@ $string['uploadcourses_help'] = 'Courses may be uploaded via text file. The form * Each record is a series of data separated by commas (or other delimiters) * The first record contains a list of fieldnames defining the format of the rest of the file * Required fieldnames are shortname, fullname, summary and category'; -$string['uploadcoursesresult'] = 'Upload courses results'; - - - - - -$string['deleteerrors'] = 'Delete errors'; -$string['errors'] = 'Errors'; -$string['invalidinput'] = 'You must specify a valid combination of --action and --mode'; -$string['nochanges'] = 'No changes'; -$string['pluginname'] = 'Course upload'; -$string['renameerrors'] = 'Rename errors'; -$string['requiredtemplate'] = 'Required. You may use template syntax here (%l = lastname, %f = firstname, %u = coursename). See help for details and examples.'; -$string['uploadpicture_badcoursefield'] = 'The course attribute specified is not valid. Please, try again.'; -$string['uploadpicture_cannotmovezip'] = 'Cannot move zip file to temporary directory.'; -$string['uploadpicture_cannotprocessdir'] = 'Cannot process unzipped files.'; -$string['uploadpicture_cannotsave'] = 'Cannot save picture for course {$a}. Check original picture file.'; -$string['uploadpicture_cannotunzip'] = 'Cannot unzip pictures file.'; -$string['uploadpicture_invalidfilename'] = 'Picture file {$a} has invalid characters in its name. Skipping.'; -$string['uploadpicture_overwrite'] = 'Overwrite existing course pictures?'; -$string['uploadpicture_coursefield'] = 'Course attribute to use to match pictures:'; -$string['uploadpicture_coursenotfound'] = 'Course with a \'{$a->coursefield}\' value of \'{$a->coursevalue}\' does not exist. Skipping.'; -$string['uploadpicture_courseskipped'] = 'Skipping course {$a} (already has a picture).'; -$string['uploadpicture_courseupdated'] = 'Picture updated for course {$a}.'; -$string['uploadpictures'] = 'Upload course pictures'; -$string['uploadpictures_help'] = 'Course pictures can be uploaded as a zip file of image files. The image files should be named chosen-course-attribute.extension, for example course1234.jpg for a course with coursename course1234.'; - $string['uploadcoursespreview'] = 'Upload courses preview'; -$string['courseuptodate'] = 'Course up-to-date'; -$string['courseupdated'] = 'Course updated'; -$string['coursedeleted'] = 'Course deleted'; -$string['courserenamed'] = 'Course renamed'; -$string['coursesrenamed'] = 'Courses renamed'; -$string['coursesskipped'] = 'Courses skipped'; -$string['coursenotadded'] = 'Course not added - already exists'; -$string['coursenotaddederror'] = 'Course not added - error'; -$string['coursenotdeletederror'] = 'Course not deleted - error'; -$string['coursenotdeletedmissing'] = 'Course not deleted - missing'; -$string['coursenotdeletedoff'] = 'Course not deleted - delete off'; -$string['coursenotdeletedadmin'] = 'Course not deleted - no admin access'; -$string['coursenotupdatederror'] = 'Course not updated - error'; -$string['coursenotupdatednotexists'] = 'Course not updated - does not exist'; -$string['coursenotupdatedadmin'] = 'Course not updated - no admin'; -$string['coursenotrenamedexists'] = 'Course not renamed - target exists'; -$string['coursenotrenamedmissing'] = 'Course not renamed - source missing'; -$string['coursenotrenamedoff'] = 'Course not renamed - renaming off'; -$string['coursenotrenamedadmin'] = 'Course not renamed - no admin'; -$string['invalidvalue'] = 'Invalid value for field {$a}'; -$string['shortnamecourse'] = 'Shortname'; - -$string['idnumbernotunique'] = 'idnumber is not unique'; -$string['ccbulk'] = 'Select for bulk operations'; -$string['ccbulkall'] = 'All courses'; -$string['ccbulknew'] = 'New courses'; -$string['ccbulkupdated'] = 'Updated courses'; -$string['cclegacy1role'] = '(Original Student) typeN=1'; -$string['cclegacy2role'] = '(Original Teacher) typeN=2'; -$string['cclegacy3role'] = '(Original Non-editing teacher) typeN=3'; -$string['ccnoemailduplicates'] = 'Prevent email address duplicates'; - -$string['ccoptype_addinc'] = 'Add all, append number to shortnames if needed'; -$string['ccoptype_addnew'] = 'Add new only, skip existing courses'; -$string['ccoptype_addupdate'] = 'Add new and update existing courses'; -$string['ccoptype_update'] = 'Update existing courses only'; -$string['ccpasswordcron'] = 'Generated in cron'; -$string['ccpasswordnew'] = 'New course password'; -$string['ccpasswordold'] = 'Existing course password'; -$string['ccstandardshortnames'] = 'Standardise shortnames'; -$string['ccupdateall'] = 'Override with file and defaults'; -$string['ccupdatefromfile'] = 'Override with file'; -$string['ccupdatemissing'] = 'Fill in missing from file and defaults'; -$string['ccupdatetype'] = 'Existing course details'; - -$string['ccfullnametemplate'] = 'Fullname template'; -$string['ccidnumbertemplate'] = 'Idnumber template'; -$string['missingtemplate'] = 'Template not found'; -$string['missing'] = 'missing'; -$string['incorrectformat'] = 'Invalid format specified'; -$string['incorrecttemplatefile'] = 'Template file not found'; -$string['invalidenrolmethod'] = 'Invalid enrolment method'; -$string['invalidaction'] = 'Invalid action selected'; - - -$string['invalidcategory'] = 'Invalid category'; -$string['invalidbackupfile'] = 'Invalid backup file'; - +$string['uploadcoursesresult'] = 'Upload courses results'; diff --git a/admin/tool/uploadcourse/locallib.php b/admin/tool/uploadcourse/locallib.php deleted file mode 100644 index 79ba08f9791..00000000000 --- a/admin/tool/uploadcourse/locallib.php +++ /dev/null @@ -1,1328 +0,0 @@ -. - -/** - * Bulk course registration functions - * - * @package tool_uploadcourse - * @subpackage uploadcourse - * @copyright 2004 onwards Martin Dougiamas (http://dougiamas.com) - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -define('CC_COURSE_ADDNEW', 0); -define('CC_COURSE_ADDINC', 1); -define('CC_COURSE_ADD_UPDATE', 2); -define('CC_COURSE_UPDATE', 3); - -define('CC_UPDATE_NOCHANGES', 0); -define('CC_UPDATE_FILEOVERRIDE', 1); -define('CC_UPDATE_ALLOVERRIDE', 2); -define('CC_UPDATE_MISSING', 3); - -define('CC_BULK_NEW', 1); -define('CC_BULK_UPDATED', 2); -define('CC_BULK_ALL', 3); - -define('CC_PWRESET_NONE', 0); -define('CC_PWRESET_WEAK', 1); -define('CC_PWRESET_ALL', 2); -define('CC_BULK_NONE', 0); - - -/** - * Return the list of stad fields the course upload processes - */ -function tool_uploadcourse_std_fields() { - // Array of all valid fields for validation. - return $std_fields = array('fullname', 'shortname', 'category', 'idnumber', 'summary', - 'format', 'showgrades', 'newsitems', 'teacher', 'editingteacher', 'student', 'modinfo', - 'manager', 'coursecreator', 'guest', 'user', 'startdate', 'numsections', - 'maxbytes', 'visible', 'groupmode', 'restrictmodules', - 'enablecompletion', 'completionstartonenrol', 'completionnotify', - 'hiddensections', 'groupmodeforce', 'lang', 'theme', - 'cost', 'showreports', 'notifystudents', 'expirynotify', 'expirythreshold', 'requested', - 'deleted', // 1 means delete course. - 'oldshortname', // For renaming. - 'backupfile', // For restoring a course template after creation. - 'templatename', // Course to use as a template - the shortname. - 'reset', - // There are also the enrolment fields but these are free form as they vary on enrolment type - // eg: enrolmethod_1,status_1,enrolmethod_2,name_2,password_2,customtext1_2 - // manual, 1, self, self1, letmein, this is a custom message 1. - ); -} - -/** - * process the upload - * - * @param object $formdata - object of the form data - * @param object $cir - object of the CSV importer - * @param array $filecolumns - file column definitions - * @param string $restorefile - file to restore from - * @param boolean $plain - plain text output - */ -function tool_uploadcourse_process_course_upload($formdata, $cir, $filecolumns, $restorefile=null, $plain=false) { - global $CFG, $USER, $OUTPUT, $SESSION, $DB; - - $std_fields = tool_uploadcourse_std_fields(); - - @set_time_limit(60*60); // 1 hour should be enough. - raise_memory_limit(MEMORY_HUGE); - - require_capability('moodle/course:create', get_context_instance(CONTEXT_SYSTEM)); - require_capability('moodle/course:update', get_context_instance(CONTEXT_SYSTEM)); - require_capability('moodle/course:delete', get_context_instance(CONTEXT_SYSTEM)); - - $strcourserenamed = get_string('courserenamed', 'tool_uploadcourse'); - $strcoursenotrenamedexists = get_string('coursenotrenamedexists', 'tool_uploadcourse'); - $strcoursenotrenamedmissing = get_string('coursenotrenamedmissing', 'tool_uploadcourse'); - $strcoursenotrenamedoff = get_string('coursenotrenamedoff', 'tool_uploadcourse'); - - $strcourseupdated = get_string('courseupdated', 'tool_uploadcourse'); - $strcoursenotupdated = get_string('coursenotupdatederror', 'tool_uploadcourse'); - $strcoursenotupdatednotexists = get_string('coursenotupdatednotexists', 'tool_uploadcourse'); - - $strcourseuptodate = get_string('courseuptodate', 'tool_uploadcourse'); - - $strcourseadded = get_string('newcourse'); - $strcoursenotadded = get_string('coursenotadded', 'tool_uploadcourse'); - $strcoursenotaddederror = get_string('coursenotaddederror', 'tool_uploadcourse'); - - $strcoursedeleted = get_string('coursedeleted', 'tool_uploadcourse'); - $strcoursenotdeletederror = get_string('coursenotdeletederror', 'tool_uploadcourse'); - $strcoursenotdeletedmissing = get_string('coursenotdeletedmissing', 'tool_uploadcourse'); - $strcoursenotdeletedoff = get_string('coursenotdeletedoff', 'tool_uploadcourse'); - $errorstr = get_string('error'); - - $returnurl = new moodle_url('/admin/tool/uploadcourse/index.php'); - $bulknurl = new moodle_url('/admin/tool/uploadcourse/index.php'); - - $today = time(); - $today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0); - - $optype = $formdata->cctype; - - $updatetype = isset($formdata->ccupdatetype) ? $formdata->ccupdatetype : 0; - $allowrenames = (!empty($formdata->ccallowrenames) and $optype != CC_COURSE_ADDNEW and $optype != CC_COURSE_ADDINC); - $allowdeletes = (!empty($formdata->ccallowdeletes) and $optype != CC_COURSE_ADDNEW and $optype != CC_COURSE_ADDINC); - $bulk = isset($formdata->ccbulk) ? $formdata->ccbulk : 0; - $standardshortnames = $formdata->ccstandardshortnames; - - // Check for the template. - $templatepathname = null; - if (!empty($formdata->templatename) && $formdata->templatename != 'none') { - $template = $DB->get_record('course', array('shortname' => $formdata->templatename)); - - // Backup the course template. - $bc = new backup_controller(backup::TYPE_1COURSE, $template->id, backup::FORMAT_MOODLE, - backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id); - $backupid = $bc->get_backupid(); - $backupbasepath = $bc->get_plan()->get_basepath(); - $bc->execute_plan(); - $bc->destroy(); - $packer = get_file_packer('application/zip'); - // Check if tmp dir exists. - $tmpdir = $CFG->tempdir . '/backup'; - if (!check_dir_exists($tmpdir, true, true)) { - throw new restore_controller_exception('cannot_create_backup_temp_dir'); - } - $filename = restore_controller::get_tempdir_name(SITEID, $USER->id); - $templatepathname = $tmpdir . '/' . $filename; - // Get the list of files in directory. - $filestemp = get_directory_list($backupbasepath, '', false, true, true); - $files = array(); - foreach ($filestemp as $file) { - // Add zip paths and fs paths to all them. - $files[$file] = $backupbasepath . '/' . $file; - } - $zippacker = get_file_packer('application/zip'); - $zippacker->archive_to_pathname($files, $templatepathname); - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($backupbasepath); - } - } - - // Check the uploaded backup file. - if (!empty($formdata->restorefile)) { - // Check if tmp dir exists. - if ($restorefile) { - $filepath = restore_controller::get_tempdir_name(SITEID, $USER->id); - $packer = get_file_packer('application/zip'); - $restorepathname = "$CFG->tempdir/backup/$filepath/"; - $result = $packer->extract_to_pathname($restorefile, $restorepathname); - // If not a backup zip file. - if (!$result) { - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($restorepathname); - fulldelete($restorefile); - } - throw new moodle_exception('invalidbackupfile', 'tool_uploadcourse'); - } - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($restorepathname); - } - } else { - $restorefile = null; - } - } - - // Verification moved to two places: after upload and into form2. - $coursesnew = 0; - $coursesupdated = 0; - $coursesuptodate = 0; // Not printed yet anywhere. - $courseserrors = 0; - $deletes = 0; - $deleteerrors = 0; - $renames = 0; - $renameerrors = 0; - $coursesskipped = 0; - $enrolmentplugins = enrol_get_plugins(false); - $courseformats = array_keys(get_plugin_list('format')); - - // Clear bulk selection. - if ($bulk) { - $SESSION->bulk_courses = array(); - } - - // Init csv import helper. - $cir->init(); - $linenum = 1; // Column header is first line. - - // Init upload progress tracker. - $upt = new tool_uploadcourse_progress_tracker($plain); - $upt->start(); // Start table. - - while ($line = $cir->next()) { - $upt->flush(); - $linenum++; - - $upt->track('line', $linenum); - - $course = new stdClass(); - - // Add fields to course object. - foreach ($line as $keynum => $value) { - if (!isset($filecolumns[$keynum])) { - // This should not happen. - continue; - } - $key = $filecolumns[$keynum]; - $course->$key = $value; - - if (in_array($key, $upt->columns)) { - // Default value in progress tracking table, can be changed later. - $upt->track($key, s($value), 'normal'); - } - } - // Validate category. - $error = false; - if (!empty($course->category)) { - $split = preg_split('|(?category); - $categories = array(); - foreach ($split as $cat) { - $cat = preg_replace('/\\\/', '', $cat); - $categories[]= $cat; - } - $course->category = 0; - foreach ($categories as $cat) { - // Does the category exist - does the category hierachy make sense. - $category = $DB->get_record('course_categories', array('name'=>trim($cat), 'parent' => $course->category)); - if (empty($category)) { - $upt->track('status', get_string('invalidvalue', 'tool_uploadcourse', 'category').' ('.$cat.' '.get_string('missing', 'tool_uploadcourse').')', 'error'); - $upt->track('category', $errorstr, 'error'); - $error = true; - break; - } - $course->category = $category->id; - } - } - // Check for category errors. - if ($error) { - $courseserrors++; - continue; - } - - if (!isset($course->shortname)) { - // Prevent warnings bellow. - $course->shortname = ''; - } - if (!empty($course->startdate) && $course->startdate != 0) { - $course->startdate = strtotime($course->startdate); - } - if (!empty($course->enrolstartdate) && $course->enrolstartdate != 0) { - $course->enrolstartdate = strtotime($course->enrolstartdate); - } - - // Check for enrolment methods. - $line_fields = (array) $course; - $enrolmethods = array(); - $enrolments = array(); - $error = false; - foreach ($line_fields as $k => $v) { - if (preg_match('/^(\w+)\_(\d+)$/', $k, $matches)) { - if (!isset($enrolments[$matches[2]])) { - $enrolments[$matches[2]] = array(); - } - if ($matches[1] == 'enrolmethod') { - if (!isset($enrolmentplugins[$v])) { - $upt->track('status', get_string('invalidenrolmethod', 'tool_uploadcourse', 'category'), 'error'); - $upt->track($k, $errorstr, 'error'); - $error = true; - } - $enrolmethods[$v] = $matches[2]; - } - $enrolments[$matches[2]][$matches[1]] = $v; - } - } - if ($error) { - continue; - } - foreach ($enrolmethods as $k => $v) { - $enrolmethods[$k] = $enrolments[$v]; - } - - // Roles. - $roles = get_all_roles(); - foreach ($roles as $role) { - if (isset($course->{$role->shortname})) { - if (in_array($role->shortname, array('teacher', 'editingteacher', 'student', - 'manager', 'coursecreator', 'guest', 'user'))) { - $course->{'role_'.$role->id} = $course->{$role->shortname}; - } - } - } - - // What type of operation is this ? - if ($optype == CC_COURSE_ADDNEW or $optype == CC_COURSE_ADDINC) { - // Course creation is a special case - the shortname may be constructed from templates using firstname and lastname - // better never try this in mixed update types. - $error = false; - if (!isset($course->fullname) or $course->fullname === '') { - $upt->track('status', get_string('missingfield', 'error', 'fullname'), 'error'); - $upt->track('fullname', $errorstr, 'error'); - $error = true; - } - if (!isset($course->summary) or $course->summary === '') { - $upt->track('status', get_string('missingfield', 'error', 'summary'), 'error'); - $upt->track('summary', $errorstr, 'error'); - $error = true; - } - if ($error) { - $courseserrors++; - continue; - } - // We require shortname too - we might use template for it though. - if (empty($course->shortname) and !empty($formdata->ccshortname)) { - $course->shortname = tool_uploadcourse_process_template($formdata->ccshortname, $course); - $upt->track('shortname', s($course->shortname)); - } - } - - // Normalize shortname. - $originalshortname = $course->shortname; - if ($standardshortnames) { - $course->shortname = clean_param($course->shortname, PARAM_MULTILANG); - } - - // Make sure we really have shortname. - if (empty($course->shortname)) { - $upt->track('status', get_string('missingfield', 'error', 'shortname'), 'error'); - $upt->track('shortname', $errorstr, 'error'); - $courseserrors++; - continue; - } - - if ($existingcourse = $DB->get_record('course', array('shortname' => $course->shortname))) { - $upt->track('id', $existingcourse->id, 'normal', false); - } - - // Find out in shortname incrementing required. - if ($existingcourse and $optype == CC_COURSE_ADDINC) { - $course->shortname = tool_uploadcourse_increment_shortname($course->shortname); - if (!empty($course->idnumber)) { - $oldidnumber = $course->idnumber; - $course->idnumber = tool_uploadcourse_increment_idnumber($course->idnumber); - if ($course->idnumber !== $oldidnumber) { - $upt->track('idnumber', s($oldidnumber).'-->'.s($course->idnumber), 'info'); - } - } - $existingcourse = false; - } - - // Check duplicate idnumber. - if (!$existingcourse and !empty($course->idnumber)) { - if ($DB->record_exists('course', array('idnumber' => $course->idnumber))) { - $upt->track('status', get_string('idnumbernotunique', 'tool_uploadcourse'), 'error'); - $upt->track('idnumber', $errorstr, 'error'); - $error = true; - } - } - - // Notify about nay shortname changes. - if ($originalshortname !== $course->shortname) { - $upt->track('shortname', '', 'normal', false); // Clear previous. - $upt->track('shortname', s($originalshortname).'-->'.s($course->shortname), 'info'); - } else { - $upt->track('shortname', s($course->shortname), 'normal', false); - } - - // Add default values for remaining fields. - $formdefaults = array(); - foreach ($std_fields as $field) { - if (isset($course->$field)) { - continue; - } - // All validation moved to form2. - if (isset($formdata->$field)) { - $course->$field = $formdata->$field; - $formdefaults[$field] = true; - if (in_array($field, $upt->columns)) { - $upt->track($field, s($course->$field), 'normal'); - } - } else { - // Process templates. - if (isset($formdata->{"cc".$field}) && !empty($formdata->{"cc".$field}) && empty($course->$field)) { - $course->$field = tool_uploadcourse_process_template($formdata->{"cc".$field}, $course); - } - } - } - // Do we run the reset ? - $resetcourse = false; - if ($course->reset) { - $resetcourse = true; - unset($course->reset); - } - - // Proof visible flag. - $course->visible = (int) $course->visible; - - if (empty($course->category)) { - $course->category = $formdata->cccategory; - } - - // Delete course. - if (!empty($course->deleted)) { - if (!$allowdeletes) { - $coursesskipped++; - $upt->track('status', $strcoursenotdeletedoff, 'warning'); - continue; - } - if ($existingcourse) { - if (delete_course($existingcourse->id, false)) { - $upt->track('status', $strcoursedeleted); - $deletes++; - } else { - $upt->track('status', $strcoursenotdeletederror, 'error'); - $deleteerrors++; - } - } else { - $upt->track('status', $strcoursenotdeletedmissing, 'error'); - $deleteerrors++; - } - continue; - } - // We do not need the deleted flag anymore. - unset($course->deleted); - - // Renaming requested? - if (!empty($course->oldshortname) ) { - if (!$allowrenames) { - $coursesskipped++; - $upt->track('status', $strcoursenotrenamedoff, 'warning'); - continue; - } - - if ($existingcourse) { - $upt->track('status', $strcoursenotrenamedexists, 'error'); - $renameerrors++; - continue; - } - - if ($standardshortnames) { - $oldshortname = clean_param($course->oldshortname, PARAM_MULTILANG); - } else { - $oldshortname = $course->oldshortname; - } - - // No guessing when looking for old shortname, it must be exact match. - if ($oldcourse = $DB->get_record('course', array('shortname'=>$oldshortname))) { - $upt->track('id', $oldcourse->id, 'normal', false); - $DB->set_field('course', 'shortname', $course->shortname, array('id'=>$oldcourse->id)); - $upt->track('shortname', '', 'normal', false); // Clear previous. - $upt->track('shortname', s($oldshortname).'-->'.s($course->shortname), 'info'); - $upt->track('status', $strcourserenamed); - $renames++; - } else { - $upt->track('status', $strcoursenotrenamedmissing, 'error'); - $renameerrors++; - continue; - } - $existingcourse = $oldcourse; - $existingcourse->shortname = $course->shortname; - } - - // Can we process with update or insert? - $skip = false; - switch ($optype) { - case CC_COURSE_ADDNEW: - if ($existingcourse) { - $coursesskipped++; - $upt->track('status', $strcoursenotadded, 'warning'); - $skip = true; - } - break; - - case CC_COURSE_ADDINC: - if ($existingcourse) { - // This should not happen! - $upt->track('status', $strcoursenotaddederror, 'error'); - $courseserrors++; - $skip = true; - } - break; - - case CC_COURSE_ADD_UPDATE: - break; - - case CC_COURSE_UPDATE: - if (!$existingcourse) { - $coursesskipped++; - $upt->track('status', $strcoursenotupdatednotexists, 'warning'); - $skip = true; - } - break; - - default: - // Unknown type. - $skip = true; - } - - // Check for the backup file as template. - $backupfile = null; - if (!empty($course->backupfile)) { - if (!is_readable($course->backupfile) || !preg_match('/(\.mbz|\.zip)$/i', $course->backupfile)) { - $upt->track('status', get_string('incorrecttemplatefile', 'tool_uploadcourse'), 'error'); - $courseserrors++; - $skip = true; - } else { - $backupfile = $course->backupfile; - } - } - - if ($skip) { - continue; - } - - // check the format - if (!empty($course->format) && !in_array($course->format, $courseformats)) { - $upt->track('status', get_string('incorrectformat', 'tool_uploadcourse'), 'error'); - $courseserrors++; - continue; - } - - $templatename = null; - if ($existingcourse) { - $course->id = $existingcourse->id; - - $upt->track('shortname', html_writer::link(new moodle_url('/course/view.php', - array('id '=> $existingcourse->id)), - s($existingcourse->shortname)), - 'normal', false); - - $existingcourse->timemodified = time(); - // Do NOT mess with timecreated or firstaccess here! - $doupdate = false; - - if ($updatetype != CC_UPDATE_NOCHANGES) { - foreach ($std_fields as $column) { - if ($column === 'shortname') { - // These can not be changed here. - continue; - } - if (!property_exists($course, $column) or !property_exists($existingcourse, $column)) { - // This should never happen. - continue; - } - // In the case $updatetype == CC_UPDATE_ALLOVERRIDE we override everything. - if ($updatetype == CC_UPDATE_MISSING) { - if (!is_null($existingcourse->$column) and $existingcourse->$column !== '') { - continue; - } - - } else if ($updatetype == CC_UPDATE_FILEOVERRIDE) { - if (!empty($formdefaults[$column])) { - // Do not override with form defaults. - continue; - } - } - if ($existingcourse->$column !== $course->$column) { - if (in_array($column, $upt->columns)) { - $upt->track($column, s($existingcourse->$column).'-->'.s($course->$column), 'info', false); - } - $existingcourse->$column = $course->$column; - $doupdate = true; - } - } - } - - if ($doupdate) { - // We want only courses that were really updated. - update_course($existingcourse); - $upt->track('status', $strcourseupdated); - $coursesupdated++; - - events_trigger('course_updated', $existingcourse); - - if ($bulk == CC_BULK_UPDATED or $bulk == CC_BULK_ALL) { - if (!in_array($course->id, $SESSION->bulk_courses)) { - $SESSION->bulk_courses[] = $course->id; - } - } - - } else { - // No course information changed. - $upt->track('status', $strcourseuptodate); - $coursesuptodate++; - - if ($bulk == CC_BULK_ALL) { - if (!in_array($course->id, $SESSION->bulk_courses)) { - $SESSION->bulk_courses[] = $course->id; - } - } - } - - } else { - // Save the new course to the database. - $course->timemodified = time(); - $course->timecreated = time(); - - // Create course - insert_record ignores any extra properties. - if (isset($course->templatename) && $course->templatename != 'none') { - $templatename = $course->templatename; - } else { - $templatename = null; - } - try { - $course = create_course($course); - } catch (moodle_exception $e) { - $upt->track('status', $e->getMessage(), 'error'); - $courseserrors++; - $skip = true; - continue; - } - $upt->track('shortname', html_writer::link(new moodle_url('/course/view.php', - array('id' => $course->id)), - s($course->shortname)), - 'normal', false); - - $upt->track('status', $strcourseadded); - $upt->track('id', $course->id, 'normal', false); - $coursesnew++; - - // Make sure course context exists. - get_context_instance(CONTEXT_COURSE, $course->id); - - events_trigger('course_created', $course); - - if ($bulk == CC_BULK_NEW or $bulk == CC_BULK_ALL) { - if (!in_array($course->id, $SESSION->bulk_courses)) { - $SESSION->bulk_courses[] = $course->id; - } - } - } - - // After creation/update, do we need to copy from template nominated in the CSV file? - if (!empty($templatename)) { - $coursetemplate = $DB->get_record('course', array('shortname' => $templatename)); - if (empty($coursetemplate)) { - $upt->track('status', get_string('incorrecttemplatefile', 'tool_uploadcourse'), 'error'); - $courseserrors++; - continue; - } - - // Backup the course template. - $bc = new backup_controller(backup::TYPE_1COURSE, $coursetemplate->id, backup::FORMAT_MOODLE, - backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id); - $backupid = $bc->get_backupid(); - $backupbasepath = $bc->get_plan()->get_basepath(); - $bc->execute_plan(); - $bc->destroy(); - $packer = get_file_packer('application/zip'); - // Check if tmp dir exists. - $tmpdir = $CFG->tempdir . '/backup'; - if (!check_dir_exists($tmpdir, true, true)) { - throw new restore_controller_exception('cannot_create_backup_temp_dir'); - } - $filename = restore_controller::get_tempdir_name(SITEID, $USER->id); - $temppathname = $tmpdir . '/' . $filename; - // Get the list of files in directory. - $filestemp = get_directory_list($backupbasepath, '', false, true, true); - $files = array(); - foreach ($filestemp as $file) { - // Add zip paths and fs paths to all them. - $files[$file] = $backupbasepath . '/' . $file; - } - $zippacker = get_file_packer('application/zip'); - $zippacker->archive_to_pathname($files, $temppathname); - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($backupbasepath); - } - - // Check if tmp dir exists. - $tmpdir = $CFG->tempdir . '/backup'; - $filename = restore_controller::get_tempdir_name($course->id, $USER->id); - $pathname = $tmpdir . '/' . $filename; - $packer = get_file_packer('application/zip'); - $packer->extract_to_pathname($temppathname, $pathname); - - // Restore the backup immediately. - $rc = new restore_controller($filename, $course->id, - backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id, backup::TARGET_CURRENT_ADDING); - // Check if the format conversion must happen first. - if ($rc->get_status() == backup::STATUS_REQUIRE_CONV) { - $rc->convert(); - } - if (!$rc->execute_precheck()) { - $precheckresults = $rc->get_precheck_results(); - if (is_array($precheckresults) && !empty($precheckresults['errors'])) { - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($pathname); - } - echo $output->precheck_notices($precheckresults); - if (!$plain) { - echo $output->continue_button(new moodle_url('/course/view.php', array('id' => $course->id))); - echo $output->footer(); - } - die(); - } - } - $rc->execute_plan(); - $rc->destroy(); - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($pathname); - } - } - - // After creation/update, do we need to copy from template? - if (!empty($templatepathname)) { - // Check if tmp dir exists. - $tmpdir = $CFG->tempdir . '/backup'; - $filename = restore_controller::get_tempdir_name($course->id, $USER->id); - $pathname = $tmpdir . '/' . $filename; - $packer = get_file_packer('application/zip'); - $packer->extract_to_pathname($templatepathname, $pathname); - - // Restore the backup immediately. - $rc = new restore_controller($filename, $course->id, - backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id, backup::TARGET_CURRENT_ADDING); - // Check if the format conversion must happen first. - if ($rc->get_status() == backup::STATUS_REQUIRE_CONV) { - $rc->convert(); - } - if (!$rc->execute_precheck()) { - $precheckresults = $rc->get_precheck_results(); - if (is_array($precheckresults) && !empty($precheckresults['errors'])) { - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($pathname); - } - echo $output->precheck_notices($precheckresults); - if (!$plain) { - echo $output->continue_button(new moodle_url('/course/view.php', array('id' => $course->id))); - echo $output->footer(); - } - die(); - } - } - $rc->execute_plan(); - $rc->destroy(); - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($pathname); - } - } - - // After creation/update, do we need to copy from template backup file? - if (!empty($restorefile)) { - // Check if tmp dir exists. - $tmpdir = $CFG->tempdir . '/backup'; - $filename = restore_controller::get_tempdir_name($course->id, $USER->id); - $pathname = $tmpdir . '/' . $filename; - $packer = get_file_packer('application/zip'); - $packer->extract_to_pathname($restorefile, $pathname); - - // Restore the backup immediately. - $rc = new restore_controller($filename, $course->id, - backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id, backup::TARGET_CURRENT_ADDING); - // Check if the format conversion must happen first. - if ($rc->get_status() == backup::STATUS_REQUIRE_CONV) { - $rc->convert(); - } - if (!$rc->execute_precheck()) { - $precheckresults = $rc->get_precheck_results(); - if (is_array($precheckresults) && !empty($precheckresults['errors'])) { - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($pathname); - } - echo $output->precheck_notices($precheckresults); - if (!$plain) { - echo $output->continue_button(new moodle_url('/course/view.php', array('id' => $course->id))); - echo $output->footer(); - } - die(); - } - } - $rc->execute_plan(); - $rc->destroy(); - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($pathname); - } - } - - // After creation/update, do we need to import a Moodle backup? - if (!empty($backupfile)) { - // Check if tmp dir exists. - $tmpdir = $CFG->tempdir . '/backup'; - if (!check_dir_exists($tmpdir, true, true)) { - throw new restore_controller_exception('cannot_create_backup_temp_dir'); - } - $filename = restore_controller::get_tempdir_name($course->id, $USER->id); - $pathname = $tmpdir . '/' . $filename; - $packer = get_file_packer('application/zip'); - $packer->extract_to_pathname($backupfile, $pathname); - - // Restore the backup immediately. - $rc = new restore_controller($filename, $course->id, - backup::INTERACTIVE_NO, backup::MODE_IMPORT, $USER->id, backup::TARGET_CURRENT_ADDING); - // Check if the format conversion must happen first. - if ($rc->get_status() == backup::STATUS_REQUIRE_CONV) { - $rc->convert(); - } - if (!$rc->execute_precheck()) { - $precheckresults = $rc->get_precheck_results(); - if (is_array($precheckresults) && !empty($precheckresults['errors'])) { - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($pathname); - } - echo $output->precheck_notices($precheckresults); - if (!$plain) { - echo $output->continue_button(new moodle_url('/course/view.php', array('id' => $course->id))); - echo $output->footer(); - } - die(); - } - } - $rc->execute_plan(); - $rc->destroy(); - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($pathname); - } - } - - // Handle enrolment methods. - $enrol_updated = false; - $instances = enrol_get_instances($course->id, false); - foreach ($enrolments as $method) { - if (isset($method['delete']) && $method['delete']) { - // Remove the enrolment method. - foreach ($instances as $instance) { - if ($instance->enrol == $method['enrolmethod']) { - $plugin = $enrolmentplugins[$instance->enrol]; - $plugin->delete_instance($instance); - $enrol_updated = true; - break; - } - } - } else if (isset($method['disable']) && $method['disable']) { - // Disable the enrolment. - foreach ($instances as $instance) { - if ($instance->enrol == $method['enrolmethod']) { - $plugin = $enrolmentplugins[$instance->enrol]; - $plugin->update_status($instance, ENROL_INSTANCE_DISABLED); - $enrol_updated = true; - break; - } - } - } else { - // We should have this enrolment method. - $instance = null; - foreach ($instances as $i) { - if ($i->enrol == $method['enrolmethod']) { - $instance = $i; - break; - } - } - $plugin = null; - if (empty($instance)) { - $plugin = $enrolmentplugins[$method['enrolmethod']]; - $instance = new stdClass(); - $instance->id = $plugin->add_default_instance($course); - $instance->roleid = $plugin->get_config('roleid'); - } else { - $plugin = $enrolmentplugins[$instance->enrol]; - $plugin->update_status($instance, ENROL_INSTANCE_ENABLED); - } - // Now update values. - foreach ($method as $k => $v) { - $instance->{$k} = $v; - } - - // Sort out the start, end and date. - $instance->enrolstartdate = (isset($method['startdate']) ? strtotime($method['startdate']) : 0); - $instance->enrolenddate = (isset($method['enddate']) ? strtotime($method['enddate']) : 0); - - // Is the enrolment period set? - if (isset($method['enrolperiod']) && ! empty($method['enrolperiod'])) { - if (preg_match('/^\d+$/', $method['enrolperiod'])) { - $method['enrolperiod'] = (int) $method['enrolperiod']; - } else { - // Try and convert period to seconds. - $method['enrolperiod'] = strtotime('1970-01-01 GMT + ' . $method['enrolperiod']); - } - $instance->enrolperiod = $method['enrolperiod']; - } - if ($instance->enrolstartdate > 0 && isset($method['enrolperiod'])) { - $instance->enrolenddate = $instance->enrolstartdate + $method['enrolperiod']; - } - if ($instance->enrolenddate > 0) { - $instance->enrolperiod = $instance->enrolenddate - $instance->enrolstartdate; - } - if ($instance->enrolenddate < $instance->enrolstartdate) { - $instance->enrolenddate = $instance->enrolstartdate; - } - // Sort out the given Role. - if (isset($method['role'])) { - $context = context_course::instance($course->id); - $roles = get_default_enrol_roles($context, $plugin->get_config('roleid')); - if (!empty($roles)) { - $roles = array_flip($roles); - } - if (isset($roles[$method['role']])) { - $instance->roleid = $roles[$method['role']]; - } - } - $instance->status = ENROL_INSTANCE_ENABLED; - $instance->timemodified = time(); - $DB->update_record('enrol', $instance); - $enrol_updated = true; - } - } - - // Do the course reset. - if ($resetcourse) { - $resetdata = new stdClass(); - $resetdata->reset_start_date = time(); - $resetdata->id = $course->id; - $resetdata->reset_events = true; - $resetdata->reset_logs = true; - $resetdata->reset_notes = true; - $resetdata->reset_comments = true; - $resetdata->reset_completion = true; - $resetdata->delete_blog_associations = true; - $roles = get_assignable_roles(context_course::instance($course->id)); - $roles[0] = get_string('noroles', 'role'); - $roles = array_reverse($roles, true); - $resetdata->reset_roles_local = true; - $resetdata->reset_gradebook_items = true; - $resetdata->reset_gradebook_grades = true; - $resetdata->reset_gradebook_items = true; - $resetdata->reset_groups_remove = true; - $resetdata->reset_groups_members = true; - $resetdata->reset_groupings_remove = true; - $resetdata->reset_groupings_members = true; - $resetdata->reset_groups_remove = true; - $resetdata->reset_groups_remove = true; - $resetdata->reset_start_date_old = $course->startdate; - $status = reset_course_userdata($resetdata); - } - - if ($enrol_updated) { - $coursesupdated++; - } - // Invalidate all enrol caches. - $context = context_course::instance($course->id); - $context->mark_dirty(); - } - - // Clean up backup files. - if (!empty($template)) { - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($backupbasepath); - } - } - if (!empty($restorefile)) { - if (empty($CFG->keeptempdirectoriesonbackup)) { - fulldelete($restorefile); - } - } - - $upt->close(); // Close table. - - $cir->close(); - $cir->cleanup(true); - $systemcontext = context_system::instance(); - mark_context_dirty($systemcontext->path); - - if (!$plain) { - echo $OUTPUT->box_start('boxwidthnarrow boxaligncenter generalbox', 'uploadresults'); - echo '

'; - if ($optype != CC_COURSE_UPDATE) { - echo get_string('coursescreated', 'tool_uploadcourse').': '.$coursesnew.'
'; - } - if ($optype == CC_COURSE_UPDATE or $optype == CC_COURSE_ADD_UPDATE) { - echo get_string('coursesupdated', 'tool_uploadcourse').': '.$coursesupdated.'
'; - } - if ($allowdeletes) { - echo get_string('coursesdeleted', 'tool_uploadcourse').': '.$deletes.'
'; - echo get_string('deleteerrors', 'tool_uploadcourse').': '.$deleteerrors.'
'; - } - if ($allowrenames) { - echo get_string('coursesrenamed', 'tool_uploadcourse').': '.$renames.'
'; - echo get_string('renameerrors', 'tool_uploadcourse').': '.$renameerrors.'
'; - } - if ($coursesskipped) { - echo get_string('coursesskipped', 'tool_uploadcourse').': '.$coursesskipped.'
'; - } - echo get_string('errors', 'tool_uploadcourse').': '.$courseserrors.'

'; - } else { - if ($optype != CC_COURSE_UPDATE) { - echo get_string('coursescreated', 'tool_uploadcourse').': '.$coursesnew."\n"; - } - if ($optype == CC_COURSE_UPDATE or $optype == CC_COURSE_ADD_UPDATE) { - echo get_string('coursesupdated', 'tool_uploadcourse').': '.$coursesupdated."\n"; - } - if ($allowdeletes) { - echo get_string('coursesdeleted', 'tool_uploadcourse').': '.$deletes."\n"; - echo get_string('deleteerrors', 'tool_uploadcourse').': '.$deleteerrors."\n"; - } - if ($allowrenames) { - echo get_string('coursesrenamed', 'tool_uploadcourse').': '.$renames."\n"; - echo get_string('renameerrors', 'tool_uploadcourse').': '.$renameerrors."\n"; - } - if ($coursesskipped) { - echo get_string('coursesskipped', 'tool_uploadcourse').': '.$coursesskipped."\n"; - } - echo get_string('errors', 'tool_uploadcourse').': '.$courseserrors."\n"; - echo "The End.\n"; - } -} - - -/** - * Tracking of processed courses. - * - * This class prints course information into a html table. - * - * @copyright 2007 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class tool_uploadcourse_progress_tracker { - /** @var int $_row - row marker */ - private $_row; - /** @var array $columns - output columns */ - public $columns = array('status', 'line', 'id', 'fullname', 'shortname', 'category', 'idnumber', 'summary', 'deleted'); - /** @var boolean $_plain - output is text mode */ - private $_plain; - - /** - * Constructor - * - * @param boolean $type - is this plain text output - */ - public function __construct($type = false) { - $this->_plain = $type; - } - - - /** - * Print table header. - * @return void - */ - public function start() { - $ci = 0; - if ($this->_plain) { - echo "\n\t".get_string('status')."\t".get_string('cccsvline', 'tool_uploadcourse')."\tID\t". - get_string('fullname')."\t".get_string('shortname')."\t".get_string('category')."\t". - get_string('idnumber')."\t".get_string('summary')."\t".get_string('delete')."\n"; - } else { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - $this->_row = null; - } - - /** - * Flush previous line and start a new one. - * @return void - */ - public function flush() { - if (empty($this->_row) or empty($this->_row['line']['normal'])) { - // Nothing to print - each line has to have at least number. - $this->_row = array(); - foreach ($this->columns as $col) { - $this->_row[$col] = array('normal'=>'', 'info'=>'', 'warning'=>'', 'error'=>''); - } - return; - } - $ci = 0; - $ri = 1; - echo $this->_plain ? "" : ''; - foreach ($this->_row as $key => $field) { - foreach ($field as $type => $content) { - if ($field[$type] !== '') { - $field[$type] = $this->_plain ? $field[$type] : ''.$field[$type].''; - } else { - unset($field[$type]); - } - } - echo $this->_plain ? "\t" : ''; - } - echo $this->_plain ? "\n" : ''; - foreach ($this->columns as $col) { - $this->_row[$col] = array('normal'=>'', 'info'=>'', 'warning'=>'', 'error'=>''); - } - } - - /** - * Add tracking info - * @param string $col name of column - * @param string $msg message - * @param string $level 'normal', 'warning' or 'error' - * @param bool $merge true means add as new line, false means override all previous text of the same type - * @return void - */ - public function track($col, $msg, $level = 'normal', $merge = true) { - if (empty($this->_row)) { - $this->flush(); // Init arrays. - } - if (!in_array($col, $this->columns)) { - debugging('Incorrect column:'.$col); - return; - } - if ($merge) { - if ($this->_row[$col][$level] != '') { - $this->_row[$col][$level] .= $this->_plain ? '' : '
'; - } - $this->_row[$col][$level] .= $msg; - } else { - $this->_row[$col][$level] = $msg; - } - } - - /** - * Print the table end - * @return void - */ - public function close() { - $this->flush(); - echo $this->_plain ? "\n" : '
'.get_string('status').''.get_string('cccsvline', 'tool_uploadcourse').'ID'.get_string('fullname').''.get_string('shortname').''.get_string('category').''.get_string('idnumber').''.get_string('summary').''.get_string('delete').'
'; - if (!empty($field)) { - echo implode(($this->_plain ? "|" : '
'), $field); - } else { - echo $this->_plain ? '' : ' '; - } - echo $this->_plain ? '' : '
'; - } -} - -/** - * Validation callback function - verified the column line of csv file. - * Converts standard column names to lowercase. - * @param csv_import_reader $cir - * @param array $stdfields standard course fields - * @param moodle_url $returnurl return url in case of any error - * @return array list of fields - */ -function tool_uploadcourse_validate_course_upload_columns(csv_import_reader $cir, $stdfields, moodle_url $returnurl) { - $columns = $cir->get_columns(); - - if (empty($columns)) { - $cir->close(); - $cir->cleanup(); - print_error('cannotreadtmpfile', 'error', $returnurl); - } - if (count($columns) < 2) { - $cir->close(); - $cir->cleanup(); - print_error('csvfewcolumns', 'error', $returnurl); - } - - // Test columns. - $processed = array(); - foreach ($columns as $key => $unused) { - $field = $columns[$key]; - $lcfield = textlib::strtolower($field); - if (in_array($field, $stdfields) or in_array($lcfield, $stdfields)) { - // Standard fields are only lowercase. - $newfield = $lcfield; - - } else if (preg_match('/^\w+\_\d+$/', $lcfield)) { - // Special fields for enrolments. - $newfield = $lcfield; - - } else { - $cir->close(); - $cir->cleanup(); - print_error('invalidfieldname', 'error', $returnurl, $field); - } - if (in_array($newfield, $processed)) { - $cir->close(); - $cir->cleanup(); - print_error('duplicatefieldname', 'error', $returnurl, $newfield); - } - $processed[$key] = $newfield; - } - - return $processed; -} - -/** - * Increments shortname - increments trailing number or adds it if not present. - * Varifies that the new shortname does not exist yet - * @param string $shortname - * @return incremented shortname which does not exist yet - */ -function tool_uploadcourse_increment_shortname($shortname) { - global $DB, $CFG; - - if (!preg_match_all('/(.*?)([0-9]+)$/', $shortname, $matches)) { - $shortname = $shortname.'2'; - } else { - $shortname = $matches[1][0].($matches[2][0]+1); - } - - if ($DB->record_exists('course', array('shortname'=>$shortname))) { - return tool_uploadcourse_increment_shortname($shortname); - } else { - return $shortname; - } -} - -/** - * Increments idnumber - increments trailing number or adds it if not present. - * Varifies that the new idnumber does not exist yet - * @param string $idnumber - * @return incremented idnumber which does not exist yet - */ -function tool_uploadcourse_increment_idnumber($idnumber) { - global $DB, $CFG; - - if (!preg_match_all('/(.*?)([0-9]+)$/', $idnumber, $matches)) { - $idnumber = $idnumber.'2'; - } else { - $idnumber = $matches[1][0].($matches[2][0]+1); - } - - if ($DB->record_exists('course', array('idnumber'=>$idnumber))) { - return tool_uploadcourse_increment_idnumber($idnumber); - } else { - return $idnumber; - } -} - -/** - * Check if default field contains templates and apply them. - * @param string $template - potential tempalte string - * @param object $course - we need coursename, firstname and lastname - * @return object $template - course template - * @return string $result - field value - */ -function tool_uploadcourse_process_template($template, $course) { - if (is_array($template)) { - // Hack for for support of text editors with format. - $t = $template['text']; - } else { - $t = $template; - } - if (strpos($t, '%') === false) { - return $template; - } - - $shortname = isset($course->shortname) ? $course->shortname : ''; - $fullname = isset($course->fullname) ? $course->fullname : ''; - $idnumber = isset($course->idnumber) ? $course->idnumber : ''; - - $callback = partial('tool_uploadcourse_process_template_callback', $shortname, $fullname, $idnumber); - - $result = preg_replace_callback('/(?. /** - * Link to CSV course upload + * Link to CSV course upload. * * @package tool_uploadcourse - * @subpackage uploadcourse - * @copyright 2010 Petr Skoda {@link http://skodak.org} * @copyright 2011 Piers Harding * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -defined('MOODLE_INTERNAL') || die; +defined('MOODLE_INTERNAL') || die(); -if (has_capability('moodle/restore:restorecourse', $systemcontext)) { +if ($hassiteconfig) { $ADMIN->add('courses', new admin_externalpage('tooluploadcourse', - get_string('uploadcourses', 'tool_uploadcourse'), - "$CFG->wwwroot/$CFG->admin/tool/uploadcourse/index.php", 'moodle/site:uploadusers')); + get_string('uploadcourses', 'tool_uploadcourse'), "/admin/tool/uploadcourse/index.php")); } diff --git a/admin/tool/uploadcourse/tests/course_test.php b/admin/tool/uploadcourse/tests/course_test.php index d5dfb9b4358..793e18467ed 100644 --- a/admin/tool/uploadcourse/tests/course_test.php +++ b/admin/tool/uploadcourse/tests/course_test.php @@ -28,6 +28,10 @@ global $CFG; /** * Course test case. + * + * @package tool_uploadcourse + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or late */ class tool_uploadcourse_course_testcase extends advanced_testcase { @@ -239,7 +243,6 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { 'enrolment_3_disable' => '1', ); - $this->assertFalse($DB->record_exists('course', array('shortname' => 'c1'))); $co = new tool_uploadcourse_course($mode, $updatemode, $data); $this->assertTrue($co->prepare()); @@ -409,7 +412,6 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { 'enablecompletion' => '1', ); - $this->assertFalse($DB->record_exists('course', array('shortname' => 'c1'))); $co = new tool_uploadcourse_course($mode, $updatemode, $data, $defaultdata); $this->assertTrue($co->prepare()); @@ -576,7 +578,8 @@ class tool_uploadcourse_course_testcase extends advanced_testcase { $mode = tool_uploadcourse_processor::MODE_CREATE_NEW; $updatemode = tool_uploadcourse_processor::UPDATE_ALL_WITH_DATA_ONLY; - $data = array('shortname' => 'A1', 'templatecourse' => $c1->shortname, 'summary' => 'A', 'category' => 1, 'fullname' => 'A1'); + $data = array('shortname' => 'A1', 'templatecourse' => $c1->shortname, 'summary' => 'A', 'category' => 1, + 'fullname' => 'A1'); $co = new tool_uploadcourse_course($mode, $updatemode, $data); $this->assertTrue($co->prepare()); $co->proceed(); diff --git a/admin/tool/uploadcourse/tests/helper_test.php b/admin/tool/uploadcourse/tests/helper_test.php index a17e5439263..a61fa674d9e 100644 --- a/admin/tool/uploadcourse/tests/helper_test.php +++ b/admin/tool/uploadcourse/tests/helper_test.php @@ -28,10 +28,14 @@ global $CFG; /** * Helper test case. + * + * @package tool_uploadcourse + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tool_uploadcourse_helper_testcase extends advanced_testcase { - function test_generate_shortname() { + public function test_generate_shortname() { $data = (object) array('fullname' => 'Ah Bh Ch 01 02 03', 'idnumber' => 'ID123'); $this->assertSame($data->fullname, tool_uploadcourse_helper::generate_shortname($data, '%f')); @@ -41,14 +45,14 @@ class tool_uploadcourse_helper_testcase extends advanced_testcase { $this->assertSame('[Ah Bh Ch] = ID123', tool_uploadcourse_helper::generate_shortname($data, '[%8f] = %i')); } - function test_get_course_formats() { + public function test_get_course_formats() { $result = tool_uploadcourse_helper::get_course_formats(); $this->assertSame(array_keys(get_plugin_list('format')), $result); // Should be similar as first result, as cached. $this->assertSame($result, tool_uploadcourse_helper::get_course_formats()); } - function test_get_enrolment_data() { + public function test_get_enrolment_data() { $this->resetAfterTest(true); $data = array( 'enrolment_1' => 'unknown', @@ -94,16 +98,17 @@ class tool_uploadcourse_helper_testcase extends advanced_testcase { $this->assertSame(tool_uploadcourse_helper::get_enrolment_data($data), $expected); } - function test_get_enrolment_plugins() { + public function test_get_enrolment_plugins() { $this->resetAfterTest(true); $actual = tool_uploadcourse_helper::get_enrolment_plugins(); $this->assertSame(array_keys(enrol_get_plugins(false)), array_keys($actual)); // This should be identical as cached. $secondactual = tool_uploadcourse_helper::get_enrolment_plugins(); - $this->assertSame($actual, $secondactual); + $this->assertEquals($actual, $secondactual); } - function test_get_restore_content_dir() { + public function test_get_restore_content_dir() { + global $CFG; $this->resetAfterTest(true); $this->setAdminUser(); @@ -144,7 +149,6 @@ class tool_uploadcourse_helper_testcase extends advanced_testcase { $this->assertEquals($bcinfo->original_course_id, $c2->id); $this->assertEquals($bcinfo->original_course_fullname, $c2->fullname); - // Checking with a shortname. $dir = tool_uploadcourse_helper::get_restore_content_dir(null, $c1->shortname); $bcinfo = backup_general_helper::get_backup_information($dir); @@ -161,6 +165,21 @@ class tool_uploadcourse_helper_testcase extends advanced_testcase { $this->assertEquals($bcinfo->original_course_id, $c2->id); $this->assertEquals($bcinfo->original_course_fullname, $c2->fullname); + // Cleaning content directories. + $oldcfg = isset($CFG->keeptempdirectoriesonbackup) ? $CFG->keeptempdirectoriesonbackup : false; + $dir = "$CFG->tempdir/backup/$dir"; + $this->assertTrue(file_exists($dir)); + + $CFG->keeptempdirectoriesonbackup = false; + tool_uploadcourse_helper::clean_restore_content(); + $this->assertTrue(file_exists($dir)); + + $CFG->keeptempdirectoriesonbackup = true; + tool_uploadcourse_helper::clean_restore_content(); + $this->assertFalse(file_exists($dir)); + + $CFG->keeptempdirectoriesonbackup = $oldcfg; + // Restore the time limit to prevent warning. set_time_limit(0); } diff --git a/admin/tool/uploadcourse/tests/processor_test.php b/admin/tool/uploadcourse/tests/processor_test.php index 5385ddeb43d..8aee781a219 100644 --- a/admin/tool/uploadcourse/tests/processor_test.php +++ b/admin/tool/uploadcourse/tests/processor_test.php @@ -25,9 +25,14 @@ defined('MOODLE_INTERNAL') || die(); global $CFG; +require_once($CFG->libdir . '/csvlib.class.php'); /** * Processor test case. + * + * @package tool_uploadcourse + * @copyright 2013 Frédéric Massart + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class tool_uploadcourse_processor_testcase extends advanced_testcase { diff --git a/admin/tool/uploadcourse/version.php b/admin/tool/uploadcourse/version.php index 1139fb236ad..112b41cb2e0 100644 --- a/admin/tool/uploadcourse/version.php +++ b/admin/tool/uploadcourse/version.php @@ -15,17 +15,15 @@ // along with Moodle. If not, see . /** - * Plugin version info + * Plugin version info. * * @package tool_uploadcourse - * @subpackage uploadcourse - * @copyright 2011 Petr Skoda {@link http://skodak.org} * @copyright 2011 Piers Harding * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -defined('MOODLE_INTERNAL') || die; -$plugin->version = 2012112301; // The current plugin version (Date: YYYYMMDDXX) -$plugin->requires = 2011091600; // Requires this Moodle version -$plugin->component = 'tool_uploadcourse'; // Full name of the plugin (used for diagnostics). +defined('MOODLE_INTERNAL') || die(); +$plugin->version = 2013070200; // The current plugin version (Date: YYYYMMDDXX). +$plugin->requires = 2013062100; // Requires this Moodle version. +$plugin->component = 'tool_uploadcourse'; // Full name of the plugin (used for diagnostics).