Merge branch 'MDL-27901-master' of git://github.com/FMCorz/moodle
authorDan Poltawski <dan@moodle.com>
Tue, 8 Jan 2013 05:01:00 +0000 (13:01 +0800)
committerDan Poltawski <dan@moodle.com>
Tue, 8 Jan 2013 05:01:00 +0000 (13:01 +0800)
434 files changed:
admin/filters.php
admin/settings/security.php
admin/tool/customlang/db/upgrade.php
admin/tool/uploaduser/index.php
admin/user.php
admin/user/user_bulk_download.php
auth/ldap/auth.php
auth/manual/db/upgrade.php
auth/mnet/db/upgrade.php
auth/shibboleth/index.php
auth/shibboleth/index_form.html
auth/shibboleth/lang/en/auth_shibboleth.php
backup/backup.php
backup/backupfilesedit.php
backup/converter/moodle1/handlerlib.php
backup/converter/moodle1/lib.php
backup/converter/moodle1/tests/lib_test.php
backup/import.php
backup/moodle2/restore_stepslib.php
backup/restore.php
backup/util/loggers/file_logger.class.php
backup/util/loggers/output_indented_logger.class.php
backup/util/loggers/output_text_logger.class.php
backup/util/ui/base_moodleform.class.php
blocks/community/block_community.php
blocks/community/communitycourse.php
blocks/community/db/upgrade.php
blocks/community/styles.css
blocks/community/yui/comments/comments.js
blocks/community/yui/imagegallery/imagegallery.js
blocks/completionstatus/block_completionstatus.php
blocks/completionstatus/db/access.php
blocks/completionstatus/db/upgrade.php [new file with mode: 0644]
blocks/completionstatus/lang/en/block_completionstatus.php
blocks/completionstatus/version.php
blocks/course_overview/db/access.php
blocks/course_overview/lang/en/block_course_overview.php
blocks/course_overview/renderer.php
blocks/course_overview/version.php
blocks/course_summary/block_course_summary.php
blocks/course_summary/db/access.php
blocks/course_summary/db/upgrade.php [new file with mode: 0644]
blocks/course_summary/lang/en/block_course_summary.php
blocks/course_summary/version.php
blocks/dock.js
blocks/glossary_random/block_glossary_random.php
blocks/glossary_random/db/access.php
blocks/glossary_random/db/upgrade.php [new file with mode: 0644]
blocks/glossary_random/lang/en/block_glossary_random.php
blocks/glossary_random/version.php
blocks/html/backup/moodle1/lib.php [new file with mode: 0644]
blocks/html/db/upgrade.php
blocks/mentees/block_mentees.php
blocks/mentees/db/access.php
blocks/mentees/db/upgrade.php [new file with mode: 0644]
blocks/mentees/lang/en/block_mentees.php
blocks/mentees/version.php
blocks/navigation/db/upgrade.php
blocks/news_items/block_news_items.php
blocks/news_items/db/access.php
blocks/news_items/db/upgrade.php [new file with mode: 0644]
blocks/news_items/lang/en/block_news_items.php
blocks/news_items/version.php
blocks/online_users/block_online_users.php
blocks/online_users/db/access.php
blocks/online_users/db/upgrade.php [new file with mode: 0644]
blocks/online_users/lang/en/block_online_users.php
blocks/online_users/version.php
blocks/rss_client/backup/moodle1/lib.php [new file with mode: 0644]
blocks/rss_client/backup/moodle2/restore_rss_client_stepslib.php
blocks/selfcompletion/block_selfcompletion.php
blocks/selfcompletion/db/access.php
blocks/selfcompletion/db/upgrade.php [new file with mode: 0644]
blocks/selfcompletion/lang/en/block_selfcompletion.php
blocks/selfcompletion/version.php
blocks/settings/db/upgrade.php
blocks/tags/edit_form.php
blocks/tags/lang/en/block_tags.php
cache/classes/definition.php
cache/classes/loaders.php
cache/forms.php
cache/stores/static/lib.php
cache/testperformance.php
comment/comment.js
comment/comment_post.php
composer.json
course/category.php
course/dnduploadlib.php
course/externallib.php
course/lib.php
course/publish/backup.php
course/recent_form.php
course/renderer.php
course/rest.php
course/search.php
course/switchrole.php
course/yui/toolboxes/toolboxes.js
enrol/README.txt
enrol/authorize/db/upgrade.php
enrol/category/cli/sync.php
enrol/category/lib.php
enrol/category/locallib.php
enrol/category/tests/sync_test.php
enrol/cohort/ajax.php
enrol/cohort/cli/sync.php
enrol/cohort/edit.php
enrol/cohort/lib.php
enrol/cohort/locallib.php
enrol/cohort/tests/sync_test.php
enrol/cohort/yui/quickenrolment/quickenrolment.js
enrol/database/cli/sync.php
enrol/database/db/upgrade.php
enrol/database/lib.php
enrol/database/tests/sync_test.php
enrol/flatfile/db/upgrade.php
enrol/guest/db/upgrade.php
enrol/imsenterprise/db/upgrade.php
enrol/ldap/lib.php
enrol/locallib.php
enrol/manual/db/upgrade.php
enrol/manual/yui/quickenrolment/quickenrolment.js
enrol/meta/addinstance_form.php
enrol/mnet/db/upgrade.php
enrol/otherusers.php
enrol/paypal/db/upgrade.php
enrol/paypal/ipn.php
enrol/paypal/lib.php
enrol/renderer.php
enrol/self/db/upgrade.php
files/renderer.php
filter/activitynames/db/install.php
filter/algebra/algebradebug.php
filter/algebra/pix.php
filter/glossary/yui/autolinker/autolinker.js
filter/manage.php
filter/mediaplugin/db/install.php
filter/mediaplugin/db/upgrade.php
filter/tex/db/upgrade.php
filter/tex/displaytex.php
filter/tex/pix.php
filter/tex/texdebug.php
filter/upgrade.txt
grade/edit/outcome/edit_form.php
grade/edit/tree/lib.php
grade/export/ods/grade_export_ods.php
grade/export/xls/grade_export_xls.php
grade/grading/form/rubric/db/upgrade.php
grade/report/grader/styles.css
grade/report/lib.php
grade/tests/reportlib_test.php [new file with mode: 0644]
group/externallib.php
install/lang/fi/admin.php
install/lang/fi/error.php
install/lang/fi/install.php
install/lang/fo/langconfig.php
install/lang/fo/moodle.php [new file with mode: 0644]
lang/en/admin.php
lang/en/block.php
lang/en/error.php
lang/en/message.php
lang/en/moodle.php
lang/en/question.php
lang/en/repository.php
lib/accesslib.php
lib/adminlib.php
lib/ajax/blocks.php
lib/authlib.php
lib/blocklib.php
lib/conditionlib.php
lib/datalib.php
lib/db/install.xml
lib/db/upgrade.php
lib/db/upgradelib.php
lib/ddl/database_manager.php
lib/ddl/oracle_sql_generator.php
lib/deprecatedlib.php
lib/dml/pdo_moodle_database.php
lib/dml/tests/dml_test.php
lib/editor/tinymce/db/upgrade.php
lib/editor/tinymce/plugins/dragmath/lib.php
lib/editor/tinymce/plugins/moodleemoticon/lib.php
lib/editor/tinymce/plugins/spellchecker/changelog.txt
lib/editor/tinymce/plugins/spellchecker/classes/GoogleSpell.php
lib/editor/tinymce/plugins/spellchecker/db/upgrade.php
lib/editor/tinymce/plugins/spellchecker/readme_moodle.txt
lib/editor/tinymce/readme_moodle.txt
lib/editor/tinymce/tiny_mce/3.5.7b/plugins/fullscreen/editor_plugin.js
lib/editor/tinymce/tiny_mce/3.5.7b/plugins/fullscreen/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/editor_plugin.js
lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/editor_plugin_src.js
lib/editor/tinymce/tiny_mce/3.5.7b/tiny_mce.js
lib/editor/tinymce/tiny_mce/3.5.7b/tiny_mce_src.js
lib/editor/tinymce/upgrade.txt
lib/excellib.class.php
lib/filebrowser/file_info_context_course.php
lib/filebrowser/file_info_context_coursecat.php
lib/filelib.php
lib/filestorage/tests/file_storage_test.php
lib/filterlib.php
lib/form/filemanager.js
lib/formslib.php
lib/grade/grade_category.php
lib/grade/grade_item.php
lib/javascript-static.js
lib/moodlelib.php
lib/navigationlib.php
lib/odslib.class.php
lib/outputlib.php
lib/outputrenderers.php
lib/outputrequirementslib.php
lib/phpunit/readme.md
lib/pluginlib.php
lib/rsslib.php
lib/sessionlib.php
lib/setuplib.php
lib/tablelib.php
lib/tests/authlib_test.php [new file with mode: 0644]
lib/tests/filter_test.php
lib/tests/moodlelib_test.php
lib/tests/textlib_test.php
lib/textlib.class.php
lib/timezone.txt
lib/webdavlib.php
lib/weblib.php
lib/yui/blocks/blocks.js
lib/yui/chooserdialogue/chooserdialogue.js
lib/yui/notification/assets/skins/sam/notification.css
lib/yui/notification/notification.js
login/change_password.php
login/change_password_form.php
login/forgot_password.php
login/index.php
login/token.php
login/unlock_account.php [new file with mode: 0644]
message/edit.php
message/lib.php
message/output/email/db/upgrade.php
message/output/jabber/db/upgrade.php
message/output/popup/db/upgrade.php
mnet/lib.php
mod/assign/assignmentplugin.php
mod/assign/db/upgrade.php
mod/assign/feedback/comments/db/upgrade.php
mod/assign/feedback/file/db/upgrade.php
mod/assign/feedback/file/importzipform.php
mod/assign/feedback/file/importziplib.php
mod/assign/feedback/file/locallib.php
mod/assign/feedback/offline/importgradesform.php
mod/assign/feedback/offline/locallib.php
mod/assign/gradingbatchoperationsform.php
mod/assign/gradingoptionsform.php
mod/assign/index.php
mod/assign/lang/en/assign.php
mod/assign/locallib.php
mod/assign/renderable.php
mod/assign/renderer.php
mod/assign/submission/comments/db/upgrade.php
mod/assign/submission/comments/lib.php
mod/assign/submission/comments/locallib.php
mod/assign/submission/file/db/upgrade.php
mod/assign/submission/file/locallib.php
mod/assign/submission/onlinetext/db/upgrade.php
mod/assign/submission/onlinetext/locallib.php
mod/assign/upgradelib.php
mod/assignment/db/upgrade.php
mod/assignment/lib.php
mod/book/db/upgrade.php
mod/chat/db/upgrade.php
mod/choice/db/upgrade.php
mod/choice/report.php
mod/data/data.js
mod/data/db/upgrade.php
mod/data/edit.php
mod/data/field/file/field.class.php
mod/data/field/latlong/kml.php
mod/data/field/picture/field.class.php
mod/data/lib.php
mod/data/version.php
mod/data/view.php
mod/feedback/analysis_to_excel.php
mod/feedback/db/upgrade.php
mod/feedback/item/captcha/captcha_form.php
mod/feedback/item/multichoice/multichoice_form.php
mod/feedback/item/multichoicerated/multichoicerated_form.php
mod/feedback/item/numeric/numeric_form.php
mod/feedback/item/textarea/textarea_form.php
mod/feedback/item/textfield/textfield_form.php
mod/folder/db/upgrade.php
mod/forum/db/services.php [new file with mode: 0644]
mod/forum/db/upgrade.php
mod/forum/externallib.php [new file with mode: 0644]
mod/forum/lib.php
mod/forum/rsslib.php
mod/forum/subscribe.php
mod/forum/tests/externallib_test.php [new file with mode: 0644]
mod/forum/version.php
mod/glossary/db/upgrade.php
mod/imscp/db/upgrade.php
mod/label/db/upgrade.php
mod/lesson/db/upgrade.php
mod/lesson/essay.php
mod/lesson/essay_form.php
mod/lesson/format.php
mod/lesson/view.php
mod/lti/backup/moodle2/backup_lti_stepslib.php
mod/lti/db/upgrade.php
mod/lti/locallib.php
mod/page/db/upgrade.php
mod/quiz/accessrule/upgrade.txt
mod/quiz/db/upgrade.php
mod/quiz/lang/en/quiz.php
mod/quiz/locallib.php
mod/quiz/mod_form.php
mod/quiz/report/attemptsreport_table.php
mod/quiz/report/overview/db/upgrade.php
mod/quiz/report/statistics/db/upgrade.php
mod/quiz/settings.php
mod/quiz/summary.php
mod/resource/db/upgrade.php
mod/scorm/db/upgrade.php
mod/scorm/lang/en/scorm.php
mod/scorm/lib.php
mod/scorm/locallib.php
mod/scorm/mod_form.php
mod/scorm/report/basic/report.php
mod/scorm/report/interactions/report.php
mod/scorm/report/reportlib.php
mod/survey/db/upgrade.php
mod/survey/download.php
mod/upgrade.txt
mod/url/db/upgrade.php
mod/wiki/create.php
mod/wiki/db/upgrade.php
mod/wiki/filesedit.php
mod/wiki/pagelib.php
mod/wiki/parser/utils.php
mod/workshop/db/upgrade.php
mod/workshop/form/accumulative/db/upgrade.php
mod/workshop/form/comments/db/upgrade.php
mod/workshop/form/numerrors/db/upgrade.php
mod/workshop/form/rubric/db/upgrade.php
mod/workshop/lib.php
portfolio/googledocs/db/upgrade.php
portfolio/picasa/db/upgrade.php
question/behaviour/upgrade.txt
question/category.php
question/category_class.php
question/export.php
question/format.php
question/format/blackboard_six/formatbase.php
question/format/blackboard_six/formatpool.php
question/format/blackboard_six/formatqti.php
question/format/blackboard_six/tests/blackboardformatpool_test.php
question/format/blackboard_six/tests/blackboardsixformatqti_test.php
question/format/learnwise/format.php
question/format/learnwise/lang/en/qformat_learnwise.php
question/format/upgrade.txt
question/format/xml/format.php
question/preview.php
question/previewlib.php
question/type/calculated/db/upgrade.php
question/type/calculated/questiontype.php
question/type/essay/db/upgrade.php
question/type/match/db/upgrade.php
question/type/multianswer/db/upgrade.php
question/type/multianswer/edit_multianswer_form.php
question/type/multianswer/question.php
question/type/multianswer/questiontype.php
question/type/multianswer/renderer.php
question/type/multianswer/tests/helper.php
question/type/multianswer/tests/question_test.php
question/type/multianswer/tests/walkthrough_test.php
question/type/multichoice/db/upgrade.php
question/type/numerical/db/upgrade.php
question/type/rendererbase.php
question/type/shortanswer/question.php
question/type/shortanswer/tests/question_test.php
report/log/locallib.php
report/outline/index.php
report/security/locallib.php
repository/dropbox/db/upgrade.php
repository/filepicker.js
repository/googledocs/db/upgrade.php
repository/picasa/db/upgrade.php
repository/s3/lib.php
repository/webdav/lib.php
tag/coursetags_add.php
theme/base/style/core.css
theme/base/style/filemanager.css
theme/base/style/question.css
theme/base/style/user.css
theme/formal_white/config.php
theme/formal_white/db/upgrade.php
theme/formal_white/layout/general.php
theme/formal_white/layout/report.php
theme/formfactor/config.php
theme/formfactor/layout/general.php
theme/formfactor/style/core.css
theme/fusion/config.php
theme/fusion/layout/general.php
theme/fusion/style/core.css
theme/leatherbound/config.php
theme/leatherbound/layout/general.php
theme/leatherbound/layout/report.php
theme/magazine/config.php
theme/magazine/layout/general.php
theme/magazine/style/core.css
theme/mymobile/config.php
theme/mymobile/layout/general.php
theme/nimble/config.php
theme/nimble/layout/general.php
theme/nonzero/config.php
theme/nonzero/layout/general.php
theme/overlay/config.php
theme/overlay/layout/general.php
theme/overlay/style/pagelayout.css
theme/sky_high/config.php
theme/sky_high/layout/general.php
theme/sky_high/layout/report.php
theme/sky_high/style/admin.css
theme/splash/config.php
theme/splash/layout/general.php
theme/splash/layout/report.php
theme/standard/style/css3.css
theme/standardold/config.php
theme/standardold/layout/frontpage.php
theme/standardold/layout/general.php
user/files.php
user/index.php
user/profile.php
user/view.php
version.php
webservice/externallib.php
webservice/tests/externallib_test.php

index c102666..64589cf 100644 (file)
@@ -35,7 +35,7 @@
     require_once($CFG->libdir . '/adminlib.php');
 
     $action = optional_param('action', '', PARAM_ALPHANUMEXT);
-    $filterpath = optional_param('filterpath', '', PARAM_PATH);
+    $filterpath = optional_param('filterpath', '', PARAM_SAFEDIR);
 
     require_login();
     $systemcontext = context_system::instance();
 
     case 'down':
         if (isset($filters[$filterpath])) {
-            $oldpos = $filters[$filterpath]->sortorder;
-            if ($oldpos <= count($filters)) {
-                filter_set_global_state($filterpath, $filters[$filterpath]->active, $oldpos + 1);
-            }
+            filter_set_global_state($filterpath, $filters[$filterpath]->active, 1);
         }
         break;
 
     case 'up':
         if (isset($filters[$filterpath])) {
             $oldpos = $filters[$filterpath]->sortorder;
-            if ($oldpos >= 1) {
-                filter_set_global_state($filterpath, $filters[$filterpath]->active, $oldpos - 1);
-            }
+            filter_set_global_state($filterpath, $filters[$filterpath]->active, -1);
         }
         break;
 
     case 'delete':
-        if (!empty($filternames[$filterpath])) {
-            $filtername = $filternames[$filterpath];
-        } else {
-            $filtername = $filterpath;
-        }
-
-        if (substr($filterpath, 0, 4) == 'mod/') {
-            $mod = basename($filterpath);
-            $a = new stdClass;
-            $a->filter = $filtername;
-            $a->module = get_string('modulename', $mod);
-            print_error('cannotdeletemodfilter', 'admin', $returnurl, $a);
-        }
-
         // If not yet confirmed, display a confirmation message.
         if (!optional_param('confirm', '', PARAM_BOOL)) {
+            $filtername = filter_get_name($filterpath);
+
             $title = get_string('deletefilterareyousure', 'admin', $filtername);
             echo $OUTPUT->header();
             echo $OUTPUT->heading($title);
         }
 
         // Do the deletion.
-        $title = get_string('deletingfilter', 'admin', $filtername);
+        $title = get_string('deletingfilter', 'admin', $filterpath);
         echo $OUTPUT->header();
         echo $OUTPUT->heading($title);
 
         filter_delete_all_for_filter($filterpath);
 
         $a = new stdClass;
-        $a->filter = $filtername;
-        $a->directory = $filterpath;
+        $a->filter = $filterpath;
+        $a->directory = "$CFG->dirroot/filter/$filterpath";
         echo $OUTPUT->box(get_string('deletefilterfiles', 'admin', $a), 'generalbox', 'notice');
         echo $OUTPUT->continue_button($returnurl);
         echo $OUTPUT->footer();
@@ -241,7 +224,7 @@ function get_table_row($filterinfo, $isfirstrow, $islastactive, $applytostrings)
     }
 
     // Disable/off/on
-    $select = new single_select(filters_action_url($filter, 'setstate'), 'newstate', $activechoices, $filterinfo->active, null, 'active' . basename($filter));
+    $select = new single_select(filters_action_url($filter, 'setstate'), 'newstate', $activechoices, $filterinfo->active, null, 'active' . $filter);
     $select->set_label(get_string('isactive', 'filters'), array('class' => 'accesshide'));
     $row[] = $OUTPUT->render($select);
 
@@ -263,25 +246,20 @@ function get_table_row($filterinfo, $isfirstrow, $islastactive, $applytostrings)
     $row[] = $updown;
 
     // Apply to strings.
-    $select = new single_select(filters_action_url($filter, 'setapplyto'), 'stringstoo', $applytochoices, $applytostrings, null, 'applyto' . basename($filter));
+    $select = new single_select(filters_action_url($filter, 'setapplyto'), 'stringstoo', $applytochoices, $applytostrings, null, 'applyto' . $filter);
     $select->set_label(get_string('applyto', 'filters'), array('class' => 'accesshide'));
     $select->disabled = $filterinfo->active == TEXTFILTER_DISABLED;
     $row[] = $OUTPUT->render($select);
 
     // Settings link, if required
     if (filter_has_global_settings($filter)) {
-        $row[] = '<a href="' . $CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=filtersetting' .
-                str_replace('/', '',$filter) . '">' . get_string('settings') . '</a>';
+        $row[] = '<a href="' . $CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=filtersetting' . $filter . '">' . get_string('settings') . '</a>';
     } else {
         $row[] = '';
     }
 
     // Delete
-    if (substr($filter, 0, 4) != 'mod/') {
-        $row[] = '<a href="' . filters_action_url($filter, 'delete') . '">' . get_string('delete') . '</a>';
-    } else {
-        $row[] = '';
-    }
+    $row[] = '<a href="' . filters_action_url($filter, 'delete') . '">' . get_string('delete') . '</a>';
 
     return $row;
 }
index 189bf87..94b379d 100644 (file)
@@ -59,6 +59,11 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
     $temp->add(new admin_setting_configcheckbox('cronclionly', new lang_string('cronclionly', 'admin'), new lang_string('configcronclionly', 'admin'), 0));
     $temp->add(new admin_setting_configpasswordunmask('cronremotepassword', new lang_string('cronremotepassword', 'admin'), new lang_string('configcronremotepassword', 'admin'), ''));
 
+    $options = array(0=>get_string('no'), 3=>3, 5=>5, 7=>7, 10=>10, 20=>20, 30=>30, 50=>50, 100=>100);
+    $temp->add(new admin_setting_configselect('lockoutthreshold', new lang_string('lockoutthreshold', 'admin'), new lang_string('lockoutthreshold_desc', 'admin'), 0, $options));
+    $temp->add(new admin_setting_configduration('lockoutwindow', new lang_string('lockoutwindow', 'admin'), new lang_string('lockoutwindow_desc', 'admin'), 60*30));
+    $temp->add(new admin_setting_configduration('lockoutduration', new lang_string('lockoutduration', 'admin'), new lang_string('lockoutduration_desc', 'admin'), 60*30));
+
     $temp->add(new admin_setting_configcheckbox('passwordpolicy', new lang_string('passwordpolicy', 'admin'), new lang_string('configpasswordpolicy', 'admin'), 1));
     $temp->add(new admin_setting_configtext('minpasswordlength', new lang_string('minpasswordlength', 'admin'), new lang_string('configminpasswordlength', 'admin'), 8, PARAM_INT));
     $temp->add(new admin_setting_configtext('minpassworddigits', new lang_string('minpassworddigits', 'admin'), new lang_string('configminpassworddigits', 'admin'), 1, PARAM_INT));
index 07c7e3b..c8bc6b0 100644 (file)
@@ -34,5 +34,9 @@ function xmldb_tool_customlang_upgrade($oldversion) {
     // Put any upgrade step following this
 
 
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this
+
+
     return true;
 }
index 8db37d0..9a6a104 100644 (file)
@@ -285,7 +285,11 @@ if ($formdata = $mform2->is_cancelled()) {
             $userserrors++;
             continue;
         }
-
+        if ($user->username !== clean_param($user->username, PARAM_USERNAME)) {
+            $upt->track('status', get_string('invalidusername', 'error', 'username'), 'error');
+            $upt->track('username', $errorstr, 'error');
+            $userserrors++;
+        }
         if ($existinguser = $DB->get_record('user', array('username'=>$user->username, 'mnethostid'=>$CFG->mnet_localhost_id))) {
             $upt->track('id', $existinguser->id, 'normal', false);
         }
@@ -900,7 +904,11 @@ if ($formdata = $mform2->is_cancelled()) {
                     $newgroupdata = new stdClass();
                     $newgroupdata->name = $addgroup;
                     $newgroupdata->courseid = $ccache[$shortname]->id;
-                    if ($ccache[$shortname]->groups[$addgroup]->id = groups_create_group($newgroupdata)){
+                    $newgroupdata->description = '';
+                    $gid = groups_create_group($newgroupdata);
+                    if ($gid){
+                        $ccache[$shortname]->groups[$addgroup] = new stdClass();
+                        $ccache[$shortname]->groups[$addgroup]->id   = $gid;
                         $ccache[$shortname]->groups[$addgroup]->name = $newgroupdata->name;
                     } else {
                         $upt->track('enrolments', get_string('unknowngroup', 'error', s($addgroup)), 'error');
index 97f1abb..aac7112 100644 (file)
@@ -2,6 +2,7 @@
 
     require_once('../config.php');
     require_once($CFG->libdir.'/adminlib.php');
+    require_once($CFG->libdir.'/authlib.php');
     require_once($CFG->dirroot.'/user/filters/lib.php');
 
     $delete       = optional_param('delete', 0, PARAM_INT);
@@ -16,6 +17,7 @@
     $acl          = optional_param('acl', '0', PARAM_INT);           // id of user to tweak mnet ACL (requires $access)
     $suspend      = optional_param('suspend', 0, PARAM_INT);
     $unsuspend    = optional_param('unsuspend', 0, PARAM_INT);
+    $unlock       = optional_param('unlock', 0, PARAM_INT);
 
     admin_externalpage_setup('editusers');
 
@@ -32,6 +34,7 @@
     $strshowallusers = get_string('showallusers');
     $strsuspend = get_string('suspenduser', 'admin');
     $strunsuspend = get_string('unsuspenduser', 'admin');
+    $strunlock = get_string('unlockaccount', 'admin');
     $strconfirm = get_string('confirm');
 
     if (empty($CFG->loginhttps)) {
             }
         }
         redirect($returnurl);
+
+    } else if ($unlock and confirm_sesskey()) {
+        require_capability('moodle/user:update', $sitecontext);
+
+        if ($user = $DB->get_record('user', array('id'=>$unlock, 'mnethostid'=>$CFG->mnet_localhost_id, 'deleted'=>0))) {
+            login_unlock_account($user);
+        }
+        redirect($returnurl);
     }
 
     // create the user filter form
                         }
                     }
 
+                    if (login_is_lockedout($user)) {
+                        $buttons[] = html_writer::link(new moodle_url($returnurl, array('unlock'=>$user->id, 'sesskey'=>sesskey())), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/unlock'), 'alt'=>$strunlock, 'class'=>'iconsmall')), array('title'=>$strunlock));
+                    }
                 }
             }
 
index 21ceba0..5d6ea51 100644 (file)
@@ -81,7 +81,7 @@ function user_download_ods($fields) {
 
     $worksheet = array();
 
-    $worksheet[0] =& $workbook->add_worksheet('');
+    $worksheet[0] = $workbook->add_worksheet('');
     $col = 0;
     foreach ($fields as $fieldname) {
         $worksheet[0]->write(0, $col, $fieldname);
@@ -119,7 +119,7 @@ function user_download_xls($fields) {
 
     $worksheet = array();
 
-    $worksheet[0] =& $workbook->add_worksheet('');
+    $worksheet[0] = $workbook->add_worksheet('');
     $col = 0;
     foreach ($fields as $fieldname) {
         $worksheet[0]->write(0, $col, $fieldname);
index fed0bae..e8abd12 100644 (file)
@@ -711,7 +711,7 @@ class auth_plugin_ldap extends auth_plugin_base {
 /// User removal
         // Find users in DB that aren't in ldap -- to be removed!
         // this is still not as scalable (but how often do we mass delete?)
-        if ($this->config->removeuser !== AUTH_REMOVEUSER_KEEP) {
+        if ($this->config->removeuser != AUTH_REMOVEUSER_KEEP) {
             $sql = 'SELECT u.*
                       FROM {user} u
                       LEFT JOIN {tmp_extuser} e ON (u.username = e.username AND u.mnethostid = e.mnethostid)
index 46fd720..0c37b61 100644 (file)
@@ -37,5 +37,9 @@ function xmldb_auth_manual_upgrade($oldversion) {
     // Put any upgrade step following this
 
 
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this
+
+
     return true;
 }
index d10cda5..2f65822 100644 (file)
@@ -38,5 +38,9 @@ function xmldb_auth_mnet_upgrade($oldversion) {
     // Put any upgrade step following this
 
 
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this
+
+
     return true;
 }
index 88caf30..61f6ba8 100644 (file)
@@ -7,7 +7,10 @@
     $PAGE->set_url('/auth/shibboleth/index.php');
 
     // Support for WAYFless URLs.
-    $SESSION->wantsurl = optional_param('target', $SESSION->wantsurl, PARAM_LOCALURL);
+    $target = optional_param('target', '', PARAM_LOCALURL);
+    if (!empty($target)) {
+        $SESSION->wantsurl = $target;
+    }
 
     if (isloggedin() && !isguestuser()) {      // Nothing to do
         if (isset($SESSION->wantsurl) and (strpos($SESSION->wantsurl, $CFG->wwwroot) === 0)) {
index 1e93cf2..29943d6 100644 (file)
@@ -40,8 +40,7 @@ if ($show_instructions) {
             </form>
             <p>
             <?php
-                print_string("auth_shibboleth_contact_administrator", "auth_shibboleth");
-                echo '<a href="mailto:'.get_admin()->email.'"> Moodle Administrator</a>.';
+                print_string("auth_shib_contact_administrator", "auth_shibboleth", get_admin()->email);
             ?>
             </p>
           </div>
index aace9a1..ea8980d 100644 (file)
@@ -25,7 +25,7 @@
 
 $string['auth_shib_auth_method'] = 'Authentication method name';
 $string['auth_shib_auth_method_description'] = 'Provide a name for the Shibboleth authentication method that is familiar to your users. This could be the name of your Shibboleth federation, e.g. <tt>SWITCHaai Login</tt> or <tt>InCommon Login</tt> or similar.';
-$string['auth_shibboleth_contact_administrator'] = 'In case you are not associated with the given organizations and you need access to a course on this server, please contact the';
+$string['auth_shib_contact_administrator'] = 'In case you are not associated with the given organizations and you need access to a course on this server, please contact the <a href="mailto:{$a}">Moodle Administrator</a>.';
 $string['auth_shibbolethdescription'] = 'Using this method users are created and authenticated using <a href="http://shibboleth.internet2.edu/">Shibboleth</a>.<br />Be sure to read the <a href="../auth/shibboleth/README.txt">README</a> for Shibboleth on how to set up your Moodle with Shibboleth';
 $string['auth_shibboleth_errormsg'] = 'Please select the organization you are member of!';
 $string['auth_shibboleth_login'] = 'Shibboleth login';
index 1f80265..2847665 100644 (file)
@@ -98,7 +98,7 @@ $PAGE->navbar->add($backup->get_stage_name());
 $renderer = $PAGE->get_renderer('core','backup');
 echo $OUTPUT->header();
 if ($backup->enforce_changed_dependencies()) {
-    echo $renderer->dependency_notification(get_string('dependenciesenforced','backup'));
+    debugging('Your settings have been altered due to unmet dependencies', DEBUG_DEVELOPER);
 }
 echo $renderer->progress_bar($backup->get_progress_bar());
 echo $backup->display($renderer);
index 6b81b7d..ac5584c 100644 (file)
@@ -33,7 +33,7 @@ $currentcontext = required_param('currentcontext', PARAM_INT);
 // file parameters
 $component  = optional_param('component', null, PARAM_COMPONENT);
 $filearea   = optional_param('filearea', null, PARAM_AREA);
-$returnurl  = optional_param('returnurl', null, PARAM_URL);
+$returnurl  = optional_param('returnurl', null, PARAM_LOCALURL);
 
 list($context, $course, $cm) = get_context_info_array($currentcontext);
 $filecontext = context::instance_by_id($contextid, IGNORE_MISSING);
index 51cad64..a2744c2 100644 (file)
@@ -88,10 +88,13 @@ abstract class moodle1_handlers_factory {
         foreach ($plugins as $name => $dir) {
             $handlerfile  = $dir . '/backup/moodle1/lib.php';
             $handlerclass = "moodle1_{$type}_{$name}_handler";
-            if (!file_exists($handlerfile)) {
+            if (file_exists($handlerfile)) {
+                require_once($handlerfile);
+            } elseif ($type == 'block') {
+                $handlerclass = "moodle1_block_generic_handler";
+            } else {
                 continue;
             }
-            require_once($handlerfile);
 
             if (!class_exists($handlerclass)) {
                 throw new moodle1_convert_exception('missing_handler_class', $handlerclass);
@@ -1989,9 +1992,93 @@ abstract class moodle1_resource_successor_handler extends moodle1_mod_handler {
  */
 abstract class moodle1_block_handler extends moodle1_plugin_handler {
 
+    public function get_paths() {
+        $blockname = strtoupper($this->pluginname);
+        return array(
+            new convert_path('block', "/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK/{$blockname}"),
+        );
+    }
+
+    public function process_block(array $data) {
+        $newdata = $this->convert_common_block_data($data);
+
+        $this->write_block_xml($newdata, $data);
+        $this->write_inforef_xml($newdata, $data);
+        $this->write_roles_xml($newdata, $data);
+
+        return $data;
+    }
+
+    protected function convert_common_block_data(array $olddata) {
+        $newdata = array();
+
+        $newdata['blockname'] = $olddata['name'];
+        $newdata['parentcontextid'] = $this->converter->get_contextid(CONTEXT_COURSE, 0);
+        $newdata['showinsubcontexts'] = 0;
+        $newdata['pagetypepattern'] = $olddata['pagetype'].='-*';
+        $newdata['subpagepattern'] = null;
+        $newdata['defaultregion'] = ($olddata['position']=='l')?'side-pre':'side-post';
+        $newdata['defaultweight'] = $olddata['weight'];
+        $newdata['configdata'] = $this->convert_configdata($olddata);
+
+        return $newdata;
+    }
+
+    protected function convert_configdata(array $olddata) {
+        return $olddata['configdata'];
+    }
+
+    protected function write_block_xml($newdata, $data) {
+        $contextid = $this->converter->get_contextid(CONTEXT_BLOCK, $data['id']);
+
+        $this->open_xml_writer("course/blocks/{$data['name']}_{$data['id']}/block.xml");
+        $this->xmlwriter->begin_tag('block', array('id' => $data['id'], 'contextid' => $contextid));
+
+        foreach ($newdata as $field => $value) {
+            $this->xmlwriter->full_tag($field, $value);
+        }
+
+        $this->xmlwriter->begin_tag('block_positions');
+        $this->xmlwriter->begin_tag('block_position', array('id' => 1));
+        $this->xmlwriter->full_tag('contextid', $newdata['parentcontextid']);
+        $this->xmlwriter->full_tag('pagetype', $data['pagetype']);
+        $this->xmlwriter->full_tag('subpage', '');
+        $this->xmlwriter->full_tag('visible', $data['visible']);
+        $this->xmlwriter->full_tag('region', $newdata['defaultregion']);
+        $this->xmlwriter->full_tag('weight', $newdata['defaultweight']);
+        $this->xmlwriter->end_tag('block_position');
+        $this->xmlwriter->end_tag('block_positions');
+        $this->xmlwriter->end_tag('block');
+        $this->close_xml_writer();
+    }
+
+    protected function write_inforef_xml($newdata, $data) {
+        $this->open_xml_writer("course/blocks/{$data['name']}_{$data['id']}/inforef.xml");
+        $this->xmlwriter->begin_tag('inforef');
+        // Subclasses may provide inforef contents if needed
+        $this->xmlwriter->end_tag('inforef');
+        $this->close_xml_writer();
+    }
+
+    protected function write_roles_xml($newdata, $data) {
+        // This is an empty shell, as the moodle1 converter doesn't handle user data.
+        $this->open_xml_writer("course/blocks/{$data['name']}_{$data['id']}/roles.xml");
+        $this->xmlwriter->begin_tag('roles');
+        $this->xmlwriter->full_tag('role_overrides', '');
+        $this->xmlwriter->full_tag('role_assignments', '');
+        $this->xmlwriter->end_tag('roles');
+        $this->close_xml_writer();
+    }
 }
 
 
+/**
+ * Base class for block generic handler
+ */
+class moodle1_block_generic_handler extends moodle1_block_handler {
+
+}
+
 /**
  * Base class for the activity modules' subplugins
  */
index 4fdf62e..4df141f 100644 (file)
@@ -254,7 +254,7 @@ class moodle1_converter extends base_converter {
             $path = '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK/' . $this->currentblock;
 
         } else if (strpos($path, '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK') === 0) {
-            $path = str_replace('/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK', '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK/' . $this->currentmod, $path);
+            $path = str_replace('/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK', '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK/' . $this->currentblock, $path);
         }
 
         if ($path !== $data['path']) {
@@ -350,12 +350,12 @@ class moodle1_converter extends base_converter {
         }
 
         if ($path === '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK') {
-            $this->currentmod = null;
+            $this->currentblock = null;
             $forbidden = true;
 
         } else if (strpos($path, '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK') === 0) {
             // expand the BLOCK paths so that they contain the module name
-            $path = str_replace('/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK', '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK/' . $this->currentmod, $path);
+            $path = str_replace('/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK', '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK/' . $this->currentblock, $path);
         }
 
         if (empty($this->pathelements[$path])) {
@@ -397,7 +397,7 @@ class moodle1_converter extends base_converter {
             $path = '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK/' . $this->currentblock;
 
         } else if (strpos($path, '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK') === 0) {
-            $path = str_replace('/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK', '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK/' . $this->currentmod, $path);
+            $path = str_replace('/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK', '/MOODLE_BACKUP/COURSE/BLOCKS/BLOCK/' . $this->currentblock, $path);
         }
 
         if (empty($this->pathelements[$path])) {
@@ -642,7 +642,9 @@ class moodle1_converter extends base_converter {
         }
         foreach ($matches[2] as $match) {
             $file = str_replace(array('$@FILEPHP@$', '$@SLASH@$', '$@FORCEDOWNLOAD@$'), array('', '/', ''), $match);
-            $files[] = rawurldecode($file);
+            if ($file === clean_param($file, PARAM_PATH)) {
+                $files[] = rawurldecode($file);
+            }
         }
 
         return array_unique($files);
@@ -1210,6 +1212,10 @@ class moodle1_file_manager implements loggable {
 
         $sourcefullpath = $this->basepath.'/'.$sourcepath;
 
+        if ($sourcefullpath !== clean_param($sourcefullpath, PARAM_PATH)) {
+            throw new moodle1_convert_exception('file_invalid_path', $sourcefullpath);
+        }
+
         if (!is_readable($sourcefullpath)) {
             throw new moodle1_convert_exception('file_not_readable', $sourcefullpath);
         }
index bf4935c..154b6c8 100644 (file)
@@ -273,6 +273,15 @@ class moodle1_converter_testcase extends advanced_testcase {
         $fileids = $fileman->get_fileids();
         $this->assertEquals(gettype($fileids), 'array');
         $this->assertEquals(0, count($fileids));
+        // try to migrate an invalid file
+        $fileman->itemid = 1;
+        $thrown = false;
+        try {
+            $fileman->migrate_file('/../../../../../../../../../../../../../../etc/passwd');
+        } catch (moodle1_convert_exception $e) {
+            $thrown = true;
+        }
+        $this->assertTrue($thrown);
         // migrate a single file
         $fileman->itemid = 4;
         $fileman->migrate_file('moddata/unittest/4/icon.gif');
@@ -435,6 +444,8 @@ class moodle1_converter_testcase extends advanced_testcase {
 
         $text = 'This is a text containing links to file.php
 as it is parsed from the backup file. <br /><br /><img border="0" width="110" vspace="0" hspace="0" height="92" title="News" alt="News" src="$@FILEPHP@$$@SLASH@$pics$@SLASH@$news.gif" /><a href="$@FILEPHP@$$@SLASH@$pics$@SLASH@$news.gif$@FORCEDOWNLOAD@$">download image</a><br />
+    <div><a href=\'$@FILEPHP@$/../../../../../../../../../../../../../../../etc/passwd\'>download passwords</a></div>
+    <div><a href=\'$@FILEPHP@$$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$etc$@SLASH@$shadow\'>download shadows</a></div>
     <br /><a href=\'$@FILEPHP@$$@SLASH@$MANUAL.DOC$@FORCEDOWNLOAD@$\'>download manual</a><br />';
 
         $files = moodle1_converter::find_referenced_files($text);
@@ -446,6 +457,8 @@ as it is parsed from the backup file. <br /><br /><img border="0" width="110" vs
         $text = moodle1_converter::rewrite_filephp_usage($text, array('/pics/news.gif', '/another/file/notused.txt'));
         $this->assertEquals($text, 'This is a text containing links to file.php
 as it is parsed from the backup file. <br /><br /><img border="0" width="110" vspace="0" hspace="0" height="92" title="News" alt="News" src="@@PLUGINFILE@@/pics/news.gif" /><a href="@@PLUGINFILE@@/pics/news.gif?forcedownload=1">download image</a><br />
+    <div><a href=\'$@FILEPHP@$/../../../../../../../../../../../../../../../etc/passwd\'>download passwords</a></div>
+    <div><a href=\'$@FILEPHP@$$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$etc$@SLASH@$shadow\'>download shadows</a></div>
     <br /><a href=\'$@FILEPHP@$$@SLASH@$MANUAL.DOC$@FORCEDOWNLOAD@$\'>download manual</a><br />');
     }
 
index 79096c0..4de77b2 100644 (file)
@@ -154,7 +154,7 @@ $PAGE->navbar->add($backup->get_stage_name());
 // Display the current stage
 echo $OUTPUT->header();
 if ($backup->enforce_changed_dependencies()) {
-    echo $renderer->dependency_notification(get_string('dependenciesenforced','backup'));
+    debugging('Your settings have been altered due to unmet dependencies', DEBUG_DEVELOPER);
 }
 echo $renderer->progress_bar($backup->get_progress_bar());
 echo $backup->display($renderer);
index fe4f504..b7da2d3 100644 (file)
@@ -190,6 +190,15 @@ class restore_gradebook_structure_step extends restore_structure_step {
                 $data->id = $newitemid = $existinggradeitem->id;
                 $DB->update_record('grade_items', $data);
             }
+        } else if ($data->itemtype == 'manual') {
+            // Manual items aren't assigned to a cm, so don't go duplicating them in the target if one exists.
+            $gi = array(
+                'itemtype' => $data->itemtype,
+                'courseid' => $data->courseid,
+                'itemname' => $data->itemname,
+                'categoryid' => $data->categoryid,
+            );
+            $newitemid = $DB->get_field('grade_items', 'id', $gi);
         }
 
         if (empty($newitemid)) {
@@ -288,8 +297,13 @@ class restore_gradebook_structure_step extends restore_structure_step {
 
         $data->courseid = $this->get_courseid();
 
-        $newitemid = $DB->insert_record('grade_settings', $data);
-        //$this->set_mapping('grade_setting', $oldid, $newitemid);
+        if (!$DB->record_exists('grade_settings', array('courseid' => $data->courseid, 'name' => $data->name))) {
+            $newitemid = $DB->insert_record('grade_settings', $data);
+        } else {
+            $newitemid = $data->id;
+        }
+
+        $this->set_mapping('grade_setting', $oldid, $newitemid);
     }
 
     /**
@@ -1259,11 +1273,11 @@ class restore_section_structure_step extends restore_structure_step {
         $sectionid = $this->get_task()->get_sectionid();
 
         // Get data object for current section availability (if any).
-        $data = $DB->get_record('course_sections_availability',
-                array('coursesectionid' => $sectionid), 'id, sourcecmid, gradeitemid', IGNORE_MISSING);
+        $records = $DB->get_records('course_sections_availability',
+                array('coursesectionid' => $sectionid), 'id, sourcecmid, gradeitemid');
 
         // If it exists, update mappings.
-        if ($data) {
+        foreach ($records as $data) {
             // Only update mappings for entries which are created by this restore.
             // Otherwise, when you restore to an existing course, it will mess up
             // existing section availability entries.
@@ -1808,6 +1822,14 @@ class restore_filters_structure_step extends restore_structure_step {
 
         $data = (object)$data;
 
+        if (strpos($data->filter, 'filter/') === 0) {
+            $data->filter = substr($data->filter, 7);
+
+        } else if (strpos($data->filter, '/') !== false) {
+            // Unsupported old filter.
+            return;
+        }
+
         if (!filter_is_enabled($data->filter)) { // Not installed or not enabled, nothing to do
             return;
         }
@@ -1818,6 +1840,14 @@ class restore_filters_structure_step extends restore_structure_step {
 
         $data = (object)$data;
 
+        if (strpos($data->filter, 'filter/') === 0) {
+            $data->filter = substr($data->filter, 7);
+
+        } else if (strpos($data->filter, '/') !== false) {
+            // Unsupported old filter.
+            return;
+        }
+
         if (!filter_is_enabled($data->filter)) { // Not installed or not enabled, nothing to do
             return;
         }
@@ -3072,9 +3102,6 @@ class restore_create_categories_and_questions extends restore_structure_step {
             $data->penalty = 1;
         }
 
-        $data->timecreated  = $this->apply_date_offset($data->timecreated);
-        $data->timemodified = $this->apply_date_offset($data->timemodified);
-
         $userid = $this->get_mappingid('user', $data->createdby);
         $data->createdby = $userid ? $userid : $this->task->get_userid();
 
index 2ac6b78..6091c09 100644 (file)
@@ -61,7 +61,7 @@ $PAGE->navbar->add($restore->get_stage_name());
 $renderer = $PAGE->get_renderer('core','backup');
 echo $OUTPUT->header();
 if (!$restore->is_independent() && $restore->enforce_changed_dependencies()) {
-    echo $renderer->dependency_notification(get_string('dependenciesenforced','backup'));
+    debugging('Your settings have been altered due to unmet dependencies', DEBUG_DEVELOPER);
 }
 echo $renderer->progress_bar($restore->get_progress_bar());
 echo $restore->display($renderer);
index e4ab4b1..5c05380 100644 (file)
@@ -75,7 +75,7 @@ class file_logger extends base_logger {
         if (substr($this->fullpath, -5) !== '.html') {
             $content = $prefix . str_repeat('  ', $depth) . $message . PHP_EOL;
         } else {
-            $content = $prefix . str_repeat('&nbsp;&nbsp;', $depth) . htmlentities($message, ENT_QUOTES) . '<br/>' . PHP_EOL;
+            $content = $prefix . str_repeat('&nbsp;&nbsp;', $depth) . htmlentities($message, ENT_QUOTES, 'UTF-8') . '<br/>' . PHP_EOL;
         }
         if (false === fwrite($this->fhandle, $content)) {
             throw new base_logger_exception('error_writing_file', $this->fullpath);
index 8bb6811..2eaea5b 100644 (file)
@@ -38,7 +38,7 @@ class output_indented_logger extends base_logger {
         if (defined('STDOUT')) {
             echo $prefix . str_repeat('  ', $depth) . $message . PHP_EOL;
         } else {
-            echo $prefix . str_repeat('&nbsp;&nbsp;', $depth) . htmlentities($message, ENT_QUOTES) . '<br/>' . PHP_EOL;
+            echo $prefix . str_repeat('&nbsp;&nbsp;', $depth) . htmlentities($message, ENT_QUOTES, 'UTF-8') . '<br/>' . PHP_EOL;
         }
         flush();
         return true;
index fe61536..9d13dfd 100644 (file)
@@ -37,7 +37,7 @@ class output_text_logger extends base_logger {
         if (defined('STDOUT')) {
             echo $prefix . $message . PHP_EOL;
         } else {
-            echo $prefix . htmlentities($message, ENT_QUOTES) . '<br/>' . PHP_EOL;
+            echo $prefix . htmlentities($message, ENT_QUOTES, 'UTF-8') . '<br/>' . PHP_EOL;
         }
         flush();
         return true;
index ce95e7a..fb0e975 100644 (file)
@@ -322,6 +322,7 @@ abstract class base_moodleform extends moodleform {
         $config->question = get_string('confirmcancelquestion', 'backup');
         $config->yesLabel = get_string('confirmcancelyes', 'backup');
         $config->noLabel = get_string('confirmcancelno', 'backup');
+        $config->closeButtonTitle = get_string('close', 'editor');
         $PAGE->requires->yui_module('moodle-backup-confirmcancel', 'M.core_backup.watch_cancel_buttons', array($config));
 
         $PAGE->requires->yui_module('moodle-backup-backupselectall', 'M.core_backup.select_all_init',
index 3702f11..5609581 100644 (file)
@@ -69,7 +69,7 @@ class block_community extends block_list {
         }
 
         $icon = html_writer::empty_tag('img', array('src' => $OUTPUT->pix_url('i/group'),
-                    'class' => 'icon', 'alt' => get_string('addcourse', 'block_community')));
+                    'class' => 'icon', 'alt' => ""));
         $addcourseurl = new moodle_url('/blocks/community/communitycourse.php',
                         array('add' => true, 'courseid' => $this->page->course->id));
         $searchlink = html_writer::tag('a', $icon . get_string('addcourse', 'block_community'),
index 3e6497f..045e72d 100644 (file)
@@ -228,10 +228,10 @@ if (!empty($courses)) {
     }
 }
 $PAGE->requires->yui_module('moodle-block_community-comments', 'M.blocks_community.init_comments',
-        array(array('commentids' => $commentedcourseids)));
+        array(array('commentids' => $commentedcourseids, 'closeButtonTitle' => get_string('close', 'editor'))));
 $PAGE->requires->yui_module('moodle-block_community-imagegallery', 'M.blocks_community.init_imagegallery',
         array(array('imageids' => $courseids, 'imagenumbers' => $courseimagenumbers,
-                'huburl' => $huburl)));
+                'huburl' => $huburl, 'closeButtonTitle' => get_string('close', 'editor'))));
 
 echo highlight($search, $renderer->course_list($courses, $huburl, $courseid));
 
index 53e2222..c0fb9f9 100644 (file)
@@ -50,5 +50,9 @@ function xmldb_block_community_upgrade($oldversion) {
     // Put any upgrade step following this
 
 
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this
+
+
     return true;
 }
index 97e6e1d..28d6162 100644 (file)
     background-color:#F6F6F6;
     border:1px solid #CCCCCC;
     overflow: auto;
+    padding: 7px 6px;
 }
 
 #page-blocks-community-communitycourse .moodle-dialogue-base .moodle-dialogue-bd {
 
 #page-blocks-community-communitycourse .moodle-dialogue-base .closebutton {
     margin-top:4px;
-    width:30px;
-}
\ No newline at end of file
+    margin-right: 4px;
+}
index c32b75e..a591ad9 100644 (file)
@@ -9,8 +9,8 @@ YUI.add('moodle-block_community-comments', function(Y) {
     Y.extend(COMMENTS, Y.Base, {
 
         event:null,
-        overlayevent:null,
-        overlays: [], //all the comment boxes
+        panelevent: null,
+        panels: [], //all the comment boxes
 
         initializer : function(params) {
 
@@ -18,17 +18,19 @@ YUI.add('moodle-block_community-comments', function(Y) {
             for (var i=0;i<this.get('commentids').length;i++)
             {
                 var commentid = this.get('commentids')[i];
-                this.overlays[commentid] = new M.core.dialogue({
-                    headerContent:Y.one('#commentoverlay-'+commentid+' .commenttitle').get('innerHTML'),
+                this.panels[commentid] = new M.core.dialogue({
+                    headerContent:Y.Node.create('<h1>')
+                        .append(Y.one('#commentoverlay-'+commentid+' .commenttitle').get('innerHTML')),
                     bodyContent:Y.one('#commentoverlay-'+commentid).get('innerHTML'),
                     visible: false, //by default it is not displayed
                     lightbox : false,
-                    zIndex:100
+                    zIndex:100,
+                    closeButtonTitle: this.get('closeButtonTitle')
                 });
 
-                this.overlays[commentid].get('contentBox').one('.commenttitle').remove();
-                this.overlays[commentid].render();
-                this.overlays[commentid].hide();
+                this.panels[commentid].get('contentBox').one('.commenttitle').remove();
+                this.panels[commentid].render();
+                this.panels[commentid].hide();
 
                 Y.one('#comments-'+commentid).on('click', this.show, this, commentid);
             }
@@ -37,34 +39,37 @@ YUI.add('moodle-block_community-comments', function(Y) {
 
         show : function (e, commentid) {
 
-            //hide all overlays
+            // Hide all panels.
             for (var i=0;i<this.get('commentids').length;i++)
             {
                 this.hide(e, this.get('commentids')[i]);
             }
 
-            this.overlays[commentid].show(); //show the overlay
+            this.panels[commentid].show(); //show the panel
 
-            e.halt(); // we are going to attach a new 'hide overlay' event to the body,
+            e.halt(); // we are going to attach a new 'hide panel' event to the body,
             // because javascript always propagate event to parent tag,
             // we need to tell Yahoo to stop to call the event on parent tag
             // otherwise the hide event will be call right away.
 
-            //we add a new event on the body in order to hide the overlay for the next click
+            // We add a new event on the body in order to hide the panel for the next click.
             this.event = Y.one(document.body).on('click', this.hide, this, commentid);
-            //we add a new event on the overlay in order to hide the overlay for the next click (touch device)
-            this.overlayevent = Y.one("#commentoverlay-"+commentid).on('click', this.hide, this, commentid);
+            // We add a new event on the panel in order to hide the panel for the next click (touch device).
+            this.panelevent = Y.one("#commentoverlay-"+commentid).on('click', this.hide, this, commentid);
+
+            // Focus on the close button
+            this.panels[commentid].get('buttons').header[0].focus();
         },
 
         hide : function (e, commentid) {
-            this.overlays[commentid].hide(); //hide the overlay
+            this.panels[commentid].hide(); //hide the panel
             if (this.event != null) {
                 this.event.detach(); //we need to detach the body hide event
             //Note: it would work without but create js warning everytime
             //we click on the body
             }
-            if (this.overlayevent != null) {
-                this.overlayevent.detach(); //we need to detach the overlay hide event
+            if (this.panelevent != null) {
+                this.panelevent.detach(); //we need to detach the panel hide event
             //Note: it would work without but create js warning everytime
             //we click on the body
             }
@@ -74,7 +79,11 @@ YUI.add('moodle-block_community-comments', function(Y) {
     }, {
         NAME : COMMENTSNAME,
         ATTRS : {
-            commentids: {}
+            commentids: {},
+            closeButtonTitle : {
+                validator : Y.Lang.isString,
+                value : 'Close'
+            }
         }
     });
 
@@ -84,5 +93,5 @@ YUI.add('moodle-block_community-comments', function(Y) {
     }
 
 }, '@VERSION@', {
-    requires:['base','overlay', 'moodle-core-notification']
+    requires:['base', 'moodle-core-notification']
 });
index e7072aa..7696f20 100644 (file)
@@ -11,8 +11,8 @@ YUI.add('moodle-block_community-imagegallery', function(Y) {
         event:null,
         previousevent:null,
         nextevent:null,
-        overlayevent:null,
-        overlay:null, //all the comment boxes
+        panelevent:null,
+        panel:null, //all the images boxes
         imageidnumbers: [],
         imageloadingevent: null,
         loadingimage: null,
@@ -26,15 +26,15 @@ YUI.add('moodle-block_community-imagegallery', function(Y) {
                 +'</div>');
             objBody.append(this.loadingimage);
 
-            /// create the div for overlay
+            // Create the div for panel.
             var objBody = Y.one(document.body);
-            var overlaytitle = Y.Node.create('<div id="imagetitleoverlay" class="hiddenoverlay"></div>');
-            objBody.append(overlaytitle);
-            var overlay = Y.Node.create('<div id="imageoverlay" class="hiddenoverlay"></div>');
-            objBody.append(overlay);
+            var paneltitle = Y.Node.create('<div id="imagetitleoverlay" class="hiddenoverlay"></div>');
+            objBody.append(paneltitle);
+            var panel = Y.Node.create('<div id="imageoverlay" class="hiddenoverlay"></div>');
+            objBody.append(panel);
 
-            /// create the overlay
-            this.overlay = new M.core.dialogue({
+            /// Create the panel.
+            this.panel = new M.core.dialogue({
                 headerContent:Y.one('#imagetitleoverlay').get('innerHTML'),
                 bodyContent:Y.one('#imageoverlay').get('innerHTML'),
                 visible: false, //by default it is not displayed
@@ -42,8 +42,8 @@ YUI.add('moodle-block_community-imagegallery', function(Y) {
                 zIndex:100
             });
 
-            this.overlay.render();
-            this.overlay.hide();
+            this.panel.render();
+            this.panel.hide();
 
             //attach a show event on the image divs (<tag id='image-X'>)
             for (var i=0;i<this.get('imageids').length;i++)
@@ -85,31 +85,31 @@ YUI.add('moodle-block_community-imagegallery', function(Y) {
             var maxheight = windowheight - 150;
 
             //load the title + link to next image
-            var overlaytitle = Y.one('#imagetitleoverlay');
+            var paneltitle = Y.one('#imagetitleoverlay');
             var previousimagelink = "<div id=\"previousarrow\" class=\"imagearrow\">←</div>";
             var nextimagelink = "<div id=\"nextarrow\" class=\"imagearrow\">→</div>";
 
-            /// need to load the images in the overlay
-            var overlay = Y.one('#imageoverlay');
-            overlay.setContent('');
+            // Need to load the images in the panel.
+            var panel = Y.one('#imageoverlay');
+            panel.setContent('');
 
-
-            overlay.append(Y.Node.create('<div style="text-align:center"><img id=\"imagetodisplay\" src="' + url
+            panel.append(Y.Node.create('<div style="text-align:center"><img id=\"imagetodisplay\" src="' + url
                 + '" style="max-height:' + maxheight + 'px;"></div>'));
-            this.overlay.destroy();
-            this.overlay = new M.core.dialogue({
-                headerContent:previousimagelink + '<div id=\"imagenumber\" class=\"imagetitle\"> Image '
-                + screennumber + ' / ' + this.imageidnumbers[imageid] + ' </div>' + nextimagelink,
+            this.panel.destroy();
+            this.panel = new M.core.dialogue({
+                headerContent:previousimagelink + '<div id=\"imagenumber\" class=\"imagetitle\"><h1> Image '
+                + screennumber + ' / ' + this.imageidnumbers[imageid] + ' </h1></div>' + nextimagelink,
                 bodyContent:Y.one('#imageoverlay').get('innerHTML'),
                 visible: false, //by default it is not displayed
                 lightbox : false,
-                zIndex:100
+                zIndex:100,
+                closeButtonTitle: this.get('closeButtonTitle')
             });
-            this.overlay.render();
-            this.overlay.hide(); //show the overlay
-            this.overlay.set("centered", true);
+            this.panel.render();
+            this.panel.hide(); //show the panel
+            this.panel.set("centered", true);
 
-            e.halt(); // we are going to attach a new 'hide overlay' event to the body,
+            e.halt(); // we are going to attach a new 'hide panel' event to the body,
             // because javascript always propagate event to parent tag,
             // we need to tell Yahoo to stop to call the event on parent tag
             // otherwise the hide event will be call right away.
@@ -123,14 +123,17 @@ YUI.add('moodle-block_community-imagegallery', function(Y) {
                 var screenshot = new Image();
                 screenshot.src = url;
 
-                var overlaywidth = windowwidth - 100;
-                if(overlaywidth > screenshot.width) {
-                    overlaywidth = screenshot.width;
+                var panelwidth = windowwidth - 100;
+                if(panelwidth > screenshot.width) {
+                    panelwidth = screenshot.width;
                 }
 
-                this.overlay.set('width', overlaywidth);
-                this.overlay.set("centered", true);
-                this.overlay.show();
+                this.panel.set('width', panelwidth);
+                this.panel.set("centered", true);
+                this.panel.show();
+
+                // Focus on the close button
+                this.panel.get('buttons').header[0].focus();
 
             }, this, url);
 
@@ -147,12 +150,12 @@ YUI.add('moodle-block_community-imagegallery', function(Y) {
             Y.one('#nextarrow').on('click', this.show, this, imageid, nextnumber);
             Y.one('#imagenumber').on('click', this.show, this, imageid, nextnumber);
 
-            //we add a new event on the body in order to hide the overlay for the next click
+            // We add a new event on the body in order to hide the panel for the next click.
             this.event = Y.one(document.body).on('click', this.hide, this);
-            //we add a new event on the overlay in order to hide the overlay for the next click (touch device)
-            this.overlayevent = Y.one("#imageoverlay").on('click', this.hide, this);
+            // We add a new event on the panel in order to hide the panel for the next click (touch device).
+            this.panelevent = Y.one("#imageoverlay").on('click', this.hide, this);
 
-            this.overlay.on('visibleChange',function(e){
+            this.panel.on('visibleChange',function(e){
                 if(e.newVal == 0){
                     this.get('maskNode').remove()
                 }
@@ -167,14 +170,14 @@ YUI.add('moodle-block_community-imagegallery', function(Y) {
             //hide the loading image
             Y.one('#hubloadingimage').setStyle('display', 'none');
 
-            this.overlay.hide(); //hide the overlay
+            this.panel.hide(); //hide the panel
             if (this.event != null) {
                 this.event.detach(); //we need to detach the body hide event
             //Note: it would work without but create js warning everytime
             //we click on the body
             }
-            if (this.overlayevent != null) {
-                this.overlayevent.detach(); //we need to detach the overlay hide event
+            if (this.panelevent != null) {
+                this.panelevent.detach(); //we need to detach the panel hide event
             //Note: it would work without but create js warning everytime
             //we click on the body
             }
@@ -185,7 +188,11 @@ YUI.add('moodle-block_community-imagegallery', function(Y) {
         ATTRS : {
             imageids: {},
             imagenumbers: {},
-            huburl: {}
+            huburl: {},
+            closeButtonTitle : {
+                validator : Y.Lang.isString,
+                value : 'Close'
+            }
         }
     });
 
@@ -195,5 +202,5 @@ YUI.add('moodle-block_community-imagegallery', function(Y) {
     }
 
 }, '@VERSION@', {
-    requires:['base','node','overlay', 'moodle-core-notification']
+    requires:['base','node', 'moodle-core-notification']
 });
index d098938..12f0ea1 100644 (file)
@@ -38,6 +38,10 @@ class block_completionstatus extends block_base {
         $this->title = get_string('pluginname', 'block_completionstatus');
     }
 
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
+    }
+
     public function get_content() {
         global $USER;
 
index 8220ecc..8d38ec8 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/completionstatus:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/completionstatus:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/completionstatus/db/upgrade.php b/blocks/completionstatus/db/upgrade.php
new file mode 100644 (file)
index 0000000..b5bbe8c
--- /dev/null
@@ -0,0 +1,69 @@
+<?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/>.
+
+/**
+ * This file keeps track of upgrades to the completion status block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_completionstatus_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'completionstatus', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'completionstatus');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index 3c90759..e389743 100644 (file)
@@ -25,7 +25,6 @@
 
 $string['completionprogressdetails'] = 'Completion progress details';
 $string['completionstatus:addinstance'] = 'Add a new course completion status block';
-$string['completionstatus:myaddinstance'] = 'Add a new course completion status block to the My Moodle page';
 $string['criteriagroup'] = 'Criteria group';
 $string['firstofsecond'] = '{$a->first} of {$a->second}';
 $string['pluginname'] = 'Course completion status';
index b97ad8e..218f326 100644 (file)
@@ -26,7 +26,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version      = 2012112900; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version      = 2012112901; // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires     = 2012112900; // Requires this Moodle version
 $plugin->component    = 'block_completionstatus';
-$plugin->dependencies = array('report_completion' => 2012112900);
\ No newline at end of file
+$plugin->dependencies = array('report_completion' => 2012112900);
index 828135c..00752d3 100644 (file)
@@ -34,18 +34,5 @@ $capabilities = array(
         ),
 
         'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
-    'block/course_overview:addinstance' => array(
-        'riskbitmask' => RISK_SPAM | RISK_XSS,
-
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_BLOCK,
-        'archetypes' => array(
-            'editingteacher' => CAP_ALLOW,
-            'manager' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/site:manageblocks'
-    ),
+    )
 );
index d7be855..3535110 100644 (file)
@@ -27,7 +27,6 @@ $string['alwaysshowall'] = 'Always Show All';
 $string['collapseall'] = 'Collapse All Course Lists';
 $string['configotherexpanded'] = 'If enabled, Other Courses will be expanded by default unless overriden by user preferences.';
 $string['configpreservestates'] = 'If enabled, the collapsed/expanded states set by the user are stored and used on each load.';
-$string['course_overview:addinstance'] = 'Add a new course overview block';
 $string['course_overview:myaddinstance'] = 'Add a new course overview block to the My Moodle page';
 $string['defaultmaxcourses'] = 'Default maximum courses';
 $string['defaultmaxcoursesdesc'] = 'Maximum courses which should be displayed on course overview block, 0 will show all courses';
index 9e5a93a..8c42428 100644 (file)
@@ -106,7 +106,9 @@ class block_course_overview_renderer extends plugin_renderer_base {
 
             $attributes = array('title' => s($course->fullname));
             if ($course->id > 0) {
-                $link = html_writer::link(new moodle_url('/course/view.php', array('id' => $course->id)), format_string($course->shortname, true, $course->id), $attributes);
+                $courseurl = new moodle_url('/course/view.php', array('id' => $course->id));
+                $coursefullname = format_string($course->fullname, true, $course->id);
+                $link = html_writer::link($courseurl, $coursefullname, $attributes);
                 $html .= $this->output->heading($link, 2, 'title');
             } else {
                 $html .= $this->output->heading(html_writer::link(
index 51a734f..40abe52 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012121000;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
-$plugin->component = 'block_course_overview'; // Full name of the plugin (used for diagnostics)
\ No newline at end of file
+$plugin->component = 'block_course_overview'; // Full name of the plugin (used for diagnostics)
index cac6591..504c626 100644 (file)
@@ -5,6 +5,10 @@ class block_course_summary extends block_base {
         $this->title = get_string('pluginname', 'block_course_summary');
     }
 
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
+    }
+
     function specialization() {
         if($this->page->pagetype == PAGE_COURSE_VIEW && $this->page->course->id != SITEID) {
             $this->title = get_string('coursesummary', 'block_course_summary');
index 5613ae7..a1e4265 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/course_summary:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/course_summary:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/course_summary/db/upgrade.php b/blocks/course_summary/db/upgrade.php
new file mode 100644 (file)
index 0000000..7a16a1f
--- /dev/null
@@ -0,0 +1,69 @@
+<?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/>.
+
+/**
+ * This file keeps track of upgrades to the course summary block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_course_summary_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'course_summary', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'course_summary');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index 836cbfc..92adcf9 100644 (file)
@@ -25,5 +25,4 @@
 
 $string['coursesummary'] = 'Course summary';
 $string['course_summary:addinstance'] = 'Add a new course/site description block';
-$string['course_summary:myaddinstance'] = 'Add a new course/site description block to the My Moodle page';
 $string['pluginname'] = 'Course/Site description';
index 38cb1cf..d036ba1 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_course_summary'; // Full name of the plugin (used for diagnostics)
index 73249e9..46c0479 100644 (file)
@@ -936,7 +936,7 @@ M.core_dock.genericblock.prototype = {
             }, this);
             // Add a close icon
             // Must set the image src seperatly of we get an error with XML strict headers
-            var closeicon = Y.Node.create('<span class="hidepanelicon" tabindex="0"><img alt="" /></span>');
+            var closeicon = Y.Node.create('<span class="hidepanelicon" tabindex="0"><img alt="'+M.str.block.hidepanel+'" title="'+M.str.block.hidedockpanel+'" /></span>');
             closeicon.one('img').setAttribute('src', M.util.image_url('t/dockclose', 'moodle'));
             closeicon.on('forceclose|click', this.hide, this);
             closeicon.on('dock:actionkey',this.hide, this, {actions:{enter:true,toggle:true}});
index 916780d..af9c550 100644 (file)
@@ -5,10 +5,15 @@ define('BGR_LASTMODIFIED', '1');
 define('BGR_NEXTONE',      '2');
 
 class block_glossary_random extends block_base {
+
     function init() {
         $this->title = get_string('pluginname','block_glossary_random');
     }
 
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
+    }
+
     function specialization() {
         global $CFG, $DB;
 
@@ -137,6 +142,7 @@ class block_glossary_random extends block_base {
             $this->config->cache = '';
             $this->instance_config_commit();
 
+            $this->content = new stdClass();
             $this->content->text   = get_string('notyetconfigured','block_glossary_random');
             $this->content->footer = '';
             return $this->content;
index 0c1acd6..e7bb687 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/glossary_random:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/glossary_random:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/glossary_random/db/upgrade.php b/blocks/glossary_random/db/upgrade.php
new file mode 100644 (file)
index 0000000..81aeabe
--- /dev/null
@@ -0,0 +1,69 @@
+<?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/>.
+
+/**
+ * This file keeps track of upgrades to the glossary random block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_glossary_random_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'glossary_random', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'glossary_random');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index ddb483d..3c51dfa 100644 (file)
@@ -28,7 +28,6 @@ $string['askaddentry'] = 'When users can add entries to the glossary, show a lin
 $string['askinvisible'] = 'When users cannot edit or view the glossary, show this text (without link)';
 $string['askviewglossary'] = 'When users can view the glossary but not add entries, show a link with this text';
 $string['glossary_random:addinstance'] = 'Add a new random glossary entry block';
-$string['glossary_random:myaddinstance'] = 'Add a new random glossary entry block to the My Moodle page';
 $string['intro'] = 'Make sure you have at least one glossary with at least one entry added to this course. Then you can adjust the following settings';
 $string['invisible'] = '(to be continued)';
 $string['lastmodified'] = 'Last modified entry';
index bcca83b..061ec44 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_glossary_random'; // Full name of the plugin (used for diagnostics)
diff --git a/blocks/html/backup/moodle1/lib.php b/blocks/html/backup/moodle1/lib.php
new file mode 100644 (file)
index 0000000..d4a491f
--- /dev/null
@@ -0,0 +1,46 @@
+<?php\r
+\r
+/**\r
+ * Provides support for the conversion of moodle1 backup to the moodle2 format\r
+ *\r
+ * @package    block_html\r
+ * @copyright  2012 Paul Nicholls\r
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\r
+ */\r
+\r
+defined('MOODLE_INTERNAL') || die();\r
+\r
+/**\r
+ * Block conversion handler for html\r
+ */\r
+class moodle1_block_html_handler extends moodle1_block_handler {\r
+    private $fileman = null;\r
+    protected function convert_configdata(array $olddata) {\r
+        $instanceid = $olddata['id'];\r
+        $contextid  = $this->converter->get_contextid(CONTEXT_BLOCK, $olddata['id']);\r
+        $configdata = unserialize(base64_decode($olddata['configdata']));\r
+\r
+        // get a fresh new file manager for this instance\r
+        $this->fileman = $this->converter->get_file_manager($contextid, 'block_html');\r
+\r
+        // convert course files embedded in the block content\r
+        $this->fileman->filearea = 'content';\r
+        $this->fileman->itemid   = 0;\r
+        $configdata->text = moodle1_converter::migrate_referenced_files($configdata->text, $this->fileman);\r
+        $configdata->format = FORMAT_HTML;\r
+\r
+        return base64_encode(serialize($configdata));\r
+    }\r
+\r
+    protected function write_inforef_xml($newdata, $data) {\r
+        $this->open_xml_writer("course/blocks/{$data['name']}_{$data['id']}/inforef.xml");\r
+        $this->xmlwriter->begin_tag('inforef');\r
+        $this->xmlwriter->begin_tag('fileref');\r
+        foreach ($this->fileman->get_fileids() as $fileid) {\r
+            $this->write_xml('file', array('id' => $fileid));\r
+        }\r
+        $this->xmlwriter->end_tag('fileref');\r
+        $this->xmlwriter->end_tag('inforef');\r
+        $this->close_xml_writer();\r
+    }\r
+}
\ No newline at end of file
index 54bb53d..c7ca26b 100644 (file)
@@ -36,5 +36,9 @@ function xmldb_block_html_upgrade($oldversion) {
     // Put any upgrade step following this
 
 
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this
+
+
     return true;
 }
index aa340af..85f48f3 100644 (file)
@@ -7,7 +7,7 @@ class block_mentees extends block_base {
     }
 
     function applicable_formats() {
-        return array('all' => true, 'tag' => false);
+        return array('all' => true, 'tag' => false, 'my' => false);
     }
 
     function specialization() {
index ba14b07..489ceb3 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/mentees:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/mentees:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/mentees/db/upgrade.php b/blocks/mentees/db/upgrade.php
new file mode 100644 (file)
index 0000000..e8aba71
--- /dev/null
@@ -0,0 +1,69 @@
+<?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/>.
+
+/**
+ * This file keeps track of upgrades to the mentees block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_mentees_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'mentees', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'mentees');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index 3a22057..1c0cdab 100644 (file)
@@ -27,6 +27,5 @@ $string['configtitle'] = 'Block title';
 $string['configtitleblankhides'] = 'Block title (no title if blank)';
 $string['leaveblanktohide'] = 'leave blank to hide the title';
 $string['mentees:addinstance'] = 'Add a new mentees block';
-$string['mentees:myaddinstance'] = 'Add a new mentees block to the My Moodle page';
 $string['newmenteesblock'] = '(new Mentees block)';
 $string['pluginname'] = 'Mentees';
index 8ead4fc..c3a8db3 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_mentees';   // Full name of the plugin (used for diagnostics)
index 32c5d8d..7476af8 100644 (file)
@@ -62,5 +62,9 @@ function xmldb_block_navigation_upgrade($oldversion, $block) {
     // Put any upgrade step following this
 
 
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this
+
+
     return true;
 }
\ No newline at end of file
index 5ecbec2..e803c6e 100644 (file)
@@ -5,6 +5,10 @@ class block_news_items extends block_base {
         $this->title = get_string('pluginname', 'block_news_items');
     }
 
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
+    }
+
     function get_content() {
         global $CFG, $USER;
 
index 86bb1b7..452158e 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/news_items:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/news_items:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/news_items/db/upgrade.php b/blocks/news_items/db/upgrade.php
new file mode 100644 (file)
index 0000000..e634e57
--- /dev/null
@@ -0,0 +1,69 @@
+<?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/>.
+
+/**
+ * This file keeps track of upgrades to the latest news block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_news_items_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'news_items', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'news_items');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index d1ab3d8..1de6507 100644 (file)
@@ -24,5 +24,4 @@
  */
 
 $string['news_items:addinstance'] = 'Add a new latest news block';
-$string['news_items:myaddinstance'] = 'Add a new navigation block to the My Moodle page';
 $string['pluginname'] = 'Latest news';
index 4cdea31..11d74ca 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_news_items'; // Full name of the plugin (used for diagnostics)
index 2efe9a2..6d14ebb 100644 (file)
@@ -10,7 +10,13 @@ class block_online_users extends block_base {
         $this->title = get_string('pluginname','block_online_users');
     }
 
-    function has_config() {return true;}
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
+    }
+
+    function has_config() {
+        return true;
+    }
 
     function get_content() {
         global $USER, $CFG, $DB, $OUTPUT;
@@ -151,12 +157,13 @@ class block_online_users extends block_base {
                 $timeago = format_time($now - $user->lastaccess); //bruno to calculate correctly on frontpage
 
                 if (isguestuser($user)) {
-                    $this->content->text .= '<div class="user">'.$OUTPUT->user_picture($user, array('size'=>16));
+                    $this->content->text .= '<div class="user">'.$OUTPUT->user_picture($user, array('size'=>16, 'alttext'=>false));
                     $this->content->text .= get_string('guestuser').'</div>';
 
                 } else {
-                    $this->content->text .= '<div class="user">'.$OUTPUT->user_picture($user, array('size'=>16));
-                    $this->content->text .= '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&amp;course='.$this->page->course->id.'" title="'.$timeago.'">'.$user->fullname.'</a></div>';
+                    $this->content->text .= '<div class="user">';
+                    $this->content->text .= '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&amp;course='.$this->page->course->id.'" title="'.$timeago.'">';
+                    $this->content->text .= $OUTPUT->user_picture($user, array('size'=>16, 'alttext'=>false, 'link'=>false)) .$user->fullname.'</a></div>';
                 }
                 if ($canshowicon and ($USER->id != $user->id) and !isguestuser($user)) {  // Only when logged in and messaging active etc
                     $anchortagcontents = '<img class="iconsmall" src="'.$OUTPUT->pix_url('t/message') . '" alt="'. get_string('messageselectadd') .'" />';
index f238b73..41959c4 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/online_users:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/online_users:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/online_users/db/upgrade.php b/blocks/online_users/db/upgrade.php
new file mode 100644 (file)
index 0000000..f45a788
--- /dev/null
@@ -0,0 +1,69 @@
+<?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/>.
+
+/**
+ * This file keeps track of upgrades to the online users block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_online_users_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'online_users', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'online_users');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index 034fce5..b7a008e 100644 (file)
@@ -25,7 +25,6 @@
 
 $string['configtimetosee'] = 'Number of minutes determining the period of inactivity after which a user is no longer considered to be online.';
 $string['online_users:addinstance'] = 'Add a new online users block';
-$string['online_users:myaddinstance'] = 'Add a new online users block to the My Moodle page';
 $string['online_users:viewlist'] = 'View list of online users';
 $string['periodnminutes'] = 'last {$a} minutes';
 $string['pluginname'] = 'Online users';
index 18e1354..4463c45 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_online_users'; // Full name of the plugin (used for diagnostics)
diff --git a/blocks/rss_client/backup/moodle1/lib.php b/blocks/rss_client/backup/moodle1/lib.php
new file mode 100644 (file)
index 0000000..95da634
--- /dev/null
@@ -0,0 +1,34 @@
+<?php\r
+\r
+/**\r
+ * Provides support for the conversion of moodle1 backup to the moodle2 format\r
+ *\r
+ * @package    block_rss_client\r
+ * @copyright  2012 Paul Nicholls\r
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\r
+ */\r
+\r
+defined('MOODLE_INTERNAL') || die();\r
+\r
+/**\r
+ * Block conversion handler for rss_client\r
+ */\r
+class moodle1_block_rss_client_handler extends moodle1_block_handler {\r
+    public function process_block(array $data) {\r
+        parent::process_block($data);\r
+        $instanceid = $data['id'];\r
+        $contextid = $this->converter->get_contextid(CONTEXT_BLOCK, $data['id']);\r
+\r
+        // Moodle 1.9 backups do not include sufficient data to restore feeds, so we need an empty shell rss_client.xml\r
+        // for the restore process to find\r
+        $this->open_xml_writer("course/blocks/{$data['name']}_{$instanceid}/rss_client.xml");\r
+        $this->xmlwriter->begin_tag('block', array('id' => $instanceid, 'contextid' => $contextid, 'blockname' => 'rss_client'));\r
+        $this->xmlwriter->begin_tag('rss_client', array('id' => $instanceid));\r
+        $this->xmlwriter->full_tag('feeds', '');\r
+        $this->xmlwriter->end_tag('rss_client');\r
+        $this->xmlwriter->end_tag('block');\r
+        $this->close_xml_writer();\r
+\r
+        return $data;\r
+    }\r
+}
\ No newline at end of file
index 8e28ac2..c23d7b9 100644 (file)
@@ -78,6 +78,9 @@ class restore_rss_client_block_structure_step extends restore_structure_step {
         $configdata = $DB->get_field('block_instances', 'configdata', array('id' => $this->task->get_blockid()));
         // Extract configdata
         $config = unserialize(base64_decode($configdata));
+        if (empty($config)) {
+            $config = new stdClass();
+        }
         // Set array of used rss feeds
         $config->rssid = $feedsarr;
         // Serialize back the configdata
index 7a44dfe..9ea6db4 100644 (file)
@@ -36,7 +36,11 @@ require_once($CFG->libdir.'/completionlib.php');
 class block_selfcompletion extends block_base {
 
     public function init() {
-        $this->title   = get_string('pluginname', 'block_selfcompletion');
+        $this->title = get_string('pluginname', 'block_selfcompletion');
+    }
+
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
     }
 
     public function get_content() {
index 489eebd..d91d4d4 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/selfcompletion:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/selfcompletion:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/selfcompletion/db/upgrade.php b/blocks/selfcompletion/db/upgrade.php
new file mode 100644 (file)
index 0000000..fd03025
--- /dev/null
@@ -0,0 +1,69 @@
+<?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/>.
+
+/**
+ * This file keeps track of upgrades to the self completion block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'selfcompletion', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'selfcompletion');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index e7c89d3..457c77c 100644 (file)
@@ -28,4 +28,3 @@ $string['completecourse'] = 'Complete course';
 $string['pluginname'] = 'Self completion';
 $string['selfcompletionnotenabled'] = 'The self completion criteria has not been enabled for this course';
 $string['selfcompletion:addinstance'] = 'Add a new self completion block';
-$string['selfcompletion:myaddinstance'] = 'Add a new self completion block to the My Moodle page';
index 517c84b..2a0d036 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_selfcompletion'; // Full name of the plugin (used for diagnostics)
index feb241a..ca5980f 100644 (file)
@@ -62,5 +62,9 @@ function xmldb_block_settings_upgrade($oldversion, $block) {
     // Put any upgrade step following this
 
 
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this
+
+
     return true;
 }
\ No newline at end of file
index bc5c265..e6bde82 100644 (file)
@@ -33,7 +33,7 @@ class block_tags_edit_form extends block_edit_form {
         // Fields for editing HTML block title and contents.
         $mform->addElement('header', 'configheader', get_string('blocksettings', 'block'));
 
-        $mform->addElement('text', 'config_title', get_string('pluginname', 'block_tags'));
+        $mform->addElement('text', 'config_title', get_string('configtitle', 'block_tags'));
         $mform->setType('config_title', PARAM_TEXT);
         $mform->setDefault('config_title', get_string('pluginname', 'block_tags'));
 
index 7f2d59f..6dcb0b9 100644 (file)
@@ -25,6 +25,7 @@
 $string['add'] = 'Add';
 $string['alltags'] = 'All tags:';
 $string['arrowtitle'] = 'Click here to enter the suggested text (grey letters).';
+$string['configtitle'] = 'Block title';
 $string['coursetags'] = 'Course tags:';
 $string['disabledtags'] = 'Tags are disabled';
 $string['defaultdisplay'] = 'Tag type to display';
index 607f074..e278bbb 100644 (file)
@@ -750,7 +750,7 @@ class cache_definition {
             if (!empty($this->identifiers)) {
                 $identifiers = array();
                 foreach ($this->identifiers as $key => $value) {
-                    $identifiers[] = htmlentities($key).'='.htmlentities($value);
+                    $identifiers[] = htmlentities($key, ENT_QUOTES, 'UTF-8').'='.htmlentities($value, ENT_QUOTES, 'UTF-8');
                 }
                 $this->keyprefixmulti['identifiers'] = join('&', $identifiers);
             }
index 74014c4..028a31e 100644 (file)
@@ -1093,6 +1093,10 @@ class cache_application extends cache implements cache_loader_with_locking {
             $todelete = array();
             // Iterate the returned data for the events.
             foreach ($events as $event => $keys) {
+                if ($keys === false) {
+                    // There are no keys.
+                    continue;
+                }
                 // Look at each key and check the timestamp.
                 foreach ($keys as $key => $timestamp) {
                     // If the timestamp of the event is more than or equal to the last invalidation (happened between the last
index 533f1f8..542e7a0 100644 (file)
@@ -101,7 +101,13 @@ class cachestore_addinstance_form extends moodleform {
         }
 
         if (method_exists($this, 'configuration_validation')) {
-            $errors = $this->configuration_validation($data, $files);
+            $newerrors = $this->configuration_validation($data, $files, $errors);
+            // We need to selectiviliy merge here
+            foreach ($newerrors as $element => $error) {
+                if (!array_key_exists($element, $errors)) {
+                    $errors[$element] = $error;
+                }
+            }
         }
 
         return $errors;
index dcbdbd7..7281fad 100644 (file)
@@ -357,6 +357,7 @@ class cachestore_static extends static_data_store implements cache_is_key_aware
      */
     public function purge() {
         $this->flush_store_by_id($this->storeid);
+        $this->store = &self::register_store_id($this->storeid);
     }
 
     /**
index 2d22751..26796c1 100644 (file)
@@ -61,7 +61,7 @@ foreach (get_plugin_list_with_file('cachestore', 'lib.php', true) as $plugin =>
     $class = 'cachestore_'.$plugin;
     $plugin = get_string('pluginname', 'cachestore_'.$plugin);
 
-    if (!class_exists($class) || !method_exists($class, 'initialise_test_instance')) {
+    if (!class_exists($class) || !method_exists($class, 'initialise_test_instance') || !$class::are_requirements_met()) {
         $applicationtable->data[] = array($plugin, $strinvalidplugin, '-', '-', '-', '-');
         $sessiontable->data[] = array($plugin, $strinvalidplugin, '-', '-', '-', '-');
         $requesttable->data[] = array($plugin, $strinvalidplugin, '-', '-', '-', '-');
index 65dcae8..f0f4ddf 100644 (file)
@@ -184,7 +184,7 @@ bodyContent: '<div class="comment-delete-confirm"><a href="#" id="confirmdelete-
                         val = val.replace('___name___', list[i].fullname);
                     }
                     if (list[i]['delete']||newcmt) {
-                        list[i].content = '<div class="comment-delete"><a href="#" id ="comment-delete-'+this.client_id+'-'+list[i].id+'" title="'+M.str.moodle.deletecomment+'"><img src="'+M.util.image_url('t/delete', 'core')+'" /></a></div>' + list[i].content;
+                        list[i].content = '<div class="comment-delete"><a href="#" id ="comment-delete-'+this.client_id+'-'+list[i].id+'" title="'+M.str.moodle.deletecomment+'"><img alt="" src="'+M.util.image_url('t/delete', 'core')+'" /></a></div>' + list[i].content;
                     }
                     val = val.replace('___time___', list[i].time);
                     val = val.replace('___picture___', list[i].avatar);
index b7a39a8..a960293 100644 (file)
@@ -38,7 +38,7 @@ $action    = optional_param('action',    '',  PARAM_ALPHA);
 $area      = optional_param('area',      '',  PARAM_AREA);
 $content   = optional_param('content',   '',  PARAM_RAW);
 $itemid    = optional_param('itemid',    '',  PARAM_INT);
-$returnurl = optional_param('returnurl', '/', PARAM_URL);
+$returnurl = optional_param('returnurl', '/', PARAM_LOCALURL);
 $component = optional_param('component', '',  PARAM_COMPONENT);
 
 // Currently this script can only add comments
index 94bf886..5f618de 100644 (file)
@@ -1,5 +1,5 @@
 {
-    "require": {
+    "require-dev": {
         "phpunit/phpunit": "3.7.*",
         "phpunit/dbUnit": "1.2.*"
     }
index 33bc709..37138b5 100644 (file)
@@ -191,6 +191,7 @@ if ($editingon && can_edit_in_category()) {
     // Integrate into the admin tree only if the user can edit categories at the top level,
     // otherwise the admin block does not appear to this user, and you get an error.
     require_once($CFG->libdir . '/adminlib.php');
+    navigation_node::override_active_url(new moodle_url('/course/category.php', array('id' => $id)));
     admin_externalpage_setup('coursemgmt', '', $urlparams, $CFG->wwwroot . '/course/category.php');
     $PAGE->set_context($context);   // Ensure that we are actually showing blocks etc for the cat context
 
index 6fb00b0..21dc7a7 100644 (file)
@@ -555,6 +555,15 @@ class dndupload_ajax_processor {
         $this->cm->groupmode = $this->course->groupmode;
         $this->cm->groupingid = $this->course->defaultgroupingid;
 
+        // Set the correct default for completion tracking.
+        $this->cm->completion = COMPLETION_TRACKING_NONE;
+        $completion = new completion_info($this->course);
+        if ($completion->is_enabled()) {
+            if (plugin_supports('mod', $this->cm->modulename, FEATURE_MODEDIT_DEFAULT_COMPLETION, true)) {
+                $this->cm->completion = COMPLETION_TRACKING_MANUAL;
+            }
+        }
+
         if (!$this->cm->id = add_course_module($this->cm)) {
             throw new coding_exception("Unable to create the course module");
         }
index 659228c..b5c82f4 100644 (file)
@@ -211,7 +211,7 @@ class core_course_external extends external_api {
                                 array(
                                     'id' => new external_value(PARAM_INT, 'activity id'),
                                     'url' => new external_value(PARAM_URL, 'activity url', VALUE_OPTIONAL),
-                                    'name' => new external_value(PARAM_TEXT, 'activity module name'),
+                                    'name' => new external_value(PARAM_RAW, 'activity module name'),
                                     'description' => new external_value(PARAM_RAW, 'activity description', VALUE_OPTIONAL),
                                     'visible' => new external_value(PARAM_INT, 'is the module visible', VALUE_OPTIONAL),
                                     'modicon' => new external_value(PARAM_URL, 'activity icon url'),
index 358de6b..a58b86a 100644 (file)
@@ -594,7 +594,7 @@ function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
             $ld = $DB->get_record('log_display', array('module'=>$log->module, 'action'=>$log->action));
             $ldcache[$log->module][$log->action] = $ld;
         }
-        if ($ld && !empty($log->info)) {
+        if ($ld && is_numeric($log->info)) {
             // ugly hack to make sure fullname is shown correctly
             if (($ld->mtable == 'user') and ($ld->field ==  $DB->sql_concat('firstname', "' '" , 'lastname'))) {
                 $log->info = fullname($DB->get_record($ld->mtable, array('id'=>$log->info)), true);
@@ -665,7 +665,7 @@ function print_log_xls($course, $user, $date, $order='l.time DESC', $modname,
     // Creating worksheets
     for ($wsnumber = 1; $wsnumber <= $nroPages; $wsnumber++) {
         $sheettitle = get_string('logs').' '.$wsnumber.'-'.$nroPages;
-        $worksheet[$wsnumber] =& $workbook->add_worksheet($sheettitle);
+        $worksheet[$wsnumber] = $workbook->add_worksheet($sheettitle);
         $worksheet[$wsnumber]->set_column(1, 1, 30);
         $worksheet[$wsnumber]->write_string(0, 0, get_string('savedat').
                                     userdate(time(), $strftimedatetime));
@@ -694,7 +694,7 @@ function print_log_xls($course, $user, $date, $order='l.time DESC', $modname,
             $ld = $DB->get_record('log_display', array('module'=>$log->module, 'action'=>$log->action));
             $ldcache[$log->module][$log->action] = $ld;
         }
-        if ($ld && !empty($log->info)) {
+        if ($ld && is_numeric($log->info)) {
             // ugly hack to make sure fullname is shown correctly
             if (($ld->mtable == 'user') and ($ld->field == $DB->sql_concat('firstname', "' '" , 'lastname'))) {
                 $log->info = fullname($DB->get_record($ld->mtable, array('id'=>$log->info)), true);
@@ -779,7 +779,7 @@ function print_log_ods($course, $user, $date, $order='l.time DESC', $modname,
     // Creating worksheets
     for ($wsnumber = 1; $wsnumber <= $nroPages; $wsnumber++) {
         $sheettitle = get_string('logs').' '.$wsnumber.'-'.$nroPages;
-        $worksheet[$wsnumber] =& $workbook->add_worksheet($sheettitle);
+        $worksheet[$wsnumber] = $workbook->add_worksheet($sheettitle);
         $worksheet[$wsnumber]->set_column(1, 1, 30);
         $worksheet[$wsnumber]->write_string(0, 0, get_string('savedat').
                                     userdate(time(), $strftimedatetime));
@@ -808,7 +808,7 @@ function print_log_ods($course, $user, $date, $order='l.time DESC', $modname,
             $ld = $DB->get_record('log_display', array('module'=>$log->module, 'action'=>$log->action));
             $ldcache[$log->module][$log->action] = $ld;
         }
-        if ($ld && !empty($log->info)) {
+        if ($ld && is_numeric($log->info)) {
             // ugly hack to make sure fullname is shown correctly
             if (($ld->mtable == 'user') and ($ld->field == $DB->sql_concat('firstname', "' '" , 'lastname'))) {
                 $log->info = fullname($DB->get_record($ld->mtable, array('id'=>$log->info)), true);
@@ -1516,8 +1516,9 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
                     $textcss = '';
                 }
 
-                // Get on-click attribute value if specified
-                $onclick = $mod->get_on_click();
+                // Get on-click attribute value if specified and decode the onclick - it
+                // has already been encoded for display (puke).
+                $onclick = htmlspecialchars_decode($mod->get_on_click(), ENT_QUOTES);
 
                 $groupinglabel = '';
                 if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', context_course::instance($course->id))) {
@@ -1656,14 +1657,25 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
                         } else {
                             $extraclass = '';
                         }
-                        echo "
-<form class='togglecompletion$extraclass' method='post' action='".$CFG->wwwroot."/course/togglecompletion.php'><div>
-<input type='hidden' name='id' value='{$mod->id}' />
-<input type='hidden' name='modulename' value='".s($mod->name)."' />
-<input type='hidden' name='sesskey' value='".sesskey()."' />
-<input type='hidden' name='completionstate' value='$newstate' />
-<input type='image' src='$imgsrc' alt='$imgalt' title='$imgtitle' />
-</div></form>";
+                        echo html_writer::start_tag('form', array(
+                                'class' => 'togglecompletion' . $extraclass,
+                                'method' => 'post',
+                                'action' => $CFG->wwwroot . '/course/togglecompletion.php'));
+                        echo html_writer::start_tag('div');
+                        echo html_writer::empty_tag('input', array(
+                                'type' => 'hidden', 'name' => 'id', 'value' => $mod->id));
+                        echo html_writer::empty_tag('input', array(
+                                'type' => 'hidden', 'name' => 'modulename',
+                                'value' => $mod->name));
+                        echo html_writer::empty_tag('input', array(
+                                'type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
+                        echo html_writer::empty_tag('input', array(
+                                'type' => 'hidden', 'name' => 'completionstate',
+                                'value' => $newstate));
+                        echo html_writer::empty_tag('input', array(
+                                'type' => 'image', 'src' => $imgsrc, 'alt' => $imgalt, 'title' => $imgtitle));
+                        echo html_writer::end_tag('div');
+                        echo html_writer::end_tag('form');
                     } else {
                         // In auto mode, or when editing, the icon is just an image
                         echo "<span class='autocompletion'>";
@@ -1683,17 +1695,20 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
             if (!$mod->uservisible) {
                 echo '<div class="availabilityinfo">'.$mod->availableinfo.'</div>';
             } else if ($canviewhidden && !empty($CFG->enableavailability)) {
-                $visibilityclass = '';
-                if (!$mod->visible) {
-                    $visibilityclass = 'accesshide';
-                }
-                $ci = new condition_info($mod);
-                $fullinfo = $ci->get_full_information();
-                if($fullinfo) {
-                    echo '<div class="availabilityinfo '.$visibilityclass.'">'.get_string($mod->showavailability
-                        ? 'userrestriction_visible'
-                        : 'userrestriction_hidden','condition',
-                        $fullinfo).'</div>';
+                // Don't add availability information if user is not editing and activity is hidden.
+                if ($mod->visible || $PAGE->user_is_editing()) {
+                    $hidinfoclass = '';
+                    if (!$mod->visible) {
+                        $hidinfoclass = 'hide';
+                    }
+                    $ci = new condition_info($mod);
+                    $fullinfo = $ci->get_full_information();
+                    if($fullinfo) {
+                        echo '<div class="availabilityinfo '.$hidinfoclass.'">'.get_string($mod->showavailability
+                            ? 'userrestriction_visible'
+                            : 'userrestriction_hidden','condition',
+                            $fullinfo).'</div>';
+                    }
                 }
             }
 
@@ -1830,7 +1845,7 @@ function print_section_add_menus($course, $section, $modnames = null, $vertical=
         // The module chooser link
         $modchooser = html_writer::start_tag('div', array('class' => 'mdl-right'));
         $modchooser.= html_writer::start_tag('div', array('class' => 'section-modchooser'));
-        $icon = $OUTPUT->pix_icon('t/add', $straddeither);
+        $icon = $OUTPUT->pix_icon('t/add', '');
         $span = html_writer::tag('span', $straddeither, array('class' => 'section-modchooser-text'));
         $modchooser .= html_writer::tag('span', $icon . $span, array('class' => 'section-modchooser-link'));
         $modchooser.= html_writer::end_tag('div');
@@ -4493,6 +4508,7 @@ function include_course_ajax($course, $usedmodules = array(), $enabledmodules =
         'courseid' => $course->id,
         'pagetype' => $PAGE->pagetype,
         'pagelayout' => $PAGE->pagelayout,
+        'subpage' => $PAGE->subpage,
         'regions' => $PAGE->blocks->get_regions(),
     );
     $PAGE->requires->yui_module('moodle-core-blocks', 'M.core_blocks.init_dragdrop', array($params), null, true);
@@ -4535,7 +4551,7 @@ function include_course_ajax($course, $usedmodules = array(), $enabledmodules =
     // Add the module chooser
     $PAGE->requires->yui_module('moodle-course-modchooser',
         'M.course.init_chooser',
-        array(array('courseid' => $course->id))
+        array(array('courseid' => $course->id, 'closeButtonTitle' => get_string('close', 'editor')))
     );
     $PAGE->requires->strings_for_js(array(
             'addresourceoractivity',
index cc9c62a..15e091a 100644 (file)
@@ -78,7 +78,7 @@ if ($backup->get_stage() !== backup_ui::STAGE_COMPLETE) {
     echo $OUTPUT->header();
     echo $OUTPUT->heading(get_string('publishcourseon', 'hub', !empty($hubname)?$hubname:$huburl), 3, 'main');
     if ($backup->enforce_changed_dependencies()) {
-        echo $renderer->dependency_notification(get_string('dependenciesenforced', 'backup'));
+        debugging('Your settings have been altered due to unmet dependencies', DEBUG_DEVELOPER);
     }
     echo $renderer->progress_bar($backup->get_progress_bar());
     echo $backup->display($renderer);
index 349fd58..cfdbffa 100644 (file)
@@ -98,6 +98,9 @@ class recent_form extends moodleform {
 
             $mform->addElement('select', 'user', get_string('participants'), $options);
             $mform->setAdvanced('user');
+        } else {
+            // Default to no user.
+            $mform->addElement('hidden', 'user', 0);
         }
 
         $options = array(''=>get_string('allactivities'));
index bbb761e..33c15b4 100644 (file)
@@ -168,6 +168,7 @@ class core_course_renderer extends plugin_renderer_base {
         if ($hascourses) {
             $content .= html_writer::start_tag('div', array('class'=>'courses'));
             $coursecount = 0;
+            $strinfo = new lang_string('info');
             foreach ($category->courses as $course) {
                 $classes = array('course');
                 $linkclass = 'course_link';
@@ -188,8 +189,9 @@ class core_course_renderer extends plugin_renderer_base {
                 }
 
                 if ($course->summary) {
+                    $url = new moodle_url('/course/info.php', array('id' => $course->id));
                     $image = html_writer::empty_tag('img', array('src'=>$this->output->pix_url('i/info'), 'alt'=>$this->strings->summary));
-                    $content .= html_writer::link(new moodle_url('/course/info.php', array('id'=>$course->id)), $image, array('title'=>$this->strings->summary));
+                    $content .= $this->action_link($url, $image, new popup_action('click', $url, 'courseinfo'), array('title' => $this->strings->summary));
                 }
                 $content .= html_writer::end_tag('div');
                 $content .= html_writer::end_tag('div');
index 12371f8..8056c57 100644 (file)
@@ -146,6 +146,7 @@ switch($requestmethod) {
                         break;
                     case 'updatetitle':
                         require_capability('moodle/course:manageactivities', $modcontext);
+                        require_once($CFG->libdir . '/gradelib.php');
                         $cm = get_coursemodule_from_id('', $id, 0, false, MUST_EXIST);
                         $module = new stdClass();
                         $module->id = $cm->instance;
@@ -164,10 +165,16 @@ switch($requestmethod) {
                             $module->name = $cm->name;
                         }
 
+                        // Attempt to update the grade item if relevant
+                        $grademodule = $DB->get_record($cm->modname, array('id' => $cm->instance));
+                        $grademodule->cmidnumber = $cm->idnumber;
+                        $grademodule->modname = $cm->modname;
+                        grade_update_mod_grades($grademodule);
+
                         // We need to return strings after they've been through filters for multilang
                         $stringoptions = new stdClass;
                         $stringoptions->context = $coursecontext;
-                        echo json_encode(array('instancename' => format_string($module->name, true,  $stringoptions)));
+                        echo json_encode(array('instancename' => html_entity_decode(format_string($module->name, true,  $stringoptions))));
                         break;
                 }
                 break;
index 5f91966..721d968 100644 (file)
@@ -175,13 +175,11 @@ if (!empty($moveto) and $data = data_submitted() and confirm_sesskey()) {   // S
 if (!empty($blocklist) and confirm_sesskey()) {
     $blockname = $DB->get_field('block', 'name', array('id' => $blocklist));
     $courses = array();
-    $courses = $DB->get_records_sql("
-            SELECT * FROM {course} WHERE id IN (
-                SELECT DISTINCT ctx.instanceid
-                FROM {context} ctx
-                JOIN {block_instances} bi ON bi.parentcontextid = ctx.id
-                WHERE ctx.contextlevel = " . CONTEXT_COURSE . " AND bi.blockname = ?)",
-            array($blockname));
+    list($select, $join) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
+    $sql = "SELECT c.* $select FROM {course} c
+            $join JOIN {block_instances} bi ON bi.parentcontextid = ctx.id
+            WHERE bi.blockname = ?";
+    $courses = $DB->get_records_sql($sql, array($blockname));
     $totalcount = count($courses);
     // Keep only chunk of array which you want to display
     if ($totalcount > $perpage) {
@@ -193,26 +191,24 @@ if (!empty($blocklist) and confirm_sesskey()) {
     }
 } elseif (!empty($modulelist) and confirm_sesskey()) { // get list of courses containing modules
     $modulename = $modulelist;
-    $sql =  "SELECT DISTINCT c.id FROM {".$modulelist."} module, {course} c"
-        ." WHERE module.course=c.id";
-
-    $courseids = $DB->get_records_sql($sql);
+    list($select, $join) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
+    $sql = "SELECT c.* $select FROM {course} c $join
+            WHERE c.id IN (SELECT DISTINCT cc.id FROM {".$modulelist."} module, {course} cc
+                           WHERE module.course = cc.id)";
+    $courselist = $DB->get_records_sql($sql);
     $courses = array();
-    if (!empty($courseids)) {
+    if (!empty($courselist)) {
         $firstcourse = $page*$perpage;
         $lastcourse = $page*$perpage + $perpage -1;
         $i = 0;
-        foreach ($courseids as $courseid) {
+        foreach ($courselist as $course) {
             if ($i >= $firstcourse && $i <= $lastcourse) {
-                $courses[$courseid->id] = $DB->get_record('course', array('id'=> $courseid->id));
+                $courses[$course->id] = $course;
             }
             $i++;
         }
-        $totalcount = count($courseids);
-    }
-    else {
-        $totalcount = 0;
     }
+    $totalcount = count($courselist);
 } else if (!empty($searchterm)) {
     // Donot do search for empty search request.
     $courses = get_courses_search($searchterms, "fullname ASC", $page, $perpage, $totalcount);
@@ -294,6 +290,7 @@ if ($courses) {
 
         foreach ($courses as $course) {
 
+            context_helper::preload_from_record($course);
             $coursecontext = context_course::instance($course->id);
 
             $linkcss = $course->visible ? "" : " class=\"dimmed\" ";
@@ -313,7 +310,7 @@ if ($courses) {
 
             echo "<tr>\n";
             echo "<td><a $linkcss href=\"view.php?id=$course->id\">"
-                . highlight($search, format_string($course->fullname)) . "</a></td>\n";
+                . highlight($search, $coursecontext->get_context_name(false)) . "</a></td>\n";
             echo "<td>".$displaylist[$course->category]."</td>\n";
             echo "<td>\n";
 
index 719762e..2b756b6 100644 (file)
@@ -35,7 +35,7 @@ require_once($CFG->dirroot.'/course/lib.php');
 
 $id         = required_param('id', PARAM_INT);
 $switchrole = optional_param('switchrole',-1, PARAM_INT);
-$returnurl  = optional_param('returnurl', false, PARAM_URL);
+$returnurl  = optional_param('returnurl', false, PARAM_LOCALURL);
 
 $PAGE->set_url('/course/switchrole.php', array('id'=>$id));
 
@@ -84,4 +84,4 @@ if ($returnurl === false) {
     $returnurl = new moodle_url('/course/view.php', array('id' => $course->id));
 }
 
-redirect($returnurl);
\ No newline at end of file
+redirect($returnurl);
index 5c8c896..1b37f40 100644 (file)
@@ -37,7 +37,7 @@ YUI.add('moodle-course-toolboxes', function(Y) {
         CONDITIONALHIDDEN : 'conditionalhidden',
         AVAILABILITYINFODIV : 'div.availabilityinfo',
         SHOWCLASS : 'editing_show',
-        ACCESSHIDECLASS : 'accesshide'
+        HIDECLASS : 'hide'
     };
 
     /**
@@ -99,7 +99,7 @@ YUI.add('moodle-course-toolboxes', function(Y) {
             var availabilityinfo = element.one(CSS.AVAILABILITYINFODIV);
 
             if (availabilityinfo) {
-                availabilityinfo.toggleClass(CSS.ACCESSHIDECLASS);
+                availabilityinfo.toggleClass(CSS.HIDECLASS);
             }
             return value;
         },
index 70ce970..d6a1887 100644 (file)
@@ -3,102 +3,7 @@ ENROLMENT MODULES
 
 (Yes, that's the correct English spelling  ;-) )
 
-enrol.class.php contains a simple 'factory' method that
-will instantiate your class when called. For an example
-of a complete class, take a look at the 'manual' class.
-
-Each plugin is in a subfolder here.
-
-Except for the configuration methods, most methods
-defined in the API are optional -- callers will use
-method_exists() to determine whether your plugin offers
-the functionality they are after.
-
-
-Mandatory methods
-=================
-
-  config_form()
-  process_config()
-
-
-Login-time methods
-==================
-
-  Before Moodle 1.7
-  -----------------
-
-      get_student_courses()
-      get_teacher_courses()
-
-  You probably will want to offer at least get_student_courses().
-
-  These methods are triggered when a user logs in successfully,
-  and they are expected to populate $USER->student and
-  $USER->teacher arrays and maintain (add/delete) entries from
-  user_students and user_teachers.
-
-  These methods are relevant for most plugins, and are the main
-  interest for plugins that work with a read-only backend such
-  as LDAP or a database.
-
-  Note that with the multi-enrol infrastructure two things have
-  changed. We now have an 'enrol' field in those tables, and
-  each plugin must maintain only its own enrolment records.
-  Conversely, the $USER->student and ->teacher arrays have the
-  enrolment type as value, like
-
-     $USER->student = array ( $courseid => $plugintype );
-
-
-  Moodle 1.7 and later
-  --------------------
-
-      setup_enrolments()
-
-  With the advent of roles, there could well not be students and
-  teachers any more, so enrolment plugins have to be more flexible
-  about how they map outside data to the internal roles.
-
-  This one method should do everything, calling functions from
-  lib/accesslib.php as necessary to set up relationships.
-
-
-Interactive enrolment methods
-=============================
-
-  print_entry()
-  check_entry()
-  check_group_entry()
-  get_access_icons()
-
-These methods are for enrolment plugins that allow for user
-driven enrolment. These methods are relevant for plugins
-that implement payment gateways (credit card, paypal),
-as well as "magic password" schemes.
-
-Only one interactive enrolment method can be active for
-a given course. The site default can be set from
-Admin->Enrolment, and then individual courses can be
-set to specific interactive enrolment methods.
-
-
-Cron
-====
-
-If your class offers a cron() method, it will be invoked by
-the standard Moodle cron every time it is called. Note that if the
-tasks are not lightweight you must control how frequently they
-execute, perhaps offering a config option.
-
-For really heavy cron processing, an alternative is to have
-a separate script to be called separately. Currently the LDAP
-and DB plugins have external scripts.
-
-
-Guilty Parties
---------------
-
-Martin Dougiamas and Shane Elliott, Moodle.com
-Martin Langhoff and Patrick Li, Catalyst IT
+All enrolment modules must extend base class enrol_plugin
+which is defined in lib/enrollib.php. You can find documentation
+of each method in the base class.
 
index ad71ff7..c369c8f 100644 (file)
@@ -30,5 +30,9 @@ function xmldb_enrol_authorize_upgrade($oldversion) {
     // Put any upgrade step following this
 
 
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this
+
+
     return true;
 }
index 7db80b8..0702c9e 100644 (file)
@@ -32,7 +32,7 @@
 
 define('CLI_SCRIPT', true);
 
-require(dirname(dirname(dirname(dirname(__FILE__)))).'/config.php');
+require(__DIR__.'/../../../config.php');
 require_once("$CFG->dirroot/enrol/category/locallib.php");
 require_once("$CFG->libdir/clilib.php");
 
@@ -49,7 +49,7 @@ if ($options['help']) {
         "Execute course category enrolment sync.
 
 Options:
--v, --verbose         Print verbose progess information
+-v, --verbose         Print verbose progress information
 -h, --help            Print out this help
 
 Example:
@@ -64,5 +64,12 @@ if (!enrol_is_enabled('category')) {
     cli_error('enrol_category plugin is disabled, synchronisation stopped', 2);
 }
 
-$verbose = !empty($options['verbose']);
-return enrol_category_sync_full($verbose);
+if (empty($options['verbose'])) {
+    $trace = new null_progress_trace();
+} else {
+    $trace = new text_progress_trace();
+}
+
+$result = enrol_category_sync_full($trace);
+
+exit($result);
index 4fed790..b806eae 100644 (file)
@@ -70,7 +70,8 @@ class enrol_category_plugin extends enrol_plugin {
         }
 
         require_once("$CFG->dirroot/enrol/category/locallib.php");
-        enrol_category_sync_full();
+        $trace = new null_progress_trace();
+        enrol_category_sync_full($trace);
     }
 
     /**
index 9e4ab0c..69ec05e 100644 (file)
@@ -252,14 +252,15 @@ function enrol_category_sync_course($course) {
  * - reorder categories
  * - disable enrol_category and enable it again
  *
- * @param bool $verbose
+ * @param progress_trace $trace
  * @return int exit code - 0 is ok, 1 means error, 2 if plugin disabled
  */
-function enrol_category_sync_full($verbose = false) {
+function enrol_category_sync_full(progress_trace $trace) {
     global $DB;
 
 
     if (!enrol_is_enabled('category')) {
+        $trace->finished();
         return 2;
     }
 
@@ -273,23 +274,20 @@ function enrol_category_sync_full($verbose = false) {
     // Any interesting roles worth synchronising?
     if (!$roles = get_roles_with_capability('enrol/category:synchronised', CAP_ALLOW, $syscontext)) {
         // yay, nothing to do, so let's remove all leftovers
-        if ($verbose) {
-            mtrace("No roles with 'enrol/category:synchronised' capability found.");
-        }
+        $trace->output("No roles with 'enrol/category:synchronised' capability found.");
         if ($instances = $DB->get_records('enrol', array('enrol'=>'category'))) {
+            $trace->output("Deleting all category enrol instances...");
             foreach ($instances as $instance) {
-                if ($verbose) {
-                    mtrace("  deleting category enrol instance from course {$instance->courseid}");
-                }
+                $trace->output("deleting category enrol instance from course {$instance->courseid}", 1);
                 $plugin->delete_instance($instance);
             }
+            $trace->output("...all instances deleted.");
         }
+        $trace->finished();
         return 0;
     }
     $rolenames = role_fix_names($roles, null, ROLENAME_SHORT, true);
-    if ($verbose) {
-        mtrace('Synchronising category enrolments for roles: '.implode(', ', $rolenames).'...');
-    }
+    $trace->output('Synchronising category enrolments for roles: '.implode(', ', $rolenames).'...');
 
     list($roleids, $params) = $DB->get_in_or_equal(array_keys($roles), SQL_PARAMS_NAMED, 'r');
     $params['courselevel'] = CONTEXT_COURSE;
@@ -357,9 +355,7 @@ function enrol_category_sync_full($verbose = false) {
         unset($instance->userid);
         unset($instance->estart);
         $plugin->enrol_user($instance, $userid, null, $estart);
-        if ($verbose) {
-            mtrace("  enrolling: user $userid ==> course $instance->courseid");
-        }
+        $trace->output("enrolling: user $userid ==> course $instance->courseid", 1);
     }
     $rs->close();
 
@@ -378,15 +374,12 @@ function enrol_category_sync_full($verbose = false) {
         $userid = $instance->userid;
         unset($instance->userid);
         $plugin->unenrol_user($instance, $userid);
-        if ($verbose) {
-            mtrace("  unenrolling: user $userid ==> course $instance->courseid");
-        }
+        $trace->output("unenrolling: user $userid ==> course $instance->courseid", 1);
     }
     $rs->close();
 
-    if ($verbose) {
-        mtrace('...user enrolment synchronisation finished.');
-    }
+    $trace->output('...user enrolment synchronisation finished.');
+    $trace->finished();
 
     return 0;
 }
index 3649764..ca8d4cd 100644 (file)
@@ -276,6 +276,8 @@ class enrol_category_testcase extends advanced_testcase {
 
         $this->resetAfterTest();
 
+        $trace = new null_progress_trace();
+
         // Setup a few courses and categories.
 
         $studentrole = $DB->get_record('role', array('shortname'=>'student'));
@@ -309,13 +311,13 @@ class enrol_category_testcase extends advanced_testcase {
         role_assign($managerrole->id, $user3->id, context_course::instance($course2->id));
         $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
 
-        $result = enrol_category_sync_full();
+        $result = enrol_category_sync_full($trace);
         $this->assertSame(0, $result);
 
         $this->disable_plugin();
         role_assign($studentrole->id, $user1->id, context_coursecat::instance($cat2->id));
         $this->enable_plugin();
-        $result = enrol_category_sync_full();
+        $result = enrol_category_sync_full($trace);
         $this->assertSame(0, $result);
         $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
         $this->assertTrue(is_enrolled(context_course::instance($course2->id), $user1->id));
@@ -329,7 +331,7 @@ class enrol_category_testcase extends advanced_testcase {
         role_assign($teacherrole->id, $user3->id, context_coursecat::instance($cat2->id));
         role_assign($managerrole->id, $user3->id, context_course::instance($course3->id));
         $this->enable_plugin();
-        $result = enrol_category_sync_full();
+        $result = enrol_category_sync_full($trace);
         $this->assertSame(0, $result);
         $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
         $this->assertTrue(is_enrolled(context_course::instance($course1->id), $user2->id));
@@ -348,7 +350,7 @@ class enrol_category_testcase extends advanced_testcase {
         role_unassign_all(array('roleid'=>$managerrole->id));
         role_unassign_all(array('roleid'=>$teacherrole->id));
 
-        $result = enrol_category_sync_full();
+        $result = enrol_category_sync_full($trace);
         $this->assertSame(2, $result);
         $this->assertEquals(0, $DB->count_records('role_assignments', array()));
         $this->assertNotEmpty($DB->count_records('user_enrolments', array()));
@@ -356,7 +358,7 @@ class enrol_category_testcase extends advanced_testcase {
         $this->disable_role_sync($teacherrole->id);
 
         $this->enable_plugin();
-        $result = enrol_category_sync_full();
+        $result = enrol_category_sync_full($trace);
         $this->assertSame(0, $result);
         $this->assertEquals(0, $DB->count_records('role_assignments', array()));
         $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
index 6eec6ce..42cc37e 100644 (file)
@@ -90,7 +90,9 @@ switch ($action) {
         }
         $enrol = enrol_get_plugin('cohort');
         $enrol->add_instance($manager->get_course(), array('customint1' => $cohortid, 'roleid' => $roleid));
-        enrol_cohort_sync($manager->get_course()->id);
+        $trace = new null_progress_trace();
+        enrol_cohort_sync($trace, $manager->get_course()->id);
+        $trace->finished();
         break;
     case 'enrolcohortusers':
         //TODO: this should be moved to enrol_manual, see MDL-35618.
index 4f1cd3b..032c34a 100644 (file)
@@ -30,8 +30,8 @@
 
 define('CLI_SCRIPT', true);
 
-require(dirname(dirname(dirname(dirname(__FILE__)))).'/config.php');
-require_once($CFG->libdir.'/clilib.php');
+require(__DIR__.'/../../../config.php');
+require_once("$CFG->libdir/clilib.php");
 require_once("$CFG->dirroot/enrol/cohort/locallib.php");
 
 // Now get cli options.
@@ -51,15 +51,20 @@ Options:
 -h, --help            Print out this help
 
 Example:
-\$sudo -u www-data /usr/bin/php enrol/cohort/cli/sync.php
+\$ sudo -u www-data /usr/bin/php enrol/cohort/cli/sync.php
 ";
 
     echo $help;
     die;
 }
 
-$verbose = !empty($options['verbose']);
+if (empty($options['verbose'])) {
+    $trace = new null_progress_trace();
+} else {
+    $trace = new text_progress_trace();
+}
 
-$result = enrol_cohort_sync(null, $verbose);
+$result = enrol_cohort_sync($trace, null);
+$trace->finished();
 
-exit($result);
\ No newline at end of file
+exit($result);
index ee97210..050bdff 100644 (file)
@@ -92,7 +92,9 @@ if ($mform->is_cancelled()) {
     }  else {
         $enrol->add_instance($course, array('name'=>$data->name, 'status'=>$data->status, 'customint1'=>$data->customint1, 'roleid'=>$data->roleid, 'customint2'=>$data->customint2));
     }
-    enrol_cohort_sync($course->id);
+    $trace = new null_progress_trace();
+    enrol_cohort_sync($trace, $course->id);
+    $trace->finished();
     redirect($returnurl);
 }
 
index 56dc5c9..a2370d4 100644 (file)
@@ -132,7 +132,9 @@ class enrol_cohort_plugin extends enrol_plugin {
         global $CFG;
 
         require_once("$CFG->dirroot/enrol/cohort/locallib.php");
-        enrol_cohort_sync();
+        $trace = new null_progress_trace();
+        enrol_cohort_sync($trace);
+        $trace->finished();
     }
 
     /**
@@ -160,7 +162,9 @@ class enrol_cohort_plugin extends enrol_plugin {
         parent::update_status($instance, $newstatus);
 
         require_once("$CFG->dirroot/enrol/cohort/locallib.php");
-        enrol_cohort_sync($instance->courseid);
+        $trace = new null_progress_trace();
+        enrol_cohort_sync($trace, $instance->courseid);
+        $trace->finished();
     }
 
     /**
@@ -279,7 +283,9 @@ class enrol_cohort_plugin extends enrol_plugin {
             $step->set_mapping('enrol', $oldid, $instanceid);
 
             require_once("$CFG->dirroot/enrol/cohort/locallib.php");
-            enrol_cohort_sync($course->id, false);
+            $trace = new null_progress_trace();
+            enrol_cohort_sync($trace, $course->id);
+            $trace->finished();
 
         } else if ($this->get_config('unenrolaction') == ENROL_EXT_REMOVED_SUSPENDNOROLES) {
             $data->customint1 = 0;
@@ -294,7 +300,9 @@ class enrol_cohort_plugin extends enrol_plugin {
             $step->set_mapping('enrol', $oldid, $instanceid);
 
             require_once("$CFG->dirroot/enrol/cohort/locallib.php");
-            enrol_cohort_sync($course->id, false);
+            $trace = new null_progress_trace();
+            enrol_cohort_sync($trace, $course->id);
+            $trace->finished();
 
         } else {
             $step->set_mapping('enrol', $oldid, 0);
index 83dd982..4027af3 100644 (file)
@@ -151,19 +151,17 @@ class enrol_cohort_handler {
 
 /**
  * Sync all cohort course links.
+ * @param progress_trace $trace
  * @param int $courseid one course, empty mean all
- * @param bool $verbose verbose CLI output
  * @return int 0 means ok, 1 means error, 2 means plugin disabled
  */
-function enrol_cohort_sync($courseid = NULL, $verbose = false) {
+function enrol_cohort_sync(progress_trace $trace, $courseid = NULL) {
     global $CFG, $DB;
     require_once("$CFG->dirroot/group/lib.php");
 
     // Purge all roles if cohort sync disabled, those can be recreated later here by cron or CLI.
     if (!enrol_is_enabled('cohort')) {
-        if ($verbose) {
-            mtrace('Cohort sync plugin is disabled, unassigning all plugin roles and stopping.');
-        }
+        $trace->output('Cohort sync plugin is disabled, unassigning all plugin roles and stopping.');
         role_unassign_all(array('component'=>'enrol_cohort'));
         return 2;
     }
@@ -172,9 +170,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
     @set_time_limit(0);
     raise_memory_limit(MEMORY_HUGE);
 
-    if ($verbose) {
-        mtrace('Starting user enrolment synchronisation...');
-    }
+    $trace->output('Starting user enrolment synchronisation...');
 
     $allroles = get_all_roles();
     $instances = array(); //cache
@@ -201,14 +197,10 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
         $instance = $instances[$ue->enrolid];
         if ($ue->status == ENROL_USER_SUSPENDED) {
             $plugin->update_user_enrol($instance, $ue->userid, ENROL_USER_ACTIVE);
-            if ($verbose) {
-                mtrace("  unsuspending: $ue->userid ==> $instance->courseid via cohort $instance->customint1");
-            }
+            $trace->output("unsuspending: $ue->userid ==> $instance->courseid via cohort $instance->customint1", 1);
         } else {
             $plugin->enrol_user($instance, $ue->userid);
-            if ($verbose) {
-                mtrace("  enrolling: $ue->userid ==> $instance->courseid via cohort $instance->customint1");
-            }
+            $trace->output("enrolling: $ue->userid ==> $instance->courseid via cohort $instance->customint1", 1);
         }
     }
     $rs->close();
@@ -229,9 +221,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
         if ($unenrolaction == ENROL_EXT_REMOVED_UNENROL) {
             // Remove enrolment together with group membership, grades, preferences, etc.
             $plugin->unenrol_user($instance, $ue->userid);
-            if ($verbose) {
-                mtrace("  unenrolling: $ue->userid ==> $instance->courseid via cohort $instance->customint1");
-            }
+            $trace->output("unenrolling: $ue->userid ==> $instance->courseid via cohort $instance->customint1", 1);
 
         } else { // ENROL_EXT_REMOVED_SUSPENDNOROLES
             // Just disable and ignore any changes.
@@ -239,9 +229,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
                 $plugin->update_user_enrol($instance, $ue->userid, ENROL_USER_SUSPENDED);
                 $context = context_course::instance($instance->courseid);
                 role_unassign_all(array('userid'=>$ue->userid, 'contextid'=>$context->id, 'component'=>'enrol_cohort', 'itemid'=>$instance->id));
-                if ($verbose) {
-                    mtrace("  suspending and unsassigning all roles: $ue->userid ==> $instance->courseid");
-                }
+                $trace->output("suspending and unsassigning all roles: $ue->userid ==> $instance->courseid", 1);
             }
         }
     }
@@ -267,9 +255,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
     $rs = $DB->get_recordset_sql($sql, $params);
     foreach($rs as $ra) {
         role_assign($ra->roleid, $ra->userid, $ra->contextid, 'enrol_cohort', $ra->itemid);
-        if ($verbose) {
-            mtrace("  assigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname);
-        }
+        $trace->output("assigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname, 1);
     }
     $rs->close();
 
@@ -291,9 +277,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
     $rs = $DB->get_recordset_sql($sql, $params);
     foreach($rs as $ra) {
         role_unassign($ra->roleid, $ra->userid, $ra->contextid, 'enrol_cohort', $ra->itemid);
-        if ($verbose) {
-            mtrace("  unassigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname);
-        }
+        $trace->output("unassigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname, 1);
     }
     $rs->close();
 
@@ -314,9 +298,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
     $rs = $DB->get_recordset_sql($sql, $params);
     foreach($rs as $gm) {
         groups_remove_member($gm->groupid, $gm->userid);
-        if ($verbose) {
-            mtrace("  removing user from group: $gm->userid ==> $gm->courseid - $gm->groupname");
-        }
+        $trace->output("removing user from group: $gm->userid ==> $gm->courseid - $gm->groupname", 1);
     }
     $rs->close();
 
@@ -333,16 +315,12 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
     $rs = $DB->get_recordset_sql($sql, $params);
     foreach($rs as $ue) {
         groups_add_member($ue->groupid, $ue->userid, 'enrol_cohort', $ue->enrolid);
-        if ($verbose) {
-            mtrace("  adding user to group: $ue->userid ==> $ue->courseid - $ue->groupname");
-        }
+        $trace->output("adding user to group: $ue->userid ==> $ue->courseid - $ue->groupname", 1);
     }
     $rs->close();
 
 
-    if ($verbose) {
-        mtrace('...user enrolment synchronisation finished.');
-    }
+    $trace->output('...user enrolment synchronisation finished.');
 
     return 0;
 }
index 75fc773..b21afc3 100644 (file)
@@ -260,6 +260,8 @@ class enrol_cohort_testcase extends advanced_testcase {
         global $DB;
         $this->resetAfterTest();
 
+        $trace = new null_progress_trace();
+
         // Setup a few courses and categories.
 
         $cohortplugin = enrol_get_plugin('cohort');
@@ -319,19 +321,19 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         // Test sync of one course only.
 
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(2, $DB->count_records('role_assignments', array()));
         $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
 
 
         $this->enable_plugin();
-        enrol_cohort_sync($course2->id, false);
+        enrol_cohort_sync($trace, $course2->id);
         $this->assertEquals(3, $DB->count_records('role_assignments', array()));
         $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort3->id)); // Use low level DB api to prevent events!
         $DB->delete_records('cohort', array('id'=>$cohort3->id)); // Use low level DB api to prevent events!
 
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
         $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
         $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user2->id)));
@@ -345,14 +347,14 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort2->id, 'userid'=>$user3->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(6, $DB->count_records('role_assignments', array()));
         $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id, 'userid'=>$user1->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
         $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance2->id, 'userid'=>$user3->id)));
         $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
@@ -363,12 +365,12 @@ class enrol_cohort_testcase extends advanced_testcase {
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id)); // Use low level DB api to prevent events!
         $DB->delete_records('cohort', array('id'=>$cohort1->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(3, $DB->count_records('role_assignments', array()));
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(3, $DB->count_records('role_assignments', array()));
 
@@ -400,7 +402,7 @@ class enrol_cohort_testcase extends advanced_testcase {
         cohort_add_member($cohort1->id, $user4->id);
         cohort_add_member($cohort2->id, $user4->id);
 
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
 
         $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(7, $DB->count_records('role_assignments', array()));
@@ -414,7 +416,7 @@ class enrol_cohort_testcase extends advanced_testcase {
         $cohortinstance1->customint2 = $group2->id;
         $DB->update_record('enrol', $cohortinstance1);
 
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertFalse(groups_is_member($group1->id, $user1->id));
         $this->assertTrue(groups_is_member($group2->id, $user1->id));
         $this->assertTrue($DB->record_exists('groups_members', array('groupid'=>$group2->id, 'userid'=>$user1->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
@@ -437,6 +439,8 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         $this->resetAfterTest();
 
+        $trace = new null_progress_trace();
+
         // Setup a few courses and categories.
 
         $cohortplugin = enrol_get_plugin('cohort');
@@ -496,13 +500,13 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         // Test sync of one course only.
 
-        enrol_cohort_sync(null, false);
+        enrol_cohort_sync($trace, null);
         $this->assertEquals(2, $DB->count_records('role_assignments', array()));
         $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
 
 
         $this->enable_plugin();
-        enrol_cohort_sync(null, false);
+        enrol_cohort_sync($trace, null);
         $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
         $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
         $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user2->id)));
@@ -516,14 +520,14 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort2->id, 'userid'=>$user3->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(6, $DB->count_records('role_assignments', array()));
         $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id, 'userid'=>$user1->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
         $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance2->id, 'userid'=>$user3->id)));
         $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
@@ -534,12 +538,12 @@ class enrol_cohort_testcase extends advanced_testcase {
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id)); // Use low level DB api to prevent events!
         $DB->delete_records('cohort', array('id'=>$cohort1->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(3, $DB->count_records('role_assignments', array()));
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(3, $DB->count_records('role_assignments', array()));
 
@@ -573,7 +577,7 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         $this->enable_plugin();
 
-        enrol_cohort_sync(null, false);
+        enrol_cohort_sync($trace, null);
 
         $this->assertEquals(8, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(8, $DB->count_records('role_assignments', array()));
@@ -593,7 +597,7 @@ class enrol_cohort_testcase extends advanced_testcase {
         $cohortinstance3->customint2 = $group3->id;
         $DB->update_record('enrol', $cohortinstance3);
 
-        enrol_cohort_sync(null, false);
+        enrol_cohort_sync($trace, null);
         $this->assertFalse(groups_is_member($group1->id, $user1->id));
         $this->assertTrue(groups_is_member($group2->id, $user1->id));
         $this->assertTrue($DB->record_exists('groups_members', array('groupid'=>$group2->id, 'userid'=>$user1->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
index 6c22963..52727e6 100644 (file)
@@ -20,6 +20,7 @@ YUI.add('moodle-enrol_cohort-quickenrolment', function(Y) {
         AJAXURL = 'ajaxurl',
         MANUALENROLMENT = 'manualEnrolment',
         CSS = {
+            CLOSEBTN : 'close-button',
             COHORT : 'qce-cohort',
             COHORTS : 'qce-cohorts',
             COHORTBUTTON : 'qce-cohort-button',
@@ -52,13 +53,16 @@ YUI.add('moodle-enrol_cohort-quickenrolment', function(Y) {
             this.publish('cohortsloaded');
             this.publish('defaultcohortroleloaded', {fireOnce:true});
 
+            var finishbutton = Y.Node.create('<div class="'+CSS.CLOSEBTN+'"></div>')
+                                   .append(Y.Node.create('<input type="button" value="'+M.str.enrol.finishenrollingusers+'" />'));
             var base = Y.Node.create('<div class="'+CSS.PANELCONTENT+'"></div>')
                 .append(Y.Node.create('<div class="'+CSS.PANELROLES+'"></div>'))
                 .append(Y.Node.create('<div class="'+CSS.PANELCOHORTS+'"></div>'))
                 .append(Y.Node.create('<div class="'+CSS.FOOTER+'"></div>')
-                    .append(Y.Node.create('<div class="'+CSS.SEARCH+'"><label>'+M.str.enrol_cohort.cohortsearch+':</label></div>')
+                    .append(Y.Node.create('<div class="'+CSS.SEARCH+'"><label for="enrolcohortsearch">'+M.str.enrol_cohort.cohortsearch+':</label></div>')
                         .append(Y.Node.create('<input type="text" id="enrolcohortsearch" value="" />'))
                     )
+                    .append(finishbutton)
                 )
                 .append(Y.Node.create('<div class="'+CSS.LIGHTBOX+' '+CSS.HIDDEN+'"></div>')
                     .append(Y.Node.create('<img alt="loading" class="'+CSS.LOADINGICON+'" />')
@@ -99,6 +103,7 @@ YUI.add('moodle-enrol_cohort-quickenrolment', function(Y) {
             this.on('defaultcohortroleloaded', this.updateContent, this, panel);
             Y.on('key', this.hide, document.body, 'down:27', this);
             close.on('click', this.hide, this);
+            finishbutton.on('click', this.hide, this);
 
             Y.all('.enrol_cohort_plugin input').each(function(node){
                 if (node.getAttribute('type', 'submit')) {
@@ -117,6 +122,11 @@ YUI.add('moodle-enrol_cohort-quickenrolment', function(Y) {
             this.getCohorts(e, false);
             this.getAssignableRoles();
             this.fire('show');
+
+            var rolesselect = Y.one('#id_enrol_cohort_assignable_roles');
+            if (rolesselect) {
+                rolesselect.focus();
+            }
         },
         updateContent : function(e, panel) {
             var content, i, roles, cohorts, count=0, supportmanual = this.get(MANUALENROLMENT), defaultrole;
@@ -154,13 +164,14 @@ YUI.add('moodle-enrol_cohort-quickenrolment', function(Y) {
                     break;
                 case 'assignablerolesloaded':
                     roles = this.get(ASSIGNABLEROLES);
-                    content = Y.Node.create('<select></select>');
+                    content = Y.Node.create('<select id="id_enrol_cohort_assignable_roles"></select>');
                     for (i in roles) {
                         content.append(Y.Node.create('<option value="'+i+'">'+roles[i]+'</option>'));
                     }
-                    panel.get('contentBox').one('.'+CSS.PANELROLES).setContent(Y.Node.create('<div><label>'+M.str.role.assignroles+':</label></div>').append(content));
+                    panel.get('contentBox').one('.'+CSS.PANELROLES).setContent(Y.Node.create('<div><label for="id_enrol_cohort_assignable_roles">'+M.str.role.assignroles+':</label></div>').append(content));
 
                     this.getDefaultCohortRole();
+                    Y.one('#id_enrol_cohort_assignable_roles').focus();
                     break;
                 case 'defaultcohortroleloaded':
                     defaultrole = this.get(DEFAULTCOHORTROLE);
@@ -280,7 +291,8 @@ YUI.add('moodle-enrol_cohort-quickenrolment', function(Y) {
                                 new M.core.ajaxException(result);
                             } else {
                                 if (result.response && result.response.message) {
-                                    new M.core.alert(result.response);
+                                    var alertpanel = new M.core.alert(result.response);
+                                    Y.Node.one('#id_yuialertconfirm-' + alertpanel.COUNT).focus();
                                 }
                                 var enrolled = Y.Node.create('<div class="'+CSS.COHORTBUTTON+' alreadyenrolled">'+M.str.enrol.synced+'</div>');
                                 node.one('.'+CSS.COHORT+' #cohortid_'+cohort.get(COHORTID)).replace(enrolled);
index 420e3d7..890a0f4 100644 (file)
@@ -33,8 +33,8 @@
 
 define('CLI_SCRIPT', true);
 
-require(dirname(dirname(dirname(dirname(__FILE__)))).'/config.php');
-require_once($CFG->libdir.'/clilib.php');
+require(__DIR__.'/../../../config.php');
+require_once("$CFG->libdir/clilib.php");
 
 // Now get cli options.
 list($options, $unrecognized) = cli_get_params(array('verbose'=>false, 'help'=>false), array('v'=>'verbose', 'h'=>'help'));
@@ -50,15 +50,15 @@ if ($options['help']) {
 The enrol_database plugin must be enabled and properly configured.
 
 Options:
--v, --verbose         Print verbose progess information
+-v, --verbose         Print verbose progress information
 -h, --help            Print out this help
 
 Example:
-\$sudo -u www-data /usr/bin/php enrol/database/cli/sync.php
+\$ sudo -u www-data /usr/bin/php enrol/database/cli/sync.php
 
 Sample cron entry:
 # 5 minutes past 4am
-5 4 * * * \$sudo -u www-data /usr/bin/php /var/www/moodle/enrol/database/cli/sync.php
+5 4 * * * sudo -u www-data /usr/bin/php /var/www/moodle/enrol/database/cli/sync.php
 ";
 
     echo $help;
@@ -66,15 +66,20 @@ Sample cron entry:
 }
 
 if (!enrol_is_enabled('database')) {
-    echo('enrol_database plugin is disabled, sync is disabled'."\n");
-    exit(1);
+    cli_error('enrol_database plugin is disabled, synchronisation stopped', 2);
 }
 
-$verbose = !empty($options['verbose']);
+if (empty($options['verbose'])) {
+    $trace = new null_progress_trace();
+} else {
+    $trace = new text_progress_trace();
+}
+
+/** @var enrol_database_plugin $enrol  */
 $enrol = enrol_get_plugin('database');
 $result = 0;
 
-$result = $result | $enrol->sync_courses($verbose);
-$result = $result | $enrol->sync_enrolments($verbose);
+$result = $result | $enrol->sync_courses($trace);
+$result = $result | $enrol->sync_enrolments($trace);
 
-exit($result);
\ No newline at end of file
+exit($result);
index 66d9592..623ae22 100644 (file)
@@ -33,5 +33,9 @@ function xmldb_enrol_database_upgrade($oldversion) {
     // Put any upgrade step following this.
 
 
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this
+
+
     return true;
 }
index 398dfee..214c70a 100644 (file)
@@ -284,27 +284,25 @@ class enrol_database_plugin extends enrol_plugin {
     /**
      * Forces synchronisation of all enrolments with external database.
      *
-     * @param bool $verbose
+     * @param progress_trace $trace
      * @param null|int $onecourse limit sync to one course only (used primarily in restore)
      * @return int 0 means success, 1 db connect failure, 2 db read failure
      */
-    public function sync_enrolments($verbose = false, $onecourse = null) {
+    public function sync_enrolments(progress_trace $trace, $onecourse = null) {
         global $CFG, $DB;
 
         // We do not create courses here intentionally because it requires full sync and is slow.
         if (!$this->get_config('dbtype') or !$this->get_config('dbhost') or !$this->get_config('remoteenroltable') or !$this->get_config('remotecoursefield') or !$this->get_config('remoteuserfield')) {
-            if ($verbose) {
-                mtrace('User enrolment synchronisation skipped.');
-            }
+            $trace->output('User enrolment synchronisation skipped.');
+            $trace->finished();
             return 0;
         }
 
-        if ($verbose) {
-            mtrace('Starting user enrolment synchronisation...');
-        }
+        $trace->output('Starting user enrolment synchronisation...');
 
         if (!$extdb = $this->db_init()) {
-            mtrace('Error while communicating with external enrolment database');
+            $trace->output('Error while communicating with external enrolment database');
+            $trace->finished();
             return 1;
         }
 
@@ -380,13 +378,13 @@ class enrol_database_plugin extends enrol_plugin {
                 }
                 $rs->Close();
             } else {
-                mtrace('Error reading data from the external enrolment table');
+                $trace->output('Error reading data from the external enrolment table');
                 $extdb->Close();
                 return 2;
             }
             $preventfullunenrol = empty($externalcourses);
             if ($preventfullunenrol and $unenrolaction == ENROL_EXT_REMOVED_UNENROL) {
-                mtrace('  Preventing unenrolment of all current users, because it might result in major data loss, there has to be at least one record in external enrol table, sorry.');
+                $trace->output('Preventing unenrolment of all current users, because it might result in major data loss, there has to be at least one record in external enrol table, sorry.', 1);
             }
 
             // First find all existing courses with enrol instance.
@@ -431,9 +429,9 @@ class enrol_database_plugin extends enrol_plugin {
             $rs->close();
 
             // Print list of missing courses.
-            if ($verbose and $externalcourses) {
+            if ($externalcourses) {
                 $list = implode(', ', array_keys($externalcourses));
-                mtrace("  error: following courses do not exist - $list");
+                $trace->output("error: following courses do not exist - $list", 1);
                 unset($list);
             }
 
@@ -491,18 +489,14 @@ class enrol_database_plugin extends enrol_plugin {
                     while ($fields = $rs->FetchRow()) {
                         $fields = array_change_key_case($fields, CASE_LOWER);
                         if (empty($fields[$userfield_l])) {
-                            if ($verbose) {
-                                mtrace("  error: skipping user without mandatory $localuserfield in course '$course->mapping'");
-                            }
+                            $trace->output("error: skipping user without mandatory $localuserfield in course '$course->mapping'", 1);
                             continue;
                         }
                         $mapping = $fields[$userfield_l];
                         if (!isset($user_mapping[$mapping])) {
                             $usersearch[$localuserfield] = $mapping;
                             if (!$user = $DB->get_record('user', $usersearch, 'id', IGNORE_MULTIPLE)) {
-                                if ($verbose) {
-                                    mtrace("  error: skipping unknown user $localuserfield '$mapping' in course '$course->mapping'");
-                                }
+                                $trace->output("error: skipping unknown user $localuserfield '$mapping' in course '$course->mapping'", 1);
                                 continue;
                             }
                             $user_mapping[$mapping] = $user->id;
@@ -512,9 +506,7 @@ class enrol_database_plugin extends enrol_plugin {
                         }
                         if (empty($fields[$rolefield_l]) or !isset($roles[$fields[$rolefield_l]])) {
                             if (!$defaultrole) {
-                                if ($verbose) {
-                                    mtrace("  error: skipping user '$userid' in course '$course->mapping' - missing course and default role");
-                                }
+                                $trace->output("error: skipping user '$userid' in course '$course->mapping' - missing course and default role", 1);
                                 continue;
                             }
                             $roleid = $defaultrole;
@@ -527,7 +519,7 @@ class enrol_database_plugin extends enrol_plugin {
                 }
                 $rs->Close();
             } else {
-                mtrace("  error: skipping course '$course->mapping' - could not match with external database");
+                $trace->output("error: skipping course '$course->mapping' - could not match with external database", 1);
                 continue;
             }
             unset($user_mapping);
@@ -539,9 +531,7 @@ class enrol_database_plugin extends enrol_plugin {
                         $this->enrol_user($instance, $userid, $roleid, 0, 0, ENROL_USER_ACTIVE);