MDL-13114 tool_uploadcourse: Initial commit

This commit is contained in:
Piers Harding 2013-06-18 15:12:09 +08:00 committed by Frederic Massart
parent 07bbbcf174
commit 3a0fda69d7
8 changed files with 2512 additions and 0 deletions

View File

@ -0,0 +1,196 @@
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 <Moodle dirroot>/admin/tool/uploadcourse
Alternatively you can use git:
cd <Moodle dirroot>/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_<n>, and then add the corresponding field values subscripted with _<n>.
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_<n> with value 1
* disable - disable_<n> 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_<n>' 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 <moodle root>/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.

View File

@ -0,0 +1,260 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* CLI Bulk course registration script from a comma separated file
*
* @package tool_uploadcourse
* @subpackage uploadcourse
* @copyright 2004 onwards Martin Dougiamas (http://dougiamas.com)
* @copyright 2012 Piers Harding
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*
* Notes:
* - it is required to use the web server account when executing PHP CLI scripts
* - you need to change the "www-data" to match the apache user account
* - use "su" if "sudo" not available
*
*/
define('CLI_SCRIPT', true);
require(dirname(dirname(dirname(dirname(dirname(__FILE__))))).'/config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/csvlib.class.php');
require_once($CFG->dirroot.'/course/lib.php');
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
require_once($CFG->libdir . '/filelib.php');
require_once($CFG->libdir.'/clilib.php');
require_once('../locallib.php');
$courseconfig = get_config('moodlecourse');
// Now get cli options.
list($options, $unrecognized) = cli_get_params(
array('verbose' => false,
'help' => false,
'action' => '',
'mode' => 'nochange',
'file' => '',
'delimiter' => 'comma',
'encoding' => 'UTF-8',
'category' => false,
'templateshortname' => false,
'template' => false,
'format' => $courseconfig->format,
'numsections' => $courseconfig->numsections,
'reset' => false,
),
array('v' => 'verbose',
'h' => 'help',
'a' => 'action',
'm' => 'mode',
'f' => 'file',
'd' => 'delimiter',
'e' => 'encoding',
'c' => 'category',
's' => 'templateshortname',
't' => 'template',
'g' => 'format',
'n' => 'numsections',
'r' => 'reset',
));
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
$help =
"Execute Course Upload.
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
-r, --reset Run the course reset by default after each course import
Example:
\$sudo -u www-data /usr/bin/php admin/tool/uploadcourse/cli/uploadcourse.php --action=addupdate \\
--mode=delete --file=./courses.csv --delimiter=comma
";
if ($options['help']) {
echo $help;
die;
}
echo "Moodle course uploader running ...\n";
$actions = array('addnew' => CC_COURSE_ADDNEW,
'addupdate' => CC_COURSE_ADD_UPDATE,
'update' => CC_COURSE_UPDATE,
'forceadd' => CC_COURSE_ADDINC);
if (!isset($options['action']) ||
!isset($actions[$options['action']]) ||
($options['action'] != 'addnew' && !isset($options['mode']))) {
echo get_string('invalidinput', 'tool_uploadcourse')."\n";
echo $help;
die;
}
if (!empty($options['verbose']) || $CFG->debug) {
define('CC_DEBUG', true);
}
if (!isset($actions[$options['action']])) {
echo get_string('invalidaction', 'tool_uploadcourse')."\n";
echo $help;
die;
}
$options['cctype'] = $actions[$options['action']];
$updatetype = array('nochange' => CC_UPDATE_NOCHANGES,
'file' => CC_UPDATE_FILEOVERRIDE,
'filedefaults' => CC_UPDATE_ALLOVERRIDE,
'missing' => CC_UPDATE_MISSING);
if ($options['mode'] == 'rename') {
$options['ccallowrenames'] = 1;
unset($options['mode']);
} else if ($options['mode'] == 'delete') {
$options['ccallowdeletes'] = 1;
unset($options['mode']);
} else if (!isset($updatetype[$options['mode']])) {
echo get_string('invalidmode', 'tool_uploadcourse')."\n";
echo $help;
die;
}
if (isset($options['mode'])) {
$options['ccupdatetype'] = $updatetype[$options['mode']];
}
$options['ccstandardshortnames'] = 1;
$options['startdate'] = time() + 3600 * 24;
$options['hiddensections'] = $courseconfig->hiddensections;
$options['newsitems'] = $courseconfig->newsitems;
$options['showgrades'] = $courseconfig->showgrades;
$options['showreports'] = $courseconfig->showreports;
$options['maxbytes'] = $courseconfig->maxbytes;
$options['legacyfiles'] = 0;
$options['groupmode'] = $courseconfig->groupmode;
$options['groupmodeforce'] = $courseconfig->groupmodeforce;
$options['visible'] = $courseconfig->visible;
$options['lang'] = $courseconfig->lang;
if ($options['category']) {
$split = preg_split('|(?<!\\\)/|', $options['category']);
$categories = array();
foreach ($split as $cat) {
$cat = preg_replace('/\\\/', '', $cat);
$categories[]= $cat;
}
$options['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' => $options['category']));
if (empty($category)) {
echo get_string('invalidcategory', 'tool_uploadcourse')."\n";
echo $help;
die;
}
$options['category'] = $category->id;
}
$options['cccategory'] = $options['category'];
} else {
$categories = $DB->get_records('course_categories');
if (empty($categories)) {
echo get_string('invalidcategory', 'tool_uploadcourse')."\n";
echo $help;
die;
}
$category = array_shift($categories);
$options['cccategory'] = $category->id;
}
if (isset($options['templateshortname'])) {
$options['ccshortname'] = $options['templateshortname'];
}
$options['file'] = realpath($options['file']);
if (!file_exists($options['file'])) {
echo get_string('invalidcsvfile', 'tool_uploadcourse')."\n";
echo $help;
die;
}
$encodings = textlib::get_encodings();
if (!isset($encodings[$options['encoding']])) {
echo get_string('invalidencoding', 'tool_uploadcourse')."\n";
echo $help;
die;
}
if ($options['template']) {
$options['template'] = realpath($options['template']);
}
if ($options['template'] && !file_exists($options['template'])) {
echo get_string('invalidtemplatefile', 'tool_uploadcourse')."\n";
echo $help;
die;
}
$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);
$restorefile = null;
if ($options['template']) {
$restorefile = $options['template'];
}
$formdata = (object) $options;
$returnurl = new moodle_url('/admin/tool/uploadcourse/index.php');
$bulknurl = new moodle_url('/admin/tool/uploadcourse/index.php');
$std_fields = tool_uploadcourse_std_fields();
// Emulate normal session.
cron_setup_user();
$content = file_get_contents($formdata->file);
$iid = csv_import_reader::get_new_iid('uploadcourse');
$cir = new csv_import_reader($iid, 'uploadcourse');
$readcount = $cir->load_csv_content($content, $formdata->encoding, $formdata->delimiter);
$filecolumns = tool_uploadcourse_validate_course_upload_columns($cir, $std_fields, $returnurl);
unset($content);
if ($readcount === false) {
print_error('csvfileerror', 'tool_uploadcourse', $returnurl, $cir->get_error());
} else if ($readcount == 0) {
print_error('csvemptyfile', 'error', $returnurl, $cir->get_error());
}
echo "CSV read count: ".$readcount."\n";
$result = tool_uploadcourse_process_course_upload($formdata, $cir, $filecolumns, $restorefile, true);
exit($result);

View File

@ -0,0 +1,350 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Bulk course upload forms
*
* @package tool_uploadcourse
* @subpackage uploadcourse
* @copyright 2007 Dan Poltawski
* @copyright 2011 Piers Harding
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
/**
* Upload a file CVS file with course information.
*
* @copyright 2007 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class admin_uploadcourse_form1 extends moodleform {
/**
* The standard form definiton
* @return object $form
*/
public function definition () {
$mform = $this->_form;
$mform->addElement('header', 'settingsheader', get_string('upload'));
$mform->addElement('filepicker', 'coursefile', get_string('file'));
$mform->addRule('coursefile', null, 'required');
$choices = csv_import_reader::get_delimiter_list();
$mform->addElement('select', 'delimiter_name', get_string('csvdelimiter', 'tool_uploadcourse'), $choices);
if (array_key_exists('cfg', $choices)) {
$mform->setDefault('delimiter_name', 'cfg');
} else if (get_string('listsep', 'langconfig') == ';') {
$mform->setDefault('delimiter_name', 'semicolon');
} else {
$mform->setDefault('delimiter_name', 'comma');
}
$choices = textlib::get_encodings();
$mform->addElement('select', 'encoding', get_string('encoding', 'tool_uploadcourse'), $choices);
$mform->setDefault('encoding', 'UTF-8');
$choices = array('10'=>10, '20'=>20, '100'=>100, '1000'=>1000, '100000'=>100000);
$mform->addElement('select', 'previewrows', get_string('rowpreviewnum', 'tool_uploadcourse'), $choices);
$mform->setType('previewrows', PARAM_INT);
$this->add_action_buttons(false, get_string('uploadcourses', 'tool_uploadcourse'));
}
}
/**
* Specify course upload details
*
* @copyright 2007 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class admin_uploadcourse_form2 extends moodleform {
/**
* The standard form definiton
* @return object $form
*/
public function definition () {
global $CFG, $COURSE, $DB;
$mform = $this->_form;
$columns = $this->_customdata['columns'];
$data = $this->_customdata['data'];
$courseconfig = get_config('moodlecourse');
// I am the template course, why should it be the administrator? we have roles now, other ppl may use this script ;-).
$templatecourse = $COURSE;
// Upload settings and file.
$mform->addElement('header', 'settingsheader', get_string('settings'));
$choices = array(CC_COURSE_ADDNEW => get_string('ccoptype_addnew', 'tool_uploadcourse'),
CC_COURSE_ADDINC => get_string('ccoptype_addinc', 'tool_uploadcourse'),
CC_COURSE_ADD_UPDATE => get_string('ccoptype_addupdate', 'tool_uploadcourse'),
CC_COURSE_UPDATE => get_string('ccoptype_update', 'tool_uploadcourse'));
$mform->addElement('select', 'cctype', get_string('ccoptype', 'tool_uploadcourse'), $choices);
$choices = array(CC_UPDATE_NOCHANGES => get_string('nochanges', 'tool_uploadcourse'),
CC_UPDATE_FILEOVERRIDE => get_string('ccupdatefromfile', 'tool_uploadcourse'),
CC_UPDATE_ALLOVERRIDE => get_string('ccupdateall', 'tool_uploadcourse'),
CC_UPDATE_MISSING => get_string('ccupdatemissing', 'tool_uploadcourse'));
$mform->addElement('select', 'ccupdatetype', get_string('ccupdatetype', 'tool_uploadcourse'), $choices);
$mform->setDefault('ccupdatetype', CC_UPDATE_NOCHANGES);
$mform->disabledIf('ccupdatetype', 'cctype', 'eq', CC_COURSE_ADDNEW);
$mform->disabledIf('ccupdatetype', 'cctype', 'eq', CC_COURSE_ADDINC);
$mform->addElement('selectyesno', 'ccallowrenames', get_string('allowrenames', 'tool_uploadcourse'));
$mform->setDefault('ccallowrenames', 0);
$mform->disabledIf('ccallowrenames', 'cctype', 'eq', CC_COURSE_ADDNEW);
$mform->disabledIf('ccallowrenames', 'cctype', 'eq', CC_COURSE_ADDINC);
$mform->addElement('selectyesno', 'ccallowdeletes', get_string('allowdeletes', 'tool_uploadcourse'));
$mform->setDefault('ccallowdeletes', 0);
$mform->disabledIf('ccallowdeletes', 'cctype', 'eq', CC_COURSE_ADDNEW);
$mform->disabledIf('ccallowdeletes', 'cctype', 'eq', CC_COURSE_ADDINC);
$mform->addElement('selectyesno', 'reset', get_string('reset', 'tool_uploadcourse'));
$mform->setDefault('ccallowdeletes', 0);
$mform->disabledIf('ccallowdeletes', 'cctype', 'eq', CC_COURSE_ADDNEW);
$mform->disabledIf('ccallowdeletes', 'cctype', 'eq', CC_COURSE_ADDINC);
$mform->addElement('selectyesno', 'ccstandardshortnames', get_string('ccstandardshortnames', 'tool_uploadcourse'));
$mform->setDefault('ccstandardshortnames', 1);
// Default values.
$mform->addElement('header', 'defaultheader', get_string('defaultvalues', 'tool_uploadcourse'));
$displaylist = array();
$parentlist = array();
make_categories_list($displaylist, $parentlist, 'moodle/course:create');
$mform->addElement('select', 'cccategory', get_string('category'), $displaylist);
$mform->addHelpButton('cccategory', 'category');
$mform->addElement('text', 'ccshortname', get_string('ccshortnametemplate', 'tool_uploadcourse'),
'maxlength="100" size="20"');
$mform->addHelpButton('ccshortname', 'shortnamecourse', 'tool_uploadcourse');
$mform->disabledIf('ccshortname', 'cctype', 'eq', CC_COURSE_ADD_UPDATE);
$mform->disabledIf('ccshortname', 'cctype', 'eq', CC_COURSE_UPDATE);
$courseformats = get_plugin_list('format');
$formcourseformats = array();
foreach ($courseformats as $courseformat => $formatdir) {
$formcourseformats[$courseformat] = get_string('pluginname', "format_$courseformat");
}
$mform->addElement('select', 'format', get_string('format'), $formcourseformats);
$mform->addHelpButton('format', 'format');
$mform->setDefault('format', $courseconfig->format);
for ($i = 0; $i <= $courseconfig->maxsections; $i++) {
$sectionmenu[$i] = "$i";
}
$mform->addElement('select', 'numsections', get_string('numberweeks'), $sectionmenu);
$mform->setDefault('numsections', $courseconfig->numsections);
$mform->addElement('date_selector', 'startdate', get_string('startdate'));
$mform->addHelpButton('startdate', 'startdate');
$mform->setDefault('startdate', time() + 3600 * 24);
$choices = array();
$choices['0'] = get_string('hiddensectionscollapsed');
$choices['1'] = get_string('hiddensectionsinvisible');
$mform->addElement('select', 'hiddensections', get_string('hiddensections'), $choices);
$mform->addHelpButton('hiddensections', 'hiddensections');
$mform->setDefault('hiddensections', $courseconfig->hiddensections);
$options = range(0, 10);
$mform->addElement('select', 'newsitems', get_string('newsitemsnumber'), $options);
$mform->addHelpButton('newsitems', 'newsitemsnumber');
$mform->setDefault('newsitems', $courseconfig->newsitems);
$mform->addElement('selectyesno', 'showgrades', get_string('showgrades'));
$mform->addHelpButton('showgrades', 'showgrades');
$mform->setDefault('showgrades', $courseconfig->showgrades);
$mform->addElement('selectyesno', 'showreports', get_string('showreports'));
$mform->addHelpButton('showreports', 'showreports');
$mform->setDefault('showreports', $courseconfig->showreports);
$choices = get_max_upload_sizes($CFG->maxbytes);
$mform->addElement('select', 'maxbytes', get_string('maximumupload'), $choices);
$mform->addHelpButton('maxbytes', 'maximumupload');
$mform->setDefault('maxbytes', $courseconfig->maxbytes);
if (!empty($course->legacyfiles) or !empty($CFG->legacyfilesinnewcourses)) {
if (empty($course->legacyfiles)) {
// 0 or missing means no legacy files ever used in this course - new course or nobody turned on legacy files yet.
$choices = array('0'=>get_string('no'), '2'=>get_string('yes'));
} else {
$choices = array('1'=>get_string('no'), '2'=>get_string('yes'));
}
$mform->addElement('select', 'legacyfiles', get_string('courselegacyfiles'), $choices);
$mform->addHelpButton('legacyfiles', 'courselegacyfiles');
if (!isset($courseconfig->legacyfiles)) {
// In case this was not initialised properly due to switching of $CFG->legacyfilesinnewcourses.
$courseconfig->legacyfiles = 0;
}
$mform->setDefault('legacyfiles', $courseconfig->legacyfiles);
}
if (!empty($CFG->allowcoursethemes)) {
$themeobjects = get_list_of_themes();
$themes=array();
$themes[''] = get_string('forceno');
foreach ($themeobjects as $key => $theme) {
if (empty($theme->hidefromselector)) {
$themes[$key] = get_string('pluginname', 'theme_'.$theme->name);
}
}
$mform->addElement('select', 'theme', get_string('forcetheme'), $themes);
}
$courseshortnames = $DB->get_records('course', null, $sort='shortname', 'id,shortname,idnumber');
$formccourseshortnames = array('none' => get_string('none'));
foreach ($courseshortnames as $course) {
$formccourseshortnames[$course->shortname] = $course->shortname;
}
$mform->addElement('select', 'templatename', get_string('coursetemplatename', 'tool_uploadcourse'), $formccourseshortnames);
$mform->addHelpButton('templatename', 'coursetemplatename', 'tool_uploadcourse');
$mform->setDefault('templatename', 'none');
$contextid = $this->_customdata['contextid'];
$mform->addElement('hidden', 'contextid', $contextid);
$mform->addElement('filepicker', 'restorefile', get_string('templatefile', 'tool_uploadcourse'));
enrol_course_edit_form($mform, null, get_context_instance(CONTEXT_SYSTEM));
$mform->addElement('header', '', get_string('groups', 'group'));
$choices = array();
$choices[NOGROUPS] = get_string('groupsnone', 'group');
$choices[SEPARATEGROUPS] = get_string('groupsseparate', 'group');
$choices[VISIBLEGROUPS] = get_string('groupsvisible', 'group');
$mform->addElement('select', 'groupmode', get_string('groupmode', 'group'), $choices);
$mform->addHelpButton('groupmode', 'groupmode', 'group');
$mform->setDefault('groupmode', $courseconfig->groupmode);
$choices = array();
$choices['0'] = get_string('no');
$choices['1'] = get_string('yes');
$mform->addElement('select', 'groupmodeforce', get_string('groupmodeforce', 'group'), $choices);
$mform->addHelpButton('groupmodeforce', 'groupmodeforce', 'group');
$mform->setDefault('groupmodeforce', $courseconfig->groupmodeforce);
// Default groupings selector.
$options = array();
$options[0] = get_string('none');
$mform->addElement('select', 'defaultgroupingid', get_string('defaultgrouping', 'group'), $options);
$mform->addElement('header', '', get_string('availability'));
$choices = array();
$choices['0'] = get_string('courseavailablenot');
$choices['1'] = get_string('courseavailable');
$mform->addElement('select', 'visible', get_string('availability'), $choices);
$mform->addHelpButton('visible', 'availability');
$mform->setDefault('visible', $courseconfig->visible);
$mform->addElement('header', '', get_string('language'));
$languages=array();
$languages[''] = get_string('forceno');
$languages += get_string_manager()->get_list_of_translations();
$mform->addElement('select', 'lang', get_string('forcelanguage'), $languages);
$mform->setDefault('lang', $courseconfig->lang);
// Hidden fields.
$mform->addElement('hidden', 'iid');
$mform->setType('iid', PARAM_INT);
$mform->addElement('hidden', 'previewrows');
$mform->setType('previewrows', PARAM_INT);
$this->add_action_buttons(true, get_string('uploadcourses', 'tool_uploadcourse'));
$this->set_data($data);
}
/**
* Form tweaks that depend on current data.
*/
public function definition_after_data() {
$mform = $this->_form;
$columns = $this->_customdata['columns'];
foreach ($columns as $column) {
if ($mform->elementExists($column)) {
$mform->removeElement($column);
}
}
}
/**
* Server side validation.
* @param array $data - form data
* @param object $files - form files
* @return array $errors - form errors
*/
public function validation($data, $files) {
global $DB;
$errors = parent::validation($data, $files);
$columns = $this->_customdata['columns'];
$optype = $data['cctype'];
// Look for other required data.
if ($optype != CC_COURSE_UPDATE) {
if (!in_array('fullname', $columns)) {
if (isset($errors['cctype'])) {
$errors['cctype'] .= ' ';
}
$errors['cctype'] .= get_string('missingfield', 'error', 'fullname');
}
if (!in_array('summary', $columns)) {
if (isset($errors['cctype'])) {
$errors['cctype'] .= ' ';
}
$errors['cctype'] .= get_string('missingfield', 'error', 'summary');
}
}
if (!empty($data['templatename']) && $data['templatename'] != 'none') {
if (!$template = $DB->get_record('course', array('shortname' => $data['templatename']))) {
$errors['templatename'] = get_string('missingtemplate', 'tool_uploadcourse');
}
}
return $errors;
}
/**
* Used to reformat the data from the editor component
*
* @return stdClass
*/
public function get_data() {
$data = parent::get_data();
if ($data !== null and isset($data->description)) {
$data->descriptionformat = $data->description['format'];
$data->description = $data->description['text'];
}
return $data;
}
}

View File

@ -0,0 +1,184 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Bulk course registration script from a comma separated file
*
* @package tool_uploadcourse
* @copyright 2004 onwards Martin Dougiamas (http://dougiamas.com)
* @copyright 2011 Piers Harding
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require('../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/csvlib.class.php');
require_once($CFG->dirroot.'/course/lib.php');
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
require_once($CFG->libdir . '/filelib.php');
require_once('locallib.php');
require_once('course_form.php');
$iid = optional_param('iid', '', PARAM_INT);
$previewrows = optional_param('previewrows', 10, PARAM_INT);
require_login();
admin_externalpage_setup('tooluploadcourse');
$returnurl = new moodle_url('/admin/tool/uploadcourse/index.php');
$bulknurl = new moodle_url('/admin/tool/uploadcourse/index.php');
$std_fields = tool_uploadcourse_std_fields();
if (empty($iid)) {
$mform1 = new admin_uploadcourse_form1();
if ($formdata = $mform1->get_data()) {
$iid = csv_import_reader::get_new_iid('uploadcourse');
$cir = new csv_import_reader($iid, 'uploadcourse');
$content = $mform1->get_file_content('coursefile');
$readcount = $cir->load_csv_content($content, $formdata->encoding, $formdata->delimiter_name);
unset($content);
if ($readcount === false) {
print_error('csvfileerror', 'tool_uploadcourse', $returnurl, $cir->get_error());
} else if ($readcount == 0) {
print_error('csvemptyfile', 'error', $returnurl, $cir->get_error());
}
// Test if columns ok.
$filecolumns = tool_uploadcourse_validate_course_upload_columns($cir, $std_fields, $returnurl);
// Continue to form2.
} else {
echo $OUTPUT->header();
echo $OUTPUT->heading_with_help(get_string('uploadcourses', 'tool_uploadcourse'), 'uploadcourses', 'tool_uploadcourse');
$mform1->display();
echo $OUTPUT->footer();
die;
}
} else {
$cir = new csv_import_reader($iid, 'uploadcourse');
$filecolumns = tool_uploadcourse_validate_course_upload_columns($cir, $std_fields, $returnurl);
}
$frontpagecontext = context_course::instance(SITEID);
$mform2 = new admin_uploadcourse_form2(null,
array('contextid' => $frontpagecontext->id,
'columns' => $filecolumns,
'data' => array('iid'=>$iid, 'previewrows'=>$previewrows)));
// If a file has been uploaded, then process it.
if ($formdata = $mform2->is_cancelled()) {
$cir->cleanup(true);
redirect($returnurl);
} else if ($formdata = $mform2->get_data()) {
// Print the header.
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('uploadcoursesresult', 'tool_uploadcourse'));
$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);
$restorefile = $tmpdir . '/' . $filename;
if (!$mform2->save_file('restorefile', $restorefile)) {
$restorefile = null;
}
$bulk = isset($formdata->ccbulk) ? $formdata->ccbulk : 0;
tool_uploadcourse_process_course_upload($formdata, $cir, $filecolumns, $restorefile);
echo $OUTPUT->box_end();
if ($bulk) {
echo $OUTPUT->continue_button($bulknurl);
} else {
echo $OUTPUT->continue_button($returnurl);
}
echo $OUTPUT->footer();
die;
}
// Print the header.
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('uploadcoursespreview', 'tool_uploadcourse'));
// NOTE: this is JUST csv processing preview, we must not prevent import from here if there is something in the file!!
// this was intended for validation of csv formatting and encoding, not filtering the data!!!!
// we definitely must not process the whole file!
// Preview table data.
$data = array();
$cir->init();
$linenum = 1; // Column header is first line.
while ($linenum <= $previewrows and $fields = $cir->next()) {
$linenum++;
$rowcols = array();
$rowcols['line'] = $linenum;
foreach ($fields as $key => $field) {
$rowcols[$filecolumns[$key]] = s($field);
}
$rowcols['status'] = array();
if (isset($rowcols['shortname'])) {
$stdshortname = clean_param($rowcols['shortname'], PARAM_MULTILANG);
if ($rowcols['shortname'] !== $stdshortname) {
$rowcols['status'][] = get_string('invalidshortnameupload');
}
if ($courseid = $DB->get_field('course', 'id', array('shortname'=>$stdshortname))) {
$rowcols['shortname'] = html_writer::link(new moodle_url('/course/view.php',
array('id' => $courseid)),
$rowcols['shortname']);
}
} else {
$rowcols['status'][] = get_string('missingshortname');
}
$rowcols['status'] = implode('<br />', $rowcols['status']);
$data[] = $rowcols;
}
if ($fields = $cir->next()) {
$data[] = array_fill(0, count($fields) + 2, '...');
}
$cir->close();
$table = new html_table();
$table->id = "ccpreview";
$table->attributes['class'] = 'generaltable';
$table->tablealign = 'center';
$table->summary = get_string('uploadcoursespreview', 'tool_uploadcourse');
$table->head = array();
$table->data = $data;
$table->head[] = get_string('cccsvline', 'tool_uploadcourse');
foreach ($filecolumns as $column) {
$table->head[] = $column;
}
$table->head[] = get_string('status');
echo html_writer::tag('div', html_writer::table($table), array('class'=>'flexible-wrap'));
// Print the form.
$mform2->display();
echo $OUTPUT->footer();
die;

View File

@ -0,0 +1,130 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for component 'tool_uploadcourse', language 'en', branch 'MOODLE_22_STABLE'
*
* @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
*/
$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 (don\t use comma-quoted as Moodle does not support it): {$a}';
$string['allowdeletes'] = 'Allow deletes';
$string['allowrenames'] = 'Allow renames';
$string['csvdelimiter'] = 'CSV delimiter';
$string['defaultvalues'] = 'Default values';
$string['deleteerrors'] = 'Delete errors';
$string['encoding'] = 'Encoding';
$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['rowpreviewnum'] = 'Preview rows';
$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['uploadcourses'] = 'Upload courses';
$string['uploadcourses_help'] = 'Courses may be uploaded (and optionally enrolled in courses) via text file. The format of the file should be as follows:
* Each line of the file contains one record
* 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 coursename, password, firstname, lastname, email';
$string['uploadcoursespreview'] = 'Upload courses preview';
$string['uploadcoursesresult'] = 'Upload courses results';
$string['courseupdated'] = 'Course updated';
$string['courseuptodate'] = 'Course up-to-date';
$string['coursedeleted'] = 'Course deleted';
$string['courserenamed'] = 'Course renamed';
$string['coursescreated'] = 'Courses created';
$string['coursesdeleted'] = 'Courses deleted';
$string['coursesrenamed'] = 'Courses renamed';
$string['coursesskipped'] = 'Courses skipped';
$string['coursesupdated'] = 'Courses updated';
$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['shortnamecourse_help'] = 'The short name of the course is displayed in the navigation. You may use template syntax here (%f = fullname, %i = idnumber), or enter an initial value that is incremented. See help for details and examples.';
$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['cccsvline'] = 'CSV line';
$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'] = 'Upload type';
$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['reset'] = 'Reset course after upload';
$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['ccshortnametemplate'] = 'Shortname template';
$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['invalidcsvfile'] = 'Invalid input CSV file';
$string['invalidaction'] = 'Invalid action selected';
$string['invalidmode'] = 'Invalid mode selected';
$string['invalidtemplatefile'] = 'Invalid template file';
$string['invalidencoding'] = 'Invalid encoding';
$string['invalidcategory'] = 'Invalid category';
$string['coursetemplatename'] = 'Course template shortname';
$string['coursetemplatename_help'] = 'Select an existing course shortname to use as a template for the creation of all courses.';
$string['templatefile'] = 'Template backup file';
$string['invalidbackupfile'] = 'Invalid backup file';

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* 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;
if (has_capability('moodle/restore:restorecourse', $systemcontext)) {
$ADMIN->add('courses', new admin_externalpage('tooluploadcourse',
get_string('uploadcourses', 'tool_uploadcourse'),
"$CFG->wwwroot/$CFG->admin/tool/uploadcourse/index.php", 'moodle/site:uploadusers'));
}

View File

@ -0,0 +1,31 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* 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).