Merge branch 'MDL-29662' of git://github.com/timhunt/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 3 Sep 2012 23:14:06 +0000 (01:14 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 3 Sep 2012 23:14:06 +0000 (01:14 +0200)
397 files changed:
admin/enrol.php
admin/environment.xml
admin/roles/lib.php
admin/tool/assignmentupgrade/lang/en/tool_assignmentupgrade.php
admin/tool/assignmentupgrade/module.js
admin/tool/assignmentupgrade/renderer.php
admin/user/user_bulk_cohortadd.php
backup/moodle2/backup_custom_fields.php
backup/moodle2/backup_stepslib.php
backup/moodle2/restore_stepslib.php
backup/upgrade.txt [new file with mode: 0644]
backup/util/dbops/backup_plan_dbops.class.php
backup/util/dbops/restore_dbops.class.php
backup/util/helper/backup_cron_helper.class.php
backup/util/plan/backup_structure_step.class.php
backup/util/plan/restore_structure_step.class.php
backup/util/structure/backup_nested_element.class.php
backup/util/ui/backup_ui_stage.class.php
backup/util/ui/restore_ui_stage.class.php
blocks/community/block_community.php
blocks/completionstatus/block_completionstatus.php
blocks/completionstatus/details.php
blocks/completionstatus/lang/en/block_completionstatus.php
blocks/edit_form.php
blocks/html/block_html.php
blocks/html/edit_form.php
blocks/html/lang/en/block_html.php
blocks/html/lib.php
blocks/html/settings.php [new file with mode: 0644]
blocks/quiz_results/block_quiz_results.php
blog/locallib.php
cohort/assign.php
cohort/edit.php
cohort/edit_form.php
cohort/index.php
cohort/lib.php
comment/lib.php
comment/locallib.php
course/editsection_form.php
course/lib.php
course/reset_form.php
draftfile.php
enrol/ajax.php
enrol/category/locallib.php
enrol/cohort/addinstance_form.php
enrol/cohort/lib.php
enrol/cohort/locallib.php
enrol/externallib.php
enrol/imsenterprise/lib.php
enrol/locallib.php
enrol/manual/ajax.php
enrol/manual/bulkchangeforms.php
enrol/manual/db/access.php
enrol/manual/db/install.php
enrol/manual/edit.php
enrol/manual/edit_form.php
enrol/manual/editenrolment.php
enrol/manual/editenrolment_form.php
enrol/manual/externallib.php
enrol/manual/lib.php
enrol/manual/locallib.php
enrol/manual/manage.php
enrol/manual/settings.php
enrol/manual/tests/lib_test.php [new file with mode: 0644]
enrol/manual/unenrolself.php
enrol/manual/version.php
enrol/renderer.php
enrol/self/db/access.php
enrol/self/db/install.php
enrol/self/edit.php
enrol/self/edit_form.php
enrol/self/editenrolment.php
enrol/self/editenrolment_form.php
enrol/self/lang/en/enrol_self.php
enrol/self/lib.php
enrol/self/locallib.php
enrol/self/settings.php
enrol/self/unenrolself.php
enrol/self/version.php
enrol/upgrade.txt
files/externallib.php
files/renderer.php
filter/algebra/filter.php
filter/algebra/tests/filter_test.php [new file with mode: 0644]
grade/grading/form/guide/lang/en/gradingform_guide.php
grade/grading/form/guide/lib.php
grade/grading/form/guide/preview.php
grade/grading/form/rubric/lib.php
grade/grading/form/rubric/preview.php
grade/grading/lib.php
grade/grading/manage.php
grade/lib.php
group/externallib.php
group/lib.php
group/members.php
install/lang/lt/admin.php
lang/en/admin.php
lang/en/backup.php
lang/en/enrol.php
lang/en/group.php
lang/en/moodle.php
lang/en/repository.php
lib/accesslib.php
lib/adodb/adodb-active-record.inc.php
lib/adodb/adodb-csvlib.inc.php
lib/adodb/adodb-datadict.inc.php
lib/adodb/adodb-error.inc.php
lib/adodb/adodb-errorhandler.inc.php
lib/adodb/adodb-errorpear.inc.php
lib/adodb/adodb-exceptions.inc.php
lib/adodb/adodb-iterator.inc.php
lib/adodb/adodb-lib.inc.php
lib/adodb/adodb-memcache.lib.inc.php
lib/adodb/adodb-pager.inc.php
lib/adodb/adodb-pear.inc.php
lib/adodb/adodb-perf.inc.php
lib/adodb/adodb-php4.inc.php
lib/adodb/adodb.inc.php
lib/adodb/drivers/adodb-access.inc.php
lib/adodb/drivers/adodb-ado.inc.php
lib/adodb/drivers/adodb-ado5.inc.php
lib/adodb/drivers/adodb-ado_access.inc.php
lib/adodb/drivers/adodb-ado_mssql.inc.php
lib/adodb/drivers/adodb-borland_ibase.inc.php
lib/adodb/drivers/adodb-csv.inc.php
lib/adodb/drivers/adodb-db2.inc.php
lib/adodb/drivers/adodb-db2oci.inc.php
lib/adodb/drivers/adodb-db2ora.inc.php
lib/adodb/drivers/adodb-fbsql.inc.php
lib/adodb/drivers/adodb-firebird.inc.php
lib/adodb/drivers/adodb-ibase.inc.php
lib/adodb/drivers/adodb-informix.inc.php
lib/adodb/drivers/adodb-informix72.inc.php
lib/adodb/drivers/adodb-ldap.inc.php
lib/adodb/drivers/adodb-mssql.inc.php
lib/adodb/drivers/adodb-mssqlnative.inc.php
lib/adodb/drivers/adodb-mssqlpo.inc.php
lib/adodb/drivers/adodb-mysql.inc.php
lib/adodb/drivers/adodb-mysqli.inc.php
lib/adodb/drivers/adodb-mysqlpo.inc.php
lib/adodb/drivers/adodb-mysqlt.inc.php
lib/adodb/drivers/adodb-netezza.inc.php
lib/adodb/drivers/adodb-oci8.inc.php
lib/adodb/drivers/adodb-oci805.inc.php
lib/adodb/drivers/adodb-oci8po.inc.php
lib/adodb/drivers/adodb-odbc.inc.php
lib/adodb/drivers/adodb-odbc_db2.inc.php
lib/adodb/drivers/adodb-odbc_mssql.inc.php
lib/adodb/drivers/adodb-odbc_oracle.inc.php
lib/adodb/drivers/adodb-odbtp.inc.php
lib/adodb/drivers/adodb-odbtp_unicode.inc.php
lib/adodb/drivers/adodb-oracle.inc.php
lib/adodb/drivers/adodb-pdo.inc.php
lib/adodb/drivers/adodb-pdo_mssql.inc.php
lib/adodb/drivers/adodb-pdo_mysql.inc.php
lib/adodb/drivers/adodb-pdo_oci.inc.php
lib/adodb/drivers/adodb-pdo_pgsql.inc.php
lib/adodb/drivers/adodb-pdo_sqlite.inc.php
lib/adodb/drivers/adodb-postgres.inc.php
lib/adodb/drivers/adodb-postgres64.inc.php
lib/adodb/drivers/adodb-postgres7.inc.php
lib/adodb/drivers/adodb-postgres8.inc.php
lib/adodb/drivers/adodb-proxy.inc.php
lib/adodb/drivers/adodb-sapdb.inc.php
lib/adodb/drivers/adodb-sqlanywhere.inc.php
lib/adodb/drivers/adodb-sqlite.inc.php
lib/adodb/drivers/adodb-sqlite3.inc.php
lib/adodb/drivers/adodb-sqlitepo.inc.php
lib/adodb/drivers/adodb-sybase.inc.php
lib/adodb/drivers/adodb-sybase_ase.inc.php
lib/adodb/drivers/adodb-vfp.inc.php
lib/adodb/lang/adodb-ar.inc.php [deleted file]
lib/adodb/lang/adodb-bg.inc.php [deleted file]
lib/adodb/lang/adodb-bgutf8.inc.php [deleted file]
lib/adodb/lang/adodb-ca.inc.php [deleted file]
lib/adodb/lang/adodb-cn.inc.php [deleted file]
lib/adodb/lang/adodb-cz.inc.php [deleted file]
lib/adodb/lang/adodb-da.inc.php [deleted file]
lib/adodb/lang/adodb-de.inc.php [deleted file]
lib/adodb/lang/adodb-es.inc.php [deleted file]
lib/adodb/lang/adodb-esperanto.inc.php [deleted file]
lib/adodb/lang/adodb-fa.inc.php [deleted file]
lib/adodb/lang/adodb-fr.inc.php [deleted file]
lib/adodb/lang/adodb-hu.inc.php [deleted file]
lib/adodb/lang/adodb-it.inc.php [deleted file]
lib/adodb/lang/adodb-nl.inc.php [deleted file]
lib/adodb/lang/adodb-pl.inc.php [deleted file]
lib/adodb/lang/adodb-pt-br.inc.php [deleted file]
lib/adodb/lang/adodb-ro.inc.php [deleted file]
lib/adodb/lang/adodb-ru1251.inc.php [deleted file]
lib/adodb/lang/adodb-sv.inc.php [deleted file]
lib/adodb/lang/adodb-uk1251.inc.php [deleted file]
lib/adodb/lang/adodb_th.inc.php [deleted file]
lib/adodb/perf/perf-db2.inc.php
lib/adodb/perf/perf-informix.inc.php
lib/adodb/perf/perf-mssql.inc.php
lib/adodb/perf/perf-mssqlnative.inc.php
lib/adodb/perf/perf-mysql.inc.php
lib/adodb/perf/perf-oci8.inc.php
lib/adodb/perf/perf-postgres.inc.php
lib/adodb/readme_moodle.txt
lib/blocklib.php
lib/boxlib.php
lib/completionlib.php
lib/cronlib.php
lib/csvlib.class.php
lib/db/install.xml
lib/db/upgrade.php
lib/db/upgradelib.php
lib/editor/tinymce/adminlib.php
lib/editor/tinymce/classes/plugin.php
lib/editor/tinymce/lang/en/editor_tinymce.php
lib/editor/tinymce/lib.php
lib/editor/tinymce/plugins/dragmath/lib.php
lib/editor/tinymce/plugins/moodleemoticon/lib.php
lib/editor/tinymce/plugins/moodleimage/lib.php
lib/editor/tinymce/plugins/moodlemedia/lib.php
lib/editor/tinymce/plugins/moodlenolink/lib.php
lib/editor/tinymce/plugins/moodlenolink/tinymce/editor_plugin.js
lib/editor/tinymce/plugins/spellchecker/config.php
lib/editor/tinymce/plugins/spellchecker/db/install.php [new file with mode: 0644]
lib/editor/tinymce/plugins/spellchecker/db/upgrade.php [new file with mode: 0644]
lib/editor/tinymce/plugins/spellchecker/db/upgradelib.php [new file with mode: 0644]
lib/editor/tinymce/plugins/spellchecker/lib.php
lib/editor/tinymce/plugins/spellchecker/settings.php [new file with mode: 0644]
lib/editor/tinymce/plugins/spellchecker/version.php
lib/editor/tinymce/settings.php
lib/editor/tinymce/subplugins.php
lib/editor/tinymce/tests/editor_test.php [new file with mode: 0644]
lib/editor/tinymce/upgrade.txt [new file with mode: 0644]
lib/externallib.php
lib/filebrowser/file_info_context_course.php
lib/filebrowser/file_info_context_coursecat.php
lib/filebrowser/file_info_context_module.php
lib/filelib.php
lib/filestorage/file_storage.php
lib/filestorage/stored_file.php
lib/flowplayer/README.txt
lib/flowplayer/README_audio.txt
lib/flowplayer/flowplayer-3.2.11.js [moved from lib/flowplayer/flowplayer-3.2.8.js with 96% similarity]
lib/flowplayer/flowplayer-3.2.11.min.js [new file with mode: 0644]
lib/flowplayer/flowplayer-3.2.14.swf [new file with mode: 0644]
lib/flowplayer/flowplayer-3.2.8.min.js [deleted file]
lib/flowplayer/flowplayer-3.2.9.swf [deleted file]
lib/flowplayer/flowplayer.audio-3.2.10.swf [new file with mode: 0644]
lib/flowplayer/flowplayer.audio-3.2.8.swf [deleted file]
lib/flowplayer/flowplayer.controls-3.2.13.swf [new file with mode: 0644]
lib/flowplayer/flowplayer.controls-3.2.9.swf [deleted file]
lib/googleapi.php
lib/javascript-static.js
lib/modinfolib.php
lib/moodlelib.php
lib/navigationlib.php
lib/oauthlib.php
lib/phpmailer/README
lib/phpmailer/README_MOODLE.txt
lib/phpmailer/changelog.txt
lib/phpmailer/class.phpmailer.php
lib/phpmailer/class.smtp.php
lib/phpmailer/moodle_phpmailer.php
lib/pluginlib.php
lib/questionlib.php
lib/session-test.php [deleted file]
lib/sessionlib.php
lib/setuplib.php
lib/tcpdf/2dbarcodes.php
lib/tcpdf/CHANGELOG.TXT
lib/tcpdf/README.TXT
lib/tcpdf/barcodes.php
lib/tcpdf/composer.json [new file with mode: 0644]
lib/tcpdf/config/tcpdf_config.php [changed mode: 0644->0755]
lib/tcpdf/qrcode.php
lib/tcpdf/readme_moodle.txt
lib/tcpdf/tcpdf.php
lib/tcpdf/tcpdf_parser.php
lib/tests/accesslib_test.php
lib/tests/completionlib_test.php
lib/tests/csvclass_test.php
lib/tests/moodlelib_test.php
lib/tests/pluginlib_test.php
lib/tests/questionlib_test.php
lib/thirdpartylibs.xml
lib/typo3/class.t3lib_cs.php
lib/typo3/class.t3lib_div.php
lib/typo3/class.t3lib_l10n_locales.php
lib/typo3/readme_moodle.txt
lib/weblib.php
login/index.php
message/edit.php
message/lib.php
mod/assign/gradingtable.php
mod/assign/locallib.php
mod/assignment/type/upload/assignment.class.php
mod/choice/backup/moodle2/restore_choice_stepslib.php
mod/data/field/checkbox/mod.html
mod/data/field/latlong/field.class.php
mod/data/field/menu/mod.html
mod/data/field/multimenu/mod.html
mod/data/field/picture/field.class.php
mod/data/field/picture/mod.html
mod/data/field/radiobutton/mod.html
mod/data/field/textarea/mod.html
mod/data/lib.php
mod/data/styles.css
mod/data/templates.php
mod/feedback/item/multichoice/lib.php
mod/feedback/item/multichoicerated/lib.php
mod/feedback/lang/en/feedback.php
mod/forum/lib.php
mod/glossary/lib.php
mod/lesson/format.php
mod/quiz/edit.php
mod/quiz/editlib.php
mod/quiz/report/upgrade.txt
mod/quiz/styles.css
mod/wiki/edit_form.php
mod/workshop/form/comments/backup/moodle1/lib.php
mod/workshop/form/numerrors/backup/moodle1/lib.php
mod/workshop/form/rubric/backup/moodle1/lib.php
question/addquestion.php
question/category.php
question/category_class.php
question/editlib.php
question/engine/questionusage.php
question/format.php
question/format/blackboard/format.php
question/format/blackboard_six/format.php
question/format/blackboard_six/formatbase.php [new file with mode: 0644]
question/format/blackboard_six/formatpool.php [new file with mode: 0644]
question/format/blackboard_six/formatqti.php [new file with mode: 0644]
question/format/blackboard_six/lang/en/qformat_blackboard_six.php
question/format/blackboard_six/tests/blackboardformatpool_test.php [new file with mode: 0644]
question/format/blackboard_six/tests/blackboardsixformatqti_test.php [new file with mode: 0644]
question/format/blackboard_six/tests/fixtures/sample_blackboard_pool.dat [new file with mode: 0644]
question/format/blackboard_six/tests/fixtures/sample_blackboard_qti.dat [new file with mode: 0644]
question/format/blackboard_six/version.php
question/format/examview/format.php
question/format/gift/format.php
question/format/gift/tests/fixtures/questions.gift.txt
question/format/gift/tests/giftformat_test.php
question/format/multianswer/format.php
question/format/multianswer/tests/fixtures/questions.multianswer.txt [new file with mode: 0644]
question/format/multianswer/tests/multianswerformat_test.php [new file with mode: 0644]
question/import.php
question/preview.php
question/question.php
question/type/calculated/datasetdefinitions_form.php
question/type/calculated/datasetitems_form.php
question/type/calculated/questiontype.php
question/type/edit_question_form.php
question/type/essay/db/upgrade.php
question/type/match/lang/en/qtype_match.php
question/type/multianswer/lang/en/qtype_multianswer.php
question/type/multianswer/questiontype.php
question/type/multichoice/lang/en/qtype_multichoice.php
question/type/multichoice/styles.css
question/type/numerical/question.php
question/type/numerical/tests/answer_test.php
question/type/questiontypebase.php
question/type/shortanswer/lang/en/qtype_shortanswer.php
report/backups/index.php
report/security/locallib.php
report/stats/lib.php
repository/alfresco/lib.php
repository/boxnet/lib.php
repository/coursefiles/lib.php
repository/draftfiles_ajax.php
repository/dropbox/db/upgrade.php [new file with mode: 0644]
repository/dropbox/lang/en/repository_dropbox.php
repository/dropbox/lib.php
repository/dropbox/locallib.php
repository/dropbox/thumbnail.php [new file with mode: 0644]
repository/dropbox/version.php
repository/equella/lib.php
repository/filepicker.php
repository/filesystem/lib.php
repository/flickr/lib.php
repository/flickr_public/lib.php
repository/googledocs/lib.php
repository/lib.php
repository/local/lib.php
repository/manage_instances.php
repository/recent/lib.php
repository/repository_ajax.php
theme/afterburner/style/afterburner_styles.css
theme/anomaly/style/general.css
theme/base/style/admin.css
theme/base/style/user.css
theme/formal_white/style/formal_white.css
theme/yui_combo.php
user/index.php
user/profile.php
user/selector/lib.php
user/selector/module.js
user/selector/search.php
version.php
webservice/lib.php

index 9fc196f..b0818dd 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+define('NO_OUTPUT_BUFFERING', true);
+
 require_once('../config.php');
 require_once($CFG->libdir.'/adminlib.php');
 
 $action  = required_param('action', PARAM_ALPHANUMEXT);
 $enrol   = required_param('enrol', PARAM_PLUGIN);
 $confirm = optional_param('confirm', 0, PARAM_BOOL);
+$migrate = optional_param('migrate', 0, PARAM_BOOL);
 
 $PAGE->set_url('/admin/enrol.php');
 $PAGE->set_context(context_system::instance());
@@ -94,24 +97,58 @@ switch ($action) {
         break;
 
     case 'uninstall':
-        echo $OUTPUT->header();
-        echo $OUTPUT->heading(get_string('enrolments', 'enrol'));
-
         if (get_string_manager()->string_exists('pluginname', 'enrol_'.$enrol)) {
             $strplugin = get_string('pluginname', 'enrol_'.$enrol);
         } else {
             $strplugin = $enrol;
         }
 
+        echo $PAGE->set_title($strplugin);
+        echo $OUTPUT->header();
+
         if (!$confirm) {
-            $uurl = new moodle_url('/admin/enrol.php', array('action'=>'uninstall', 'enrol'=>$enrol, 'sesskey'=>sesskey(), 'confirm'=>1));
-            echo $OUTPUT->confirm(get_string('uninstallconfirm', 'enrol', $strplugin), $uurl, $return);
+            echo $OUTPUT->heading(get_string('enrolments', 'enrol'));
+
+            $deleteurl = new moodle_url('/admin/enrol.php', array('action'=>'uninstall', 'enrol'=>$enrol, 'sesskey'=>sesskey(), 'confirm'=>1, 'migrate'=>0));
+            $migrateurl = new moodle_url('/admin/enrol.php', array('action'=>'uninstall', 'enrol'=>$enrol, 'sesskey'=>sesskey(), 'confirm'=>1, 'migrate'=>1));
+
+            $migrate = new single_button($migrateurl, get_string('uninstallmigrate', 'enrol'));
+            $delete = new single_button($deleteurl, get_string('uninstalldelete', 'enrol'));
+            $cancel = new single_button($return, get_string('cancel'), 'get');
+
+            $buttons = $OUTPUT->render($delete) . $OUTPUT->render($cancel);
+            if ($enrol !== 'manual') {
+                $buttons = $OUTPUT->render($migrate) . $buttons;
+            }
+
+            echo $OUTPUT->box_start('generalbox', 'notice');
+            echo html_writer::tag('p', markdown_to_html(get_string('uninstallconfirm', 'enrol', $strplugin)));
+            echo html_writer::tag('div', $buttons, array('class' => 'buttons'));
+            echo $OUTPUT->box_end();
+
             echo $OUTPUT->footer();
             exit;
 
-        } else {  // Delete everything!!
+        } else {
+            // This may take a long time.
+            set_time_limit(0);
+
+            // Disable plugin to prevent concurrent cron execution.
+            unset($enabled[$enrol]);
+            set_config('enrol_plugins_enabled', implode(',', array_keys($enabled)));
+
+            if ($migrate) {
+                echo $OUTPUT->heading(get_string('uninstallmigrating', 'enrol', 'enrol_'.$enrol));
+
+                require_once("$CFG->dirroot/enrol/manual/locallib.php");
+                enrol_manual_migrate_plugin_enrolments($enrol);
+
+                echo $OUTPUT->notification(get_string('success'), 'notifysuccess');
+            }
+
+            // Delete everything!!
             uninstall_plugin('enrol', $enrol);
-            $syscontext->mark_dirty(); // resets all enrol caches
+            $syscontext->mark_dirty(); // Resets all enrol caches.
 
             $a = new stdClass();
             $a->plugin = $strplugin;
index 004cab0..584a9b0 100644 (file)
         </FEEDBACK>
       </PHP_SETTING>
     </PHP_SETTINGS>
-</MOODLE>
+  </MOODLE>
+  <MOODLE version="2.4" requires="2.2">
+    <UNICODE level="required">
+      <FEEDBACK>
+        <ON_ERROR message="unicoderequired" />
+      </FEEDBACK>
+    </UNICODE>
+    <DATABASE level="required">
+      <VENDOR name="mysql" version="5.1.33" />
+      <VENDOR name="postgres" version="8.3" />
+      <VENDOR name="mssql" version="9.0" />
+      <VENDOR name="odbc_mssql" version="9.0" />
+      <VENDOR name="mssql_n" version="9.0" />
+      <VENDOR name="oracle" version="10.2" />
+      <VENDOR name="sqlite" version="2.0" />
+    </DATABASE>
+    <PHP version="5.3.2" level="required">
+    </PHP>
+    <PCREUNICODE level="optional">
+      <FEEDBACK>
+        <ON_CHECK message="pcreunicodewarning" />
+      </FEEDBACK>
+    </PCREUNICODE>
+    <PHP_EXTENSIONS>
+      <PHP_EXTENSION name="iconv" level="required">
+        <FEEDBACK>
+          <ON_CHECK message="iconvrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="mbstring" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="mbstringrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="curl" level="required">
+        <FEEDBACK>
+          <ON_CHECK message="curlrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="openssl" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="opensslrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="tokenizer" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="tokenizerrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="xmlrpc" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="xmlrpcrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="soap" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="soaprecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="ctype" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="ctyperequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="zip" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="ziprequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="gd" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="gdrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="simplexml" level="required">
+        <FEEDBACK>
+          <ON_CHECK message="simplexmlrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="spl" level="required">
+        <FEEDBACK>
+          <ON_CHECK message="splrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="pcre" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="dom" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="xml" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="intl" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="intlrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="json" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="hash" level="required"/>
+    </PHP_EXTENSIONS>
+    <PHP_SETTINGS>
+      <PHP_SETTING name="memory_limit" value="40M" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="settingmemorylimit" />
+        </FEEDBACK>
+      </PHP_SETTING>
+      <PHP_SETTING name="safe_mode" value="0" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="settingsafemode" />
+        </FEEDBACK>
+      </PHP_SETTING>
+      <PHP_SETTING name="file_uploads" value="1" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="settingfileuploads" />
+        </FEEDBACK>
+      </PHP_SETTING>
+    </PHP_SETTINGS>
+  </MOODLE>
 </COMPATIBILITY_MATRIX>
index 43eb7f5..df537f0 100644 (file)
@@ -933,7 +933,7 @@ class override_permissions_table_advanced extends capability_table_with_risks {
         global $DB;
 
     /// Get the capabilities from the parent context, so that can be shown in the interface.
-        $parentcontext = get_context_instance_by_id(get_parent_contextid($this->context));
+        $parentcontext = context::instance_by_id(get_parent_contextid($this->context));
         $this->parentpermissions = role_context_capabilities($this->roleid, $parentcontext);
     }
 
@@ -996,7 +996,7 @@ abstract class role_assign_user_selector_base extends user_selector_base {
         if (isset($options['context'])) {
             $this->context = $options['context'];
         } else {
-            $this->context = get_context_instance_by_id($options['contextid']);
+            $this->context = context::instance_by_id($options['contextid']);
         }
         $options['accesscontext'] = $this->context;
         parent::__construct($name, $options);
@@ -1230,7 +1230,7 @@ class existing_role_holders extends role_assign_user_selector_base {
     }
 
     protected function parent_con_group_name($search, $contextid) {
-        $context = get_context_instance_by_id($contextid);
+        $context = context::instance_by_id($contextid);
         $contextname = print_context_name($context, true, true);
         if ($search) {
             $a = new stdClass;
@@ -1477,7 +1477,7 @@ class role_allow_switch_page extends role_allow_role_page {
 function roles_get_potential_user_selector($context, $name, $options) {
         $blockinsidecourse = false;
         if ($context->contextlevel == CONTEXT_BLOCK) {
-            $parentcontext = get_context_instance_by_id(get_parent_contextid($context));
+            $parentcontext = context::instance_by_id(get_parent_contextid($context));
             $blockinsidecourse = in_array($parentcontext->contextlevel, array(CONTEXT_MODULE, CONTEXT_COURSE));
         }
 
index e9a61dc..9dc8c6e 100644 (file)
@@ -36,6 +36,7 @@ $string['conversioncomplete'] = 'Assignment converted';
 $string['conversionfailed'] = 'The assignment conversion was not successful. The log from the upgrade was: <br />{$a}';
 $string['listnotupgraded'] = 'List assignments that have not been upgraded';
 $string['listnotupgraded_desc'] = 'You can upgrade individual assignments from here';
+$string['noassignmentsselected'] = 'No assignments selected';
 $string['noassignmentstoupgrade'] = 'There are no assignments that require upgrading';
 $string['notsupported'] = '';
 $string['notupgradedintro'] = 'This page lists the assignments created with an older version of Moodle that have not been upgraded to the new assignment module in Moodle 2.3. Not all assignments can be upgraded - if they were created with a custom assignment subtype, then that subtype will need to be upgraded to the new assignment plugin format in order to complete the upgrade.';
index edee839..7c170f1 100644 (file)
@@ -42,8 +42,8 @@ M.tool_assignmentupgrade = {
             }
         });
 
-        var batchform = Y.one('.tool_assignmentupgrade_batchform form');
-        batchform.on('submit', function(e) {
+        var upgradeselectedbutton = Y.one('#id_upgradeselected');
+        upgradeselectedbutton.on('click', function(e) {
             checkboxes = Y.all('td.c0 input');
             var selectedassignments = [];
             checkboxes.each(function(node) {
@@ -56,7 +56,7 @@ M.tool_assignmentupgrade = {
             assignmentsinput = Y.one('input.selectedassignments');
             assignmentsinput.set('value', selectedassignments.join(','));
             if (selectedassignments.length == 0) {
-                alert(M.str.assign.noassignmentsselected);
+                alert(M.str.tool_assignmentupgrade.noassignmentsselected);
                 e.preventDefault();
             }
         });
index ddb8cfa..29192d7 100644 (file)
@@ -119,7 +119,7 @@ class tool_assignmentupgrade_renderer extends plugin_renderer_base {
         $output = '';
         $output .= $this->header();
         $this->page->requires->js_init_call('M.tool_assignmentupgrade.init_upgrade_table', array());
-
+        $this->page->requires->string_for_js('noassignmentsselected', 'tool_assignmentupgrade');
 
         $output .= $this->heading(get_string('notupgradedtitle', 'tool_assignmentupgrade'));
         $output .= $this->box(get_string('notupgradedintro', 'tool_assignmentupgrade'));
index 1e32564..be72d51 100644 (file)
@@ -45,7 +45,7 @@ foreach ($allcohorts as $c) {
         // external cohorts can not be modified
         continue;
     }
-    $context = get_context_instance_by_id($c->contextid);
+    $context = context::instance_by_id($c->contextid);
     if (!has_capability('moodle/cohort:assign', $context)) {
         continue;
     }
index e0ceb33..12929de 100644 (file)
@@ -96,14 +96,19 @@ class file_nested_element extends backup_nested_element {
         if (is_null($this->backupid)) {
             $this->backupid = $processor->get_var(backup::VAR_BACKUPID);
         }
-        parent::process($processor);
+        return parent::process($processor);
     }
 
     public function fill_values($values) {
         // Fill values
         parent::fill_values($values);
         // Do our own tasks (copy file from moodle to backup)
-        backup_file_manager::copy_file_moodle2backup($this->backupid, $values);
+        try {
+            backup_file_manager::copy_file_moodle2backup($this->backupid, $values);
+        } catch (file_exception $e) {
+            $this->add_result(array('missing_files_in_pool' => true));
+            $this->add_log('missing file in pool: ' . $e->debuginfo, backup::LOG_WARNING);
+        }
     }
 }
 
index b4399f2..850bb2e 100644 (file)
@@ -522,9 +522,12 @@ class backup_enrolments_structure_step extends backup_structure_step {
         $enrol = new backup_nested_element('enrol', array('id'), array(
             'enrol', 'status', 'sortorder', 'name', 'enrolperiod', 'enrolstartdate',
             'enrolenddate', 'expirynotify', 'expirytreshold', 'notifyall',
-            'password', 'cost', 'currency', 'roleid', 'customint1', 'customint2', 'customint3',
-            'customint4', 'customchar1', 'customchar2', 'customdec1', 'customdec2',
-            'customtext1', 'customtext2', 'timecreated', 'timemodified'));
+            'password', 'cost', 'currency', 'roleid',
+            'customint1', 'customint2', 'customint3', 'customint4', 'customint5', 'customint6', 'customint7', 'customint8',
+            'customchar1', 'customchar2', 'customchar3',
+            'customdec1', 'customdec2',
+            'customtext1', 'customtext2', 'customtext3', 'customtext4',
+            'timecreated', 'timemodified'));
 
         $userenrolments = new backup_nested_element('user_enrolments');
 
@@ -1002,7 +1005,7 @@ class backup_groups_structure_step extends backup_structure_step {
         $members = new backup_nested_element('group_members');
 
         $member = new backup_nested_element('group_member', array('id'), array(
-            'userid', 'timeadded'));
+            'userid', 'timeadded', 'component', 'itemid'));
 
         $groupings = new backup_nested_element('groupings');
 
index 3677d7b..8742f0a 100644 (file)
@@ -270,7 +270,14 @@ class restore_gradebook_structure_step extends restore_structure_step {
 
         $data->contextid = context_course::instance($this->get_courseid())->id;
 
-        $newitemid = $DB->insert_record('grade_letters', $data);
+        $gradeletter = (array)$data;
+        unset($gradeletter['id']);
+        if (!$DB->record_exists('grade_letters', $gradeletter)) {
+            $newitemid = $DB->insert_record('grade_letters', $data);
+        } else {
+            $newitemid = $data->id;
+        }
+
         $this->set_mapping('grade_letter', $oldid, $newitemid);
     }
     protected function process_grade_setting($data) {
@@ -773,6 +780,17 @@ class restore_groups_structure_step extends restore_structure_step {
         // map user newitemid and insert if not member already
         if ($data->userid = $this->get_mappingid('user', $data->userid)) {
             if (!$DB->record_exists('groups_members', array('groupid' => $data->groupid, 'userid' => $data->userid))) {
+                // Check the componment, if any, exists
+                if (!empty($data->component)) {
+                    $dir = get_component_directory($data->component);
+                    if (!$dir || !is_dir($dir)) {
+                        // Component does not exist on restored system; clear
+                        // component and itemid
+                        unset($data->component);
+                        unset($data->itemid);
+                    }
+                }
+
                 $DB->insert_record('groups_members', $data);
             }
         }
@@ -2399,17 +2417,21 @@ class restore_activity_grades_structure_step extends restore_structure_step {
 
     /**
      * process activity grade_letters. Note that, while these are possible,
-     * because grade_letters are contextid based, in proctice, only course
+     * because grade_letters are contextid based, in practice, only course
      * context letters can be defined. So we keep here this method knowing
      * it won't be executed ever. gradebook restore will restore course letters.
      */
     protected function process_grade_letter($data) {
         global $DB;
 
-        $data = (object)$data;
+        $data['contextid'] = $this->task->get_contextid();
+        $gradeletter = (object)$data;
 
-        $data->contextid = $this->task->get_contextid();
-        $newitemid = $DB->insert_record('grade_letters', $data);
+        // Check if it exists before adding it
+        unset($data['id']);
+        if (!$DB->record_exists('grade_letters', $data)) {
+            $newitemid = $DB->insert_record('grade_letters', $gradeletter);
+        }
         // no need to save any grade_letter mapping
     }
 }
diff --git a/backup/upgrade.txt b/backup/upgrade.txt
new file mode 100644 (file)
index 0000000..cb02095
--- /dev/null
@@ -0,0 +1,17 @@
+This files describes API changes in /backup/*,
+information provided here is intended especially for developers.
+
+=== 2.4 ===
+
+* Since 2.3.1+ the backup file name schema has changed. The ID of the course will always be part of
+    the filename regardless of the setting 'backup_shortname'. See MDL-33812.
+
+=== 2.3 ===
+
+* Since 2.3.1+ the backup file name schema has changed. The ID of the course will always be part of
+    the filename regardless of the setting 'backup_shortname'. See MDL-33812.
+
+=== 2.2 ===
+
+* Since 2.2.4+ the backup file name schema has changed. The ID of the course will always be part of
+    the filename regardless of the setting 'backup_shortname'. See MDL-33812.
\ No newline at end of file
index e169a8a..2e2faae 100644 (file)
@@ -197,19 +197,19 @@ abstract class backup_plan_dbops extends backup_dbops {
     * @param int $courseid/$sectionid/$cmid
     * @param bool $users Should be true is users were included in the backup
     * @param bool $anonymised Should be true is user information was anonymized.
-    * @param bool $useidasname true to use id, false to use strings (default)
+    * @param bool $useidonly only use the ID in the file name
     * @return string The filename to use
     */
-    public static function get_default_backup_filename($format, $type, $id, $users, $anonymised, $useidasname = false) {
+    public static function get_default_backup_filename($format, $type, $id, $users, $anonymised, $useidonly = false) {
         global $DB;
 
         // Calculate backup word
         $backupword = str_replace(' ', '_', textlib::strtolower(get_string('backupfilename')));
         $backupword = trim(clean_filename($backupword), '_');
 
+        // Not $useidonly, lets fetch the name
         $shortname = '';
-        // Not $useidasname, lets calculate it, else $id will be used
-        if (!$useidasname) {
+        if (!$useidonly) {
             // Calculate proper name element (based on type)
             switch ($type) {
                 case backup::TYPE_1COURSE:
@@ -231,7 +231,11 @@ abstract class backup_plan_dbops extends backup_dbops {
             $shortname = textlib::strtolower(trim(clean_filename($shortname), '_'));
         }
 
-        $name = empty($shortname) ? $id : $shortname;
+        // The name will always contain the ID, but we append the course short name if requested.
+        $name = $id;
+        if (!$useidonly && $shortname != '') {
+            $name .= '-' . $shortname;
+        }
 
         // Calculate date
         $backupdateformat = str_replace(' ', '_', get_string('backupnameformat', 'langconfig'));
index 3bd86e3..4b6c63c 100644 (file)
@@ -818,10 +818,13 @@ abstract class restore_dbops {
      * @param int|null $olditemid
      * @param int|null $forcenewcontextid explicit value for the new contextid (skip mapping)
      * @param bool $skipparentitemidctxmatch
+     * @return array of result object
      */
     public static function send_files_to_pool($basepath, $restoreid, $component, $filearea, $oldcontextid, $dfltuserid, $itemname = null, $olditemid = null, $forcenewcontextid = null, $skipparentitemidctxmatch = false) {
         global $DB;
 
+        $results = array();
+
         if ($forcenewcontextid) {
             // Some components can have "forced" new contexts (example: questions can end belonging to non-standard context mappings,
             // with questions originally at system/coursecat context in source being restored to course context in target). So we need
@@ -901,8 +904,14 @@ abstract class restore_dbops {
                 // this is a regular file, it must be present in the backup pool
                 $backuppath = $basepath . backup_file_manager::get_backup_content_file_location($file->contenthash);
 
+                // The file is not found in the backup.
                 if (!file_exists($backuppath)) {
-                    throw new restore_dbops_exception('file_not_found_in_pool', $file);
+                    $result = new stdClass();
+                    $result->code = 'file_missing_in_backup';
+                    $result->message = sprintf('missing file %s%s in backup', $file->filepath, $file->filename);
+                    $result->level = backup::LOG_WARNING;
+                    $results[] = $result;
+                    continue;
                 }
 
                 // create the file in the filepool if it does not exist yet
@@ -959,6 +968,7 @@ abstract class restore_dbops {
             }
         }
         $rs->close();
+        return $results;
     }
 
     /**
index ea8fda0..e3ada4f 100644 (file)
@@ -46,6 +46,8 @@ abstract class backup_cron_automated_helper {
     const BACKUP_STATUS_UNFINISHED = 2;
     /** Course automated backup was skipped */
     const BACKUP_STATUS_SKIPPED = 3;
+    /** Course automated backup had warnings */
+    const BACKUP_STATUS_WARNING = 4;
 
     /** Run if required by the schedule set in config. Default. **/
     const RUN_ON_SCHEDULE = 0;
@@ -139,7 +141,7 @@ abstract class backup_cron_automated_helper {
                     $params = array('courseid' => $course->id, 'time' => $now-31*24*60*60, 'action' => '%view%');
                     $logexists = $DB->record_exists_select('log', $sqlwhere, $params);
                     if (!$logexists) {
-                        $backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_SKIPPED;
+                        $backupcourse->laststatus = self::BACKUP_STATUS_SKIPPED;
                         $backupcourse->nextstarttime = $nextstarttime;
                         $DB->update_record('backup_courses', $backupcourse);
                         mtrace('Skipping unchanged course '.$course->fullname);
@@ -160,7 +162,7 @@ abstract class backup_cron_automated_helper {
                         $starttime = time();
 
                         $backupcourse->laststarttime = time();
-                        $backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_UNFINISHED;
+                        $backupcourse->laststatus = self::BACKUP_STATUS_UNFINISHED;
                         $DB->update_record('backup_courses', $backupcourse);
 
                         $backupcourse->laststatus = backup_cron_automated_helper::launch_automated_backup($course, $backupcourse->laststarttime, $admin->id);
@@ -169,7 +171,7 @@ abstract class backup_cron_automated_helper {
 
                         $DB->update_record('backup_courses', $backupcourse);
 
-                        if ($backupcourse->laststatus) {
+                        if ($backupcourse->laststatus === self::BACKUP_STATUS_OK) {
                             // Clean up any excess course backups now that we have
                             // taken a successful backup.
                             $removedcount = backup_cron_automated_helper::remove_excess_backups($course);
@@ -188,17 +190,18 @@ abstract class backup_cron_automated_helper {
             $message = "";
 
             $count = backup_cron_automated_helper::get_backup_status_array();
-            $haserrors = ($count[backup_cron_automated_helper::BACKUP_STATUS_ERROR] != 0 || $count[backup_cron_automated_helper::BACKUP_STATUS_UNFINISHED] != 0);
+            $haserrors = ($count[self::BACKUP_STATUS_ERROR] != 0 || $count[self::BACKUP_STATUS_UNFINISHED] != 0);
 
             //Build the message text
             //Summary
             $message .= get_string('summary')."\n";
             $message .= "==================================================\n";
             $message .= "  ".get_string('courses').": ".array_sum($count)."\n";
-            $message .= "  ".get_string('ok').": ".$count[backup_cron_automated_helper::BACKUP_STATUS_OK]."\n";
-            $message .= "  ".get_string('skipped').": ".$count[backup_cron_automated_helper::BACKUP_STATUS_SKIPPED]."\n";
-            $message .= "  ".get_string('error').": ".$count[backup_cron_automated_helper::BACKUP_STATUS_ERROR]."\n";
-            $message .= "  ".get_string('unfinished').": ".$count[backup_cron_automated_helper::BACKUP_STATUS_UNFINISHED]."\n\n";
+            $message .= "  ".get_string('ok').": ".$count[self::BACKUP_STATUS_OK]."\n";
+            $message .= "  ".get_string('skipped').": ".$count[self::BACKUP_STATUS_SKIPPED]."\n";
+            $message .= "  ".get_string('error').": ".$count[self::BACKUP_STATUS_ERROR]."\n";
+            $message .= "  ".get_string('unfinished').": ".$count[self::BACKUP_STATUS_UNFINISHED]."\n";
+            $message .= "  ".get_string('warning').": ".$count[self::BACKUP_STATUS_WARNING]."\n\n";
 
             //Reference
             if ($haserrors) {
@@ -261,6 +264,7 @@ abstract class backup_cron_automated_helper {
             self::BACKUP_STATUS_OK => 0,
             self::BACKUP_STATUS_UNFINISHED => 0,
             self::BACKUP_STATUS_SKIPPED => 0,
+            self::BACKUP_STATUS_WARNING => 0
         );
 
         $statuses = $DB->get_records_sql('SELECT DISTINCT bc.laststatus, COUNT(bc.courseid) AS statuscount FROM {backup_courses} bc GROUP BY bc.laststatus');
@@ -334,7 +338,7 @@ abstract class backup_cron_automated_helper {
      */
     public static function launch_automated_backup($course, $starttime, $userid) {
 
-        $outcome = true;
+        $outcome = self::BACKUP_STATUS_OK;
         $config = get_config('backup');
         $bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO, backup::MODE_AUTOMATED, $userid);
 
@@ -369,6 +373,7 @@ abstract class backup_cron_automated_helper {
 
             $bc->execute_plan();
             $results = $bc->get_results();
+            $outcome = self::outcome_from_results($results);
             $file = $results['backup_destination']; // may be empty if file already moved to target location
             $dir = $config->backup_auto_destination;
             $storage = (int)$config->backup_auto_storage;
@@ -377,8 +382,10 @@ abstract class backup_cron_automated_helper {
             }
             if ($file && !empty($dir) && $storage !== 0) {
                 $filename = backup_plan_dbops::get_default_backup_filename($format, $type, $course->id, $users, $anonymised, !$config->backup_shortname);
-                $outcome = $file->copy_content_to($dir.'/'.$filename);
-                if ($outcome && $storage === 1) {
+                if (!$file->copy_content_to($dir.'/'.$filename)) {
+                    $outcome = self::BACKUP_STATUS_ERROR;
+                }
+                if ($outcome != self::BACKUP_STATUS_ERROR && $storage === 1) {
                     $file->delete();
                 }
             }
@@ -387,7 +394,7 @@ abstract class backup_cron_automated_helper {
             $bc->log('backup_auto_failed_on_course', backup::LOG_ERROR, $course->shortname); // Log error header.
             $bc->log('Exception: ' . $e->errorcode, backup::LOG_ERROR, $e->a, 1); // Log original exception problem.
             $bc->log('Debug: ' . $e->debuginfo, backup::LOG_DEBUG, null, 1); // Log original debug information.
-            $outcome = false;
+            $outcome = self::BACKUP_STATUS_ERROR;
         }
 
         $bc->destroy();
@@ -396,6 +403,30 @@ abstract class backup_cron_automated_helper {
         return $outcome;
     }
 
+    /**
+     * Returns the backup outcome by analysing its results.
+     *
+     * @param array $results returned by a backup
+     * @return int {@link self::BACKUP_STATUS_OK} and other constants
+     */
+    public static function outcome_from_results($results) {
+        $outcome = self::BACKUP_STATUS_OK;
+        foreach ($results as $code => $value) {
+            // Each possible error and warning code has to be specified in this switch
+            // which basically analyses the results to return the correct backup status.
+            switch ($code) {
+                case 'missing_files_in_pool':
+                    $outcome = self::BACKUP_STATUS_WARNING;
+                    break;
+            }
+            // If we found the highest error level, we exit the loop.
+            if ($outcome == self::BACKUP_STATUS_ERROR) {
+                break;
+            }
+        }
+        return $outcome;
+    }
+
     /**
      * Removes deleted courses fromn the backup_courses table so that we don't
      * waste time backing them up.
@@ -530,18 +561,7 @@ abstract class backup_cron_automated_helper {
         if (!empty($dir) && ($storage == 1 || $storage == 2)) {
             // Calculate backup filename regex, ignoring the date/time/info parts that can be
             // variable, depending of languages, formats and automated backup settings
-
-
-            // MDL-33531: use different filenames depending on backup_shortname option
-            if ( !empty($config->backup_shortname) ) {
-                $context = get_context_instance(CONTEXT_COURSE, $course->id);
-                $courseref = format_string($course->shortname, true, array('context' => $context));
-                $courseref = str_replace(' ', '_', $courseref);
-                $courseref = textlib::strtolower(trim(clean_filename($courseref), '_'));
-            } else {
-                $courseref = $course->id;
-            }
-            $filename = $backupword . '-' . backup::FORMAT_MOODLE . '-' . backup::TYPE_1COURSE . '-' .$courseref . '-';
+            $filename = $backupword . '-' . backup::FORMAT_MOODLE . '-' . backup::TYPE_1COURSE . '-' .$course->id . '-';
             $regex = '#^'.preg_quote($filename, '#').'.*\.mbz$#';
 
             // Store all the matching files into fullpath => timemodified array
index f62fee9..964dd3f 100644 (file)
@@ -94,11 +94,22 @@ abstract class backup_structure_step extends backup_step {
         // Process structure definition
         $structure->process($pr);
 
+        // Get the results from the nested elements
+        $results = $structure->get_results();
+
+        // Get the log messages to append to the log
+        $logs = $structure->get_logs();
+        foreach ($logs as $log) {
+            $this->log($log->message, $log->level, $log->a, $log->depth, $log->display);
+        }
+
         // Close everything
         $xw->stop();
 
         // Destroy the structure. It helps PHP 5.2 memory a lot!
         $structure->destroy();
+
+        return $results;
     }
 
     /**
index 42491cf..7a1cfa2 100644 (file)
@@ -218,8 +218,14 @@ abstract class restore_structure_step extends restore_step {
      */
     public function add_related_files($component, $filearea, $mappingitemname, $filesctxid = null, $olditemid = null) {
         $filesctxid = is_null($filesctxid) ? $this->task->get_old_contextid() : $filesctxid;
-        restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $component,
-                                          $filearea, $filesctxid, $this->task->get_userid(), $mappingitemname, $olditemid);
+        $results = restore_dbops::send_files_to_pool($this->get_basepath(), $this->get_restoreid(), $component,
+                $filearea, $filesctxid, $this->task->get_userid(), $mappingitemname, $olditemid);
+        $resultstoadd = array();
+        foreach ($results as $result) {
+            $this->log($result->message, $result->level);
+            $resultstoadd[$result->code] = true;
+        }
+        $this->task->add_result($resultstoadd);
     }
 
     /**
index 9a47901..8557ec8 100644 (file)
@@ -37,6 +37,8 @@ class backup_nested_element extends base_nested_element implements processable {
     protected $aliases;   // Define DB->final element aliases
     protected $fileannotations;   // array of file areas to be searched by file annotations
     protected $counter;   // Number of instances of this element that have been processed
+    protected $results;  // Logs the results we encounter during the process.
+    protected $logs;     // Some log messages that could be retrieved later.
 
     /**
      * Constructor - instantiates one backup_nested_element, specifying its basic info.
@@ -55,8 +57,16 @@ class backup_nested_element extends base_nested_element implements processable {
         $this->aliases   = array();
         $this->fileannotations = array();
         $this->counter   = 0;
+        $this->results  = array();
+        $this->logs     = array();
     }
 
+    /**
+     * Process the nested element
+     *
+     * @param object $processor the processor
+     * @return void
+     */
     public function process($processor) {
         if (!$processor instanceof base_processor) { // No correct processor, throw exception
             throw new base_element_struct_exception('incorrect_processor');
@@ -113,6 +123,69 @@ class backup_nested_element extends base_nested_element implements processable {
         $iterator->close();
     }
 
+    /**
+     * Saves a log message to an array
+     *
+     * @see backup_helper::log()
+     * @param string $message to add to the logs
+     * @param int $level level of importance {@link backup::LOG_DEBUG} and other constants
+     * @param mixed $a to be included in $message
+     * @param int $depth of the message
+     * @param display $bool supporting translation via get_string() if true
+     * @return void
+     */
+    protected function add_log($message, $level, $a = null, $depth = null, $display = false) {
+        // Adding the result to the oldest parent.
+        if ($this->get_parent()) {
+            $parent = $this->get_grandparent();
+            $parent->add_log($message, $level, $a, $depth, $display);
+        } else {
+            $log = new stdClass();
+            $log->message = $message;
+            $log->level = $level;
+            $log->a = $a;
+            $log->depth = $depth;
+            $log->display = $display;
+            $this->logs[] = $log;
+        }
+    }
+
+    /**
+     * Saves the results to an array
+     *
+     * @param array $result associative array
+     * @return void
+     */
+    protected function add_result($result) {
+        if (is_array($result)) {
+            // Adding the result to the oldest parent.
+            if ($this->get_parent()) {
+                $parent = $this->get_grandparent();
+                $parent->add_result($result);
+            } else {
+                $this->results = array_merge($this->results, $result);
+            }
+        }
+    }
+
+    /**
+     * Returns the logs
+     *
+     * @return array of log objects
+     */
+    public function get_logs() {
+        return $this->logs;
+    }
+
+    /**
+     * Returns the results
+     *
+     * @return associative array of results
+     */
+    public function get_results() {
+        return $this->results;
+    }
+
     public function set_source_array($arr) {
         // TODO: Only elements having final elements can set source
         $this->var_array = $arr;
index 472294a..4065212 100644 (file)
@@ -487,6 +487,9 @@ class backup_ui_stage_complete extends backup_ui_stage_final {
         if (!empty($this->results['include_file_references_to_external_content'])) {
             $output .= $renderer->notification(get_string('filereferencesincluded', 'backup'), 'notifyproblem');
         }
+        if (!empty($this->results['missing_files_in_pool'])) {
+            $output .= $renderer->notification(get_string('missingfilesinpool', 'backup'), 'notifyproblem');
+        }
         $output .= $renderer->notification(get_string('executionsuccess', 'backup'), 'notifysuccess');
         $output .= $renderer->continue_button($restorerul);
         $output .= $renderer->box_end();
index 6c28254..a7464bf 100644 (file)
@@ -772,6 +772,9 @@ class restore_ui_stage_complete extends restore_ui_stage_process {
             $html .= $renderer->box_end();
         }
         $html .= $renderer->box_start();
+        if (array_key_exists('file_missing_in_backup', $this->results)) {
+            $html .= $renderer->notification(get_string('restorefileweremissing', 'backup'), 'notifyproblem');
+        }
         $html .= $renderer->notification(get_string('restoreexecutionsuccess', 'backup'), 'notifysuccess');
         $html .= $renderer->continue_button(new moodle_url('/course/view.php', array(
             'id' => $this->get_ui()->get_controller()->get_courseid())), 'get');
index 35e3f2e..c211342 100644 (file)
@@ -43,7 +43,7 @@ class block_community extends block_list {
     function user_can_edit() {
         // Don't allow people to edit the block if they can't even use it
         if (!has_capability('moodle/community:add',
-                        get_context_instance_by_id($this->instance->parentcontextid))) {
+                        context::instance_by_id($this->instance->parentcontextid))) {
             return false;
         }
         return parent::user_can_edit();
@@ -52,7 +52,7 @@ class block_community extends block_list {
     function get_content() {
         global $CFG, $OUTPUT, $USER;
 
-        $coursecontext = get_context_instance_by_id($this->instance->parentcontextid);
+        $coursecontext = context::instance_by_id($this->instance->parentcontextid);
 
         if (!has_capability('moodle/community:add', $coursecontext)
                 or $this->content !== NULL) {
index 2b598ce..b339e9a 100644 (file)
  *
  * @package    block
  * @subpackage completion
- * @copyright  2009 Catalyst IT Ltd
+ * @copyright  2009-2012 Catalyst IT Ltd
  * @author     Aaron Barnes <aaronb@catalyst.net.nz>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 defined('MOODLE_INTERNAL') || die();
 
-
-require_once($CFG->libdir.'/completionlib.php');
+require_once("{$CFG->libdir}/completionlib.php");
 
 /**
  * Course completion status
@@ -36,25 +35,28 @@ require_once($CFG->libdir.'/completionlib.php');
 class block_completionstatus extends block_base {
 
     public function init() {
-        $this->title   = get_string('pluginname', 'block_completionstatus');
+        $this->title = get_string('pluginname', 'block_completionstatus');
     }
 
     public function get_content() {
-        global $USER, $CFG, $DB, $COURSE;
+        global $USER;
 
         // If content is cached
         if ($this->content !== NULL) {
             return $this->content;
         }
 
+        $course  = $this->page->course;
+        $context = context_course::instance($course->id);
+
         // Create empty content
-        $this->content = new stdClass;
+        $this->content = new stdClass();
 
         // Can edit settings?
-        $can_edit = has_capability('moodle/course:update', context_course::instance($this->page->course->id));
+        $can_edit = has_capability('moodle/course:update', $context);
 
         // Get course completion data
-        $info = new completion_info($this->page->course);
+        $info = new completion_info($course);
 
         // Don't display if completion isn't enabled!
         if (!completion_info::is_enabled_for_site()) {
@@ -84,9 +86,9 @@ class block_completionstatus extends block_base {
         // Check this user is enroled
         if (!$info->is_tracked_user($USER->id)) {
             // If not enrolled, but are can view the report:
-            if (has_capability('report/completion:view', context_course::instance($COURSE->id))) {
-                $this->content->text = '<a href="'.$CFG->wwwroot.'/report/completion/index.php?course='.$COURSE->id.
-                                       '">'.get_string('viewcoursereport', 'completion').'</a>';
+            if (has_capability('report/completion:view', $context)) {
+                $report = new moodle_url('/report/completion/index.php', array('course' => $course->id));
+                $this->content->text = '<a href="'.$report->out().'">'.get_string('viewcoursereport', 'completion').'</a>';
                 return $this->content;
             }
 
@@ -187,7 +189,7 @@ class block_completionstatus extends block_base {
         // Load course completion
         $params = array(
             'userid' => $USER->id,
-            'course' => $COURSE->id
+            'course' => $course->id
         );
         $ccompletion = new completion_completion($params);
 
@@ -221,7 +223,8 @@ class block_completionstatus extends block_base {
         $this->content->text .= $shtml.'</tbody></table>';
 
         // Display link to detailed view
-        $this->content->footer = '<br><a href="'.$CFG->wwwroot.'/blocks/completionstatus/details.php?course='.$COURSE->id.'">'.get_string('moredetails', 'completion').'</a>';
+        $details = new moodle_url('/blocks/completionstatus/details.php', array('course' => $course->id));
+        $this->content->footer = '<br><a href="'.$details->out().'">'.get_string('moredetails', 'completion').'</a>';
 
         return $this->content;
     }
index a71da02..bb1b051 100644 (file)
  *
  * @package    block
  * @subpackage completion
- * @copyright  2009 Catalyst IT Ltd
+ * @copyright  2009-2012 Catalyst IT Ltd
  * @author     Aaron Barnes <aaronb@catalyst.net.nz>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-require_once('../../config.php');
-require_once($CFG->libdir.'/completionlib.php');
-
-
-// TODO:  Make this page Moodle 2.0 compliant
+require_once(dirname(__FILE__).'/../../config.php');
+require_once("{$CFG->libdir}/completionlib.php");
 
 
 ///
 /// Load data
 ///
 $id = required_param('course', PARAM_INT);
-// User id
 $userid = optional_param('user', 0, PARAM_INT);
 
 // Load course
-$course = $DB->get_record('course', array('id' => $id));
+$course = $DB->get_record('course', array('id' => $id), '*', MUST_EXIST);
 
 // Load user
 if ($userid) {
@@ -76,21 +72,13 @@ if (!$can_view) {
 // Load completion data
 $info = new completion_info($course);
 
-$returnurl = "{$CFG->wwwroot}/course/view.php?id={$id}";
+$returnurl = new moodle_url('/course/view.php', array('id' => $id));
 
 // Don't display if completion isn't enabled!
 if (!$info->is_enabled()) {
     print_error('completionnotenabled', 'completion', $returnurl);
 }
 
-// Load criteria to display
-$completions = $info->get_completions($user->id);
-
-// Check if this course has any criteria
-if (empty($completions)) {
-    print_error('nocriteriaset', 'completion', $returnurl);
-}
-
 // Check this user is enroled
 if (!$info->is_tracked_user($user->id)) {
     if ($USER->id == $user->id) {
@@ -104,6 +92,7 @@ if (!$info->is_tracked_user($user->id)) {
 ///
 /// Display page
 ///
+$PAGE->set_context(context_course::instance($course->id));
 
 // Print header
 $page = get_string('completionprogressdetails', 'block_completionstatus');
@@ -111,7 +100,7 @@ $title = format_string($course->fullname) . ': ' . $page;
 
 $PAGE->navbar->add($page);
 $PAGE->set_pagelayout('standard');
-$PAGE->set_url('/blocks/completionstatus/details.php', array('course' => $course->id));
+$PAGE->set_url('/blocks/completionstatus/details.php', array('course' => $course->id, 'user' => $user->id));
 $PAGE->set_title(get_string('course') . ': ' . $course->fullname);
 $PAGE->set_heading($title);
 echo $OUTPUT->header();
@@ -135,122 +124,148 @@ $coursecomplete = $info->is_course_complete($user->id);
 // Has this user completed any criteria?
 $criteriacomplete = $info->count_course_user_data($user->id);
 
+// Load course completion
+$params = array(
+    'userid' => $user->id,
+    'course' => $course->id,
+);
+$ccompletion = new completion_completion($params);
+
 if ($coursecomplete) {
     echo get_string('complete');
-} else if (!$criteriacomplete) {
+} else if (!$criteriacomplete && !$ccompletion->timestarted) {
     echo '<i>'.get_string('notyetstarted', 'completion').'</i>';
 } else {
     echo '<i>'.get_string('inprogress','completion').'</i>';
 }
 
 echo '</td></tr>';
-echo '<tr><td colspan="2"><b>'.get_string('required').':</b> ';
 
-// Get overall aggregation method
-$overall = $info->get_aggregation_method();
+// Load criteria to display
+$completions = $info->get_completions($user->id);
 
-if ($overall == COMPLETION_AGGREGATION_ALL) {
-    echo get_string('criteriarequiredall', 'completion');
+// Check if this course has any criteria
+if (empty($completions)) {
+    echo '<tr><td colspan="2"><br />';
+    echo $OUTPUT->box(get_string('err_nocriteria', 'completion'), 'noticebox');
+    echo '</td></tr></tbody></table>';
 } else {
-    echo get_string('criteriarequiredany', 'completion');
-}
+    echo '<tr><td colspan="2"><b>'.get_string('required').':</b> ';
 
-echo '</td></tr></tbody></table>';
-
-// Generate markup for criteria statuses
-echo '<table class="generalbox boxaligncenter" cellpadding="3"><tbody>';
-echo '<tr class="ccheader">';
-echo '<th class="c0 header" scope="col">'.get_string('criteriagroup', 'block_completionstatus').'</th>';
-echo '<th class="c1 header" scope="col">'.get_string('criteria', 'completion').'</th>';
-echo '<th class="c2 header" scope="col">'.get_string('requirement', 'block_completionstatus').'</th>';
-echo '<th class="c3 header" scope="col">'.get_string('status').'</th>';
-echo '<th class="c4 header" scope="col">'.get_string('complete').'</th>';
-echo '<th class="c5 header" scope="col">'.get_string('completiondate', 'report_completion').'</th>';
-echo '</tr>';
-
-// Save row data
-$rows = array();
-
-global $COMPLETION_CRITERIA_TYPES;
-
-// Loop through course criteria
-foreach ($completions as $completion) {
-    $criteria = $completion->get_criteria();
-    $complete = $completion->is_complete();
-
-    $row = array();
-    $row['type'] = $criteria->criteriatype;
-    $row['title'] = $criteria->get_title();
-    $row['status'] = $completion->get_status();
-    $row['timecompleted'] = $completion->timecompleted;
-    $row['details'] = $criteria->get_details($completion);
-    $rows[] = $row;
-}
+    // Get overall aggregation method
+    $overall = $info->get_aggregation_method();
 
-// Print table
-$last_type = '';
-$agg_type = false;
+    if ($overall == COMPLETION_AGGREGATION_ALL) {
+        echo get_string('criteriarequiredall', 'completion');
+    } else {
+        echo get_string('criteriarequiredany', 'completion');
+    }
+
+    echo '</td></tr></tbody></table>';
+
+    // Generate markup for criteria statuses
+    echo '<table class="generalbox logtable boxaligncenter" id="criteriastatus" width="100%"><tbody>';
+    echo '<tr class="ccheader">';
+    echo '<th class="c0 header" scope="col">'.get_string('criteriagroup', 'block_completionstatus').'</th>';
+    echo '<th class="c1 header" scope="col">'.get_string('criteria', 'completion').'</th>';
+    echo '<th class="c2 header" scope="col">'.get_string('requirement', 'block_completionstatus').'</th>';
+    echo '<th class="c3 header" scope="col">'.get_string('status').'</th>';
+    echo '<th class="c4 header" scope="col">'.get_string('complete').'</th>';
+    echo '<th class="c5 header" scope="col">'.get_string('completiondate', 'report_completion').'</th>';
+    echo '</tr>';
 
-foreach ($rows as $row) {
+    // Save row data
+    $rows = array();
+
+    // Loop through course criteria
+    foreach ($completions as $completion) {
+        $criteria = $completion->get_criteria();
+
+        $row = array();
+        $row['type'] = $criteria->criteriatype;
+        $row['title'] = $criteria->get_title();
+        $row['status'] = $completion->get_status();
+        $row['complete'] = $completion->is_complete();
+        $row['timecompleted'] = $completion->timecompleted;
+        $row['details'] = $criteria->get_details($completion);
+        $rows[] = $row;
+    }
 
-    // Criteria group
-    echo '<td class="c0">';
-    if ($last_type !== $row['details']['type']) {
-        $last_type = $row['details']['type'];
-        echo $last_type;
+    // Print table
+    $last_type = '';
+    $agg_type = false;
+    $oddeven = 0;
 
-        // Reset agg type
-        $agg_type = true;
-    } else {
-        // Display aggregation type
-        if ($agg_type) {
-            $agg = $info->get_aggregation_method($row['type']);
+    foreach ($rows as $row) {
 
-            echo '(<i>';
+        echo '<tr class="r' . $oddeven . '">';
 
-            if ($agg == COMPLETION_AGGREGATION_ALL) {
-                echo strtolower(get_string('all', 'completion'));
-            } else {
-                echo strtolower(get_string('any', 'completion'));
-            }
+        // Criteria group
+        echo '<td class="cell c0">';
+        if ($last_type !== $row['details']['type']) {
+            $last_type = $row['details']['type'];
+            echo $last_type;
+
+            // Reset agg type
+            $agg_type = true;
+        } else {
+            // Display aggregation type
+            if ($agg_type) {
+                $agg = $info->get_aggregation_method($row['type']);
 
-            echo '</i> '.strtolower(get_string('required')).')';
-            $agg_type = false;
+                echo '(<i>';
+
+                if ($agg == COMPLETION_AGGREGATION_ALL) {
+                    echo strtolower(get_string('aggregateall', 'completion'));
+                } else {
+                    echo strtolower(get_string('aggregateany', 'completion'));
+                }
+
+                echo '</i> '.strtolower(get_string('required')).')';
+                $agg_type = false;
+            }
         }
+        echo '</td>';
+
+        // Criteria title
+        echo '<td class="cell c1">';
+        echo $row['details']['criteria'];
+        echo '</td>';
+
+        // Requirement
+        echo '<td class="cell c2">';
+        echo $row['details']['requirement'];
+        echo '</td>';
+
+        // Status
+        echo '<td class="cell c3">';
+        echo $row['details']['status'];
+        echo '</td>';
+
+        // Is complete
+        echo '<td class="cell c4">';
+        echo $row['complete'] ? get_string('yes') : get_string('no');
+        echo '</td>';
+
+        // Completion data
+        echo '<td class="cell c5">';
+        if ($row['timecompleted']) {
+            echo userdate($row['timecompleted'], get_string('strftimedate', 'langconfig'));
+        } else {
+            echo '-';
+        }
+        echo '</td>';
+        echo '</tr>';
+        // for row striping
+        $oddeven = $oddeven ? 0 : 1;
     }
-    echo '</td>';
-
-    // Criteria title
-    echo '<td class="c1">';
-    echo $row['details']['criteria'];
-    echo '</td>';
-
-    // Requirement
-    echo '<td class="c2">';
-    echo $row['details']['requirement'];
-    echo '</td>';
-
-    // Status
-    echo '<td class="c3">';
-    echo $row['details']['status'];
-    echo '</td>';
-
-    // Is complete
-    echo '<td class="c4">';
-    echo ($row['status'] === get_string('yes')) ? get_string('yes') : get_string('no');
-    echo '</td>';
-
-    // Completion data
-    echo '<td class="c5">';
-    if ($row['timecompleted']) {
-        echo userdate($row['timecompleted'], '%e %B %G');
-    } else {
-        echo '-';
-    }
-    echo '</td>';
-    echo '</tr>';
+
+    echo '</tbody></table>';
 }
 
-echo '</tbody></table>';
+echo '<div class="buttons">';
+$courseurl = new moodle_url("/course/view.php", array('id' => $course->id));
+echo $OUTPUT->single_button($courseurl, get_string('returntocourse', 'block_completionstatus'), 'get');
+echo '</div>';
 
 echo $OUTPUT->footer();
index fcc965a..6658c17 100644 (file)
@@ -5,3 +5,4 @@ $string['criteriagroup'] = 'Criteria group';
 $string['firstofsecond'] = '{$a->first} of {$a->second}';
 $string['pluginname'] = 'Course completion status';
 $string['requirement'] = 'Requirement';
+$string['returntocourse'] = 'Return to course';
index 9380fa2..169c54d 100644 (file)
@@ -87,7 +87,7 @@ class block_edit_form extends moodleform {
 
         $regionoptions = $this->page->theme->get_all_block_regions();
 
-        $parentcontext = get_context_instance_by_id($this->block->instance->parentcontextid);
+        $parentcontext = context::instance_by_id($this->block->instance->parentcontextid);
         $mform->addElement('hidden', 'bui_parentcontextid', $parentcontext->id);
 
         $mform->addElement('static', 'bui_homecontext', get_string('createdat', 'block'), print_context_name($parentcontext));
index 39040ae..67b108f 100644 (file)
@@ -29,6 +29,10 @@ class block_html extends block_base {
         $this->title = get_string('pluginname', 'block_html');
     }
 
+    function has_config() {
+        return true;
+    }
+
     function applicable_formats() {
         return array('all' => true);
     }
@@ -104,7 +108,7 @@ class block_html extends block_base {
     function content_is_trusted() {
         global $SCRIPT;
 
-        if (!$context = get_context_instance_by_id($this->instance->parentcontextid)) {
+        if (!$context = context::instance_by_id($this->instance->parentcontextid, IGNORE_MISSING)) {
             return false;
         }
         //find out if this block is on the profile page
@@ -138,10 +142,14 @@ class block_html extends block_base {
      * @return array
      */
     function html_attributes() {
+        global $CFG;
+
         $attributes = parent::html_attributes();
 
-        if (!empty($this->config->classes)) {
-            $attributes['class'] .= ' '.$this->config->classes;
+        if (!empty($CFG->block_html_allowcssclasses)) {
+            if (!empty($this->config->classes)) {
+                $attributes['class'] .= ' '.$this->config->classes;
+            }
         }
 
         return $attributes;
index f544f98..edb5705 100644 (file)
@@ -31,6 +31,8 @@
  */
 class block_html_edit_form extends block_edit_form {
     protected function specific_definition($mform) {
+        global $CFG;
+
         // Fields for editing HTML block title and contents.
         $mform->addElement('header', 'configheader', get_string('blocksettings', 'block'));
 
@@ -42,9 +44,11 @@ class block_html_edit_form extends block_edit_form {
         $mform->addRule('config_text', null, 'required', null, 'client');
         $mform->setType('config_text', PARAM_RAW); // XSS is prevented when printing the block contents and serving files
 
-        $mform->addElement('text', 'config_classes', get_string('configclasses', 'block_html'));
-        $mform->setType('config_classes', PARAM_TEXT);
-        $mform->addHelpButton('config_classes', 'configclasses', 'block_html');
+        if (!empty($CFG->block_html_allowcssclasses)) {
+            $mform->addElement('text', 'config_classes', get_string('configclasses', 'block_html'));
+            $mform->setType('config_classes', PARAM_TEXT);
+            $mform->addHelpButton('config_classes', 'configclasses', 'block_html');
+        }
     }
 
     function set_data($defaults) {
index 6e82be8..d331059 100644 (file)
@@ -23,7 +23,9 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['configclasses'] = 'Additional HTML classes';
+$string['allowadditionalcssclasses'] = 'Allow additional CSS classes';
+$string['configallowadditionalcssclasses'] = 'Adds a configuration option to HTML block instances allowing additional CSS classes to be set.';
+$string['configclasses'] = 'Additional CSS classes';
 $string['configclasses_help'] = 'The purpose of this configuration is to aid with theming by helping distinguish HTML blocks from each other. Any CSS classes entered here (space delimited) will be appended to the block\'s default classes.';
 $string['configcontent'] = 'Content';
 $string['configtitle'] = 'Block title';
index a2555c3..03d58ca 100644 (file)
@@ -53,7 +53,7 @@ function block_html_pluginfile($course, $birecord_or_cm, $context, $filearea, $a
         send_file_not_found();
     }
 
-    if ($parentcontext = get_context_instance_by_id($birecord_or_cm->parentcontextid)) {
+    if ($parentcontext = context::instance_by_id($birecord_or_cm->parentcontextid, IGNORE_MISSING)) {
         if ($parentcontext->contextlevel == CONTEXT_USER) {
             // force download on all personal pages including /my/
             //because we do not have reliable way to find out from where this is used
diff --git a/blocks/html/settings.php b/blocks/html/settings.php
new file mode 100644 (file)
index 0000000..59cb797
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+
+defined('MOODLE_INTERNAL') || die;
+
+if ($ADMIN->fulltree) {
+    $settings->add(new admin_setting_configcheckbox('block_html_allowcssclasses', get_string('allowadditionalcssclasses', 'block_html'),
+                       get_string('configallowadditionalcssclasses', 'block_html'), 0));
+}
+
+
index d18af55..8795a68 100644 (file)
@@ -65,7 +65,7 @@ class block_quiz_results extends block_base {
         if (empty($this->instance->parentcontextid)) {
             return 0;
         }
-        $parentcontext = get_context_instance_by_id($this->instance->parentcontextid);
+        $parentcontext = context::instance_by_id($this->instance->parentcontextid);
         if ($parentcontext->contextlevel != CONTEXT_MODULE) {
             return 0;
         }
index 43b36af..9a07fba 100644 (file)
@@ -292,11 +292,10 @@ class blog_entry implements renderable {
      * @return void
      */
     public function delete() {
-        global $DB, $USER;
-
-        $returnurl = '';
+        global $DB;
 
         $this->delete_attachments();
+        $this->remove_associations();
 
         $DB->delete_records('post', array('id' => $this->id));
         tag_set('post', $this->id, array());
index b7f6589..5eaa2a7 100644 (file)
@@ -32,7 +32,7 @@ $id = required_param('id', PARAM_INT);
 require_login();
 
 $cohort = $DB->get_record('cohort', array('id'=>$id), '*', MUST_EXIST);
-$context = get_context_instance_by_id($cohort->contextid, MUST_EXIST);
+$context = context::instance_by_id($cohort->contextid, MUST_EXIST);
 
 require_capability('moodle/cohort:assign', $context);
 
index dc1bd08..721d790 100644 (file)
@@ -40,9 +40,9 @@ require_login();
 $category = null;
 if ($id) {
     $cohort = $DB->get_record('cohort', array('id'=>$id), '*', MUST_EXIST);
-    $context = get_context_instance_by_id($cohort->contextid, MUST_EXIST);
+    $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
 } else {
-    $context = get_context_instance_by_id($contextid, MUST_EXIST);
+    $context = context::instance_by_id($contextid, MUST_EXIST);
     if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
         print_error('invalidcontext');
     }
index 9576071..81e7a7c 100644 (file)
@@ -103,7 +103,7 @@ class cohort_edit_form extends moodleform {
         }
         // always add current - this is not likely, but if the logic gets changed it might be a problem
         if (!isset($options[$currentcontextid])) {
-            $context = get_context_instance_by_id($currentcontextid, MUST_EXIST);
+            $context = context::instance_by_id($currentcontextid, MUST_EXIST);
             $options[$context->id] = print_context_name($syscontext);
         }
         return $options;
index 026bcb8..00aab66 100644 (file)
@@ -35,7 +35,7 @@ $searchquery  = optional_param('search', '', PARAM_RAW);
 require_login();
 
 if ($contextid) {
-    $context = get_context_instance_by_id($contextid, MUST_EXIST);
+    $context = context::instance_by_id($contextid, MUST_EXIST);
 } else {
     $context = context_system::instance();
 }
index 223644b..67c2bf4 100644 (file)
@@ -155,6 +155,18 @@ function cohort_remove_member($cohortid, $userid) {
     events_trigger('cohort_member_removed', (object)array('cohortid'=>$cohortid, 'userid'=>$userid));
 }
 
+/**
+ * Is this user a cohort member?
+ * @param int $cohortid
+ * @param int $userid
+ * @return bool
+ */
+function cohort_is_member($cohortid, $userid) {
+    global $DB;
+
+    return $DB->record_exists('cohort_members', array('cohortid'=>$cohortid, 'userid'=>$userid));
+}
+
 /**
  * Returns list of visible cohorts in course.
  *
index 9bf2653..8954244 100644 (file)
@@ -120,7 +120,7 @@ class comment {
             $this->contextid = $this->context->id;
         } else if(!empty($options->contextid)) {
             $this->contextid = $options->contextid;
-            $this->context = get_context_instance_by_id($this->contextid);
+            $this->context = context::instance_by_id($this->contextid);
         } else {
             print_error('invalidcontext');
         }
index 5a8b0d7..c53fa80 100644 (file)
@@ -114,7 +114,7 @@ class comment_manager {
      */
     private function setup_plugin($comment) {
         global $DB;
-        $this->context = get_context_instance_by_id($comment->contextid);
+        $this->context = context::instance_by_id($comment->contextid, IGNORE_MISSING);
         if (!$this->context) {
             return false;
         }
index f27ff2a..73da8d3 100644 (file)
@@ -38,6 +38,7 @@ class editsection_form extends moodleform {
         $course = $this->_customdata['course'];
 
         if (!empty($CFG->enableavailability)) {
+            $mform->addElement('header', '', get_string('availabilityconditions', 'condition'));
             // String used by conditions more than once
             $strcondnone = get_string('none', 'condition');
             // Grouping conditions - only if grouping is enabled at site level
@@ -51,7 +52,6 @@ class editsection_form extends moodleform {
                                 $grouping->name, true, array('context' => $context));
                     }
                 }
-                $mform->addElement('header', '', get_string('availabilityconditions', 'condition'));
                 $mform->addElement('select', 'groupingid', get_string('groupingsection', 'group'), $options);
                 $mform->addHelpButton('groupingid', 'groupingsection', 'group');
             }
index 75cc734..cf8f372 100644 (file)
@@ -531,10 +531,19 @@ function print_mnet_log($hostid, $course, $user=0, $date=0, $order="l.time ASC",
 
 function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
                         $modid, $modaction, $groupid) {
-    global $DB;
+    global $DB, $CFG;
+
+    require_once($CFG->libdir . '/csvlib.class.php');
 
-    $text = get_string('course')."\t".get_string('time')."\t".get_string('ip_address')."\t".
-            get_string('fullnameuser')."\t".get_string('action')."\t".get_string('info');
+    $csvexporter = new csv_export_writer('tab');
+
+    $header = array();
+    $header[] = get_string('course');
+    $header[] = get_string('time');
+    $header[] = get_string('ip_address');
+    $header[] = get_string('fullnameuser');
+    $header[] = get_string('action');
+    $header[] = get_string('info');
 
     if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
                        $modname, $modid, $modaction, $groupid)) {
@@ -561,16 +570,10 @@ function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
 
     $strftimedatetime = get_string("strftimedatetime");
 
-    $filename = 'logs_'.userdate(time(),get_string('backupnameformat', 'langconfig'),99,false);
-    $filename .= '.txt';
-    header("Content-Type: application/download\n");
-    header("Content-Disposition: attachment; filename=\"$filename\"");
-    header("Expires: 0");
-    header("Cache-Control: must-revalidate,post-check=0,pre-check=0");
-    header("Pragma: public");
-
-    echo get_string('savedat').userdate(time(), $strftimedatetime)."\n";
-    echo $text."\n";
+    $csvexporter->set_filename('logs', '.txt');
+    $title = array(get_string('savedat').userdate(time(), $strftimedatetime));
+    $csvexporter->add_data($title);
+    $csvexporter->add_data($header);
 
     if (empty($logs['logs'])) {
         return true;
@@ -600,9 +603,9 @@ function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
         $firstField = format_string($courses[$log->course], true, array('context' => $coursecontext));
         $fullname = fullname($log, has_capability('moodle/site:viewfullnames', $coursecontext));
         $row = array($firstField, userdate($log->time, $strftimedatetime), $log->ip, $fullname, $log->module.' '.$log->action, $log->info);
-        $text = implode("\t", $row);
-        echo $text." \n";
+        $csvexporter->add_data($row);
     }
+    $csvexporter->download_file();
     return true;
 }
 
index 751c0c7..020edd0 100644 (file)
@@ -61,13 +61,13 @@ class course_reset_form extends moodleform {
         if ($allmods = $DB->get_records('modules') ) {
             foreach ($allmods as $mod) {
                 $modname = $mod->name;
-                if (!$DB->count_records($modname, array('course'=>$COURSE->id))) {
-                    continue; // skip mods with no instances
-                }
                 $modfile = $CFG->dirroot."/mod/$modname/lib.php";
                 $mod_reset_course_form_definition = $modname.'_reset_course_form_definition';
                 $mod_reset__userdata = $modname.'_reset_userdata';
                 if (file_exists($modfile)) {
+                    if (!$DB->count_records($modname, array('course'=>$COURSE->id))) {
+                        continue; // Skip mods with no instances
+                    }
                     include_once($modfile);
                     if (function_exists($mod_reset_course_form_definition)) {
                         $mod_reset_course_form_definition($mform);
index ede5706..821ae57 100644 (file)
@@ -61,7 +61,7 @@ if ($component !== 'user' or $filearea !== 'draft') {
     send_file_not_found();
 }
 
-$context = get_context_instance_by_id($contextid);
+$context = context::instance_by_id($contextid);
 if ($context->contextlevel != CONTEXT_USER) {
     send_file_not_found();
 }
index 67ae497..ede3c5a 100644 (file)
@@ -63,7 +63,7 @@ switch ($action) {
     case 'unenrol':
         $ue = $DB->get_record('user_enrolments', array('id'=>required_param('ue', PARAM_INT)), '*', MUST_EXIST);
         list ($instance, $plugin) = $manager->get_user_enrolment_components($ue);
-        if (!$instance || !$plugin || !$plugin->allow_unenrol_user($instance, $ue) || !has_capability("enrol/$instance->enrol:unenrol", $manager->get_context()) || !$manager->unenrol_user($ue)) {
+        if (!$instance || !$plugin || !enrol_is_enabled($instance->enrol) || !$plugin->allow_unenrol_user($instance, $ue) || !has_capability("enrol/$instance->enrol:unenrol", $manager->get_context()) || !$manager->unenrol_user($ue)) {
             throw new enrol_ajax_exception('unenrolnotpermitted');
         }
         break;
index 2c16f76..9e4ab0c 100644 (file)
@@ -45,8 +45,8 @@ class enrol_category_handler {
             return true;
         }
 
-        // Only category level roles are interesting.
-        $parentcontext = get_context_instance_by_id($ra->contextid);
+        //only category level roles are interesting
+        $parentcontext = context::instance_by_id($ra->contextid);
         if ($parentcontext->contextlevel != CONTEXT_COURSECAT) {
             return true;
         }
@@ -102,8 +102,8 @@ class enrol_category_handler {
             return true;
         }
 
-        // Only category level roles are interesting.
-        $parentcontext = get_context_instance_by_id($ra->contextid);
+        // only category level roles are interesting
+        $parentcontext = context::instance_by_id($ra->contextid);
         if ($parentcontext->contextlevel != CONTEXT_COURSECAT) {
             return true;
         }
index e9015a2..c209493 100644 (file)
@@ -46,7 +46,7 @@ class enrol_cohort_addinstance_form extends moodleform {
               ORDER BY name ASC";
         $rs = $DB->get_recordset_sql($sql, $params);
         foreach ($rs as $c) {
-            $context = get_context_instance_by_id($c->contextid);
+            $context = context::instance_by_id($c->contextid);
             if (!has_capability('moodle/cohort:view', $context)) {
                 continue;
             }
index b70b89f..4ad304e 100644 (file)
@@ -92,7 +92,7 @@ class enrol_cohort_plugin extends enrol_plugin {
               ORDER BY name ASC";
         $cohorts = $DB->get_records_sql($sql, $params);
         foreach ($cohorts as $c) {
-            $context = get_context_instance_by_id($c->contextid);
+            $context = context::instance_by_id($c->contextid);
             if (has_capability('moodle/cohort:view', $context)) {
                 return true;
             }
index 5ca237a..869e06c 100644 (file)
@@ -368,7 +368,7 @@ function enrol_cohort_get_cohorts(course_enrolment_manager $manager) {
           ORDER BY name ASC";
     $rs = $DB->get_recordset_sql($sql, $params);
     foreach ($rs as $c) {
-        $context = get_context_instance_by_id($c->contextid);
+        $context = context::instance_by_id($c->contextid);
         if (!has_capability('moodle/cohort:view', $context)) {
             continue;
         }
@@ -394,7 +394,7 @@ function enrol_cohort_can_view_cohort($cohortid) {
     global $DB;
     $cohort = $DB->get_record('cohort', array('id' => $cohortid), 'id, contextid');
     if ($cohort) {
-        $context = get_context_instance_by_id($cohort->contextid);
+        $context = context::instance_by_id($cohort->contextid);
         if (has_capability('moodle/cohort:view', $context)) {
             return true;
         }
@@ -457,7 +457,7 @@ function enrol_cohort_search_cohorts(course_enrolment_manager $manager, $offset
         // Track offset
         $offset++;
         // Check capabilities
-        $context = get_context_instance_by_id($c->contextid);
+        $context = context::instance_by_id($c->contextid);
         if (!has_capability('moodle/cohort:view', $context)) {
             continue;
         }
index 0fd4182..757362a 100644 (file)
@@ -381,7 +381,7 @@ class core_role_external extends external_api {
 
         foreach ($params['assignments'] as $assignment) {
             // Ensure the current user is allowed to run this function in the enrolment context
-            $context = get_context_instance_by_id($assignment['contextid']);
+            $context = context::instance_by_id($assignment['contextid'], IGNORE_MISSING);
             self::validate_context($context);
             require_capability('moodle/role:assign', $context);
 
@@ -445,7 +445,7 @@ class core_role_external extends external_api {
 
         foreach ($params['unassignments'] as $unassignment) {
             // Ensure the current user is allowed to run this function in the unassignment context
-            $context = get_context_instance_by_id($unassignment['contextid']);
+            $context = context::instance_by_id($unassignment['contextid'], IGNORE_MISSING);
             self::validate_context($context);
             require_capability('moodle/role:assign', $context);
 
index 81f9e4c..0e00925 100644 (file)
@@ -702,7 +702,8 @@ function process_membership_tag($tagcontents){
                         }
                         // Add the user-to-group association if it doesn't already exist
                         if($member->groupid) {
-                            groups_add_member($member->groupid, $memberstoreobj->userid);
+                            groups_add_member($member->groupid, $memberstoreobj->userid,
+                                    'enrol_imsenterprise', $einstance->id);
                         }
                     } // End of group-enrolment (from member.role.extension.cohort tag)
 
@@ -793,6 +794,19 @@ function load_role_mappings() {
     }
 }
 
+    /**
+     * Called whenever anybody tries (from the normal interface) to remove a group
+     * member which is registered as being created by this component. (Not called
+     * when deleting an entire group or course at once.)
+     * @param int $itemid Item ID that was stored in the group_members entry
+     * @param int $groupid Group ID
+     * @param int $userid User ID being removed from group
+     * @return bool True if the remove is permitted, false to give an error
+     */
+    function enrol_imsenterprise_allow_group_member_remove($itemid, $groupid, $userid) {
+        return false;
+    }
+
 } // end of class
 
 
index b19a716..596320a 100644 (file)
@@ -97,6 +97,7 @@ class course_enrolment_manager {
     private $_instances = null;
     private $_inames = null;
     private $_plugins = null;
+    private $_allplugins = null;
     private $_roles = null;
     private $_assignableroles = null;
     private $_assignablerolesothers = null;
@@ -397,11 +398,13 @@ class course_enrolment_manager {
     /**
      * Returns all of the enrolment instances for this course.
      *
+     * NOTE: since 2.4 it includes instances of disabled plugins too.
+     *
      * @return array
      */
     public function get_enrolment_instances() {
         if ($this->_instances === null) {
-            $this->_instances = enrol_get_instances($this->course->id, true);
+            $this->_instances = enrol_get_instances($this->course->id, false);
         }
         return $this->_instances;
     }
@@ -409,12 +412,14 @@ class course_enrolment_manager {
     /**
      * Returns the names for all of the enrolment instances for this course.
      *
+     * NOTE: since 2.4 it includes instances of disabled plugins too.
+     *
      * @return array
      */
     public function get_enrolment_instance_names() {
         if ($this->_inames === null) {
             $instances = $this->get_enrolment_instances();
-            $plugins = $this->get_enrolment_plugins();
+            $plugins = $this->get_enrolment_plugins(false);
             foreach ($instances as $key=>$instance) {
                 if (!isset($plugins[$instance->enrol])) {
                     // weird, some broken stuff in plugin
@@ -430,13 +435,29 @@ class course_enrolment_manager {
     /**
      * Gets all of the enrolment plugins that are active for this course.
      *
+     * @param bool $onlyenabled return only enabled enrol plugins
      * @return array
      */
-    public function get_enrolment_plugins() {
+    public function get_enrolment_plugins($onlyenabled = true) {
         if ($this->_plugins === null) {
             $this->_plugins = enrol_get_plugins(true);
         }
-        return $this->_plugins;
+
+        if ($onlyenabled) {
+            return $this->_plugins;
+        }
+
+        if ($this->_allplugins === null) {
+            // Make sure we have the same objects in _allplugins and _plugins.
+            $this->_allplugins = $this->_plugins;
+            foreach (enrol_get_plugins(false) as $name=>$plugin) {
+                if (!isset($this->_allplugins[$name])) {
+                    $this->_allplugins[$name] = $plugin;
+                }
+            }
+        }
+
+        return $this->_allplugins;
     }
 
     /**
@@ -522,7 +543,7 @@ class course_enrolment_manager {
             $userenrolment = $DB->get_record('user_enrolments', array('id'=>(int)$userenrolment));
         }
         $instances = $this->get_enrolment_instances();
-        $plugins = $this->get_enrolment_plugins();
+        $plugins = $this->get_enrolment_plugins(false);
         if (!$userenrolment || !isset($instances[$userenrolment->enrolid])) {
             return array(false, false);
         }
@@ -675,7 +696,7 @@ class course_enrolment_manager {
     }
 
     /**
-     * Gets the enrolments this user has in the course
+     * Gets the enrolments this user has in the course - including all suspended plugins and instances.
      *
      * @global moodle_database $DB
      * @param int $userid
@@ -687,7 +708,7 @@ class course_enrolment_manager {
         $params['userid'] = $userid;
         $userenrolments = $DB->get_records_select('user_enrolments', "enrolid $instancessql AND userid = :userid", $params);
         $instances = $this->get_enrolment_instances();
-        $plugins = $this->get_enrolment_plugins();
+        $plugins = $this->get_enrolment_plugins(false);
         $inames = $this->get_enrolment_instance_names();
         foreach ($userenrolments as &$ue) {
             $ue->enrolmentinstance     = $instances[$ue->enrolid];
@@ -829,6 +850,8 @@ class course_enrolment_manager {
         $url = new moodle_url($pageurl, $this->get_url_params());
         $extrafields = get_extra_user_fields($context);
 
+        $enabledplugins = $this->get_enrolment_plugins(true);
+
         $userdetails = array();
         foreach ($users as $user) {
             $details = $this->prepare_user_for_display($user, $extrafields, $now);
@@ -849,7 +872,15 @@ class course_enrolment_manager {
             // Enrolments
             $details['enrolments'] = array();
             foreach ($this->get_user_enrolments($user->id) as $ue) {
-                if ($ue->timestart and $ue->timeend) {
+                if (!isset($enabledplugins[$ue->enrolmentinstance->enrol])) {
+                    $details['enrolments'][$ue->id] = array(
+                        'text' => $ue->enrolmentinstancename,
+                        'period' => null,
+                        'dimmed' =>  true,
+                        'actions' => array()
+                    );
+                    continue;
+                } else if ($ue->timestart and $ue->timeend) {
                     $period = get_string('periodstartend', 'enrol', array('start'=>userdate($ue->timestart), 'end'=>userdate($ue->timeend)));
                     $periodoutside = ($ue->timestart && $ue->timeend && $now < $ue->timestart && $now > $ue->timeend);
                 } else if ($ue->timestart) {
@@ -909,7 +940,7 @@ class course_enrolment_manager {
     }
 
     public function get_manual_enrol_buttons() {
-        $plugins = $this->get_enrolment_plugins();
+        $plugins = $this->get_enrolment_plugins(true); // Skip disabled plugins.
         $buttons = array();
         foreach ($plugins as $plugin) {
             $newbutton = $plugin->get_manual_enrol_button($this);
@@ -941,7 +972,7 @@ class course_enrolment_manager {
      */
     public function get_filtered_enrolment_plugin() {
         $instances = $this->get_enrolment_instances();
-        $plugins = $this->get_enrolment_plugins();
+        $plugins = $this->get_enrolment_plugins(false);
 
         if (empty($this->instancefilter) || !array_key_exists($this->instancefilter, $instances)) {
             return false;
@@ -965,7 +996,7 @@ class course_enrolment_manager {
         global $DB;
 
         $instances = $this->get_enrolment_instances();
-        $plugins = $this->get_enrolment_plugins();
+        $plugins = $this->get_enrolment_plugins(false);
 
         if  (!empty($this->instancefilter)) {
             $instancesql = ' = :instanceid';
index 140b4cd..faf8ac0 100644 (file)
@@ -20,8 +20,7 @@
  * The general idea behind this file is that any errors should throw exceptions
  * which will be returned and acted upon by the calling AJAX script.
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2010 Sam Hemelryk
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -32,8 +31,7 @@ require('../../config.php');
 require_once($CFG->dirroot.'/enrol/locallib.php');
 require_once($CFG->dirroot.'/group/lib.php');
 
-// Must have the sesskey
-$id      = required_param('id', PARAM_INT); // course id
+$id      = required_param('id', PARAM_INT); // Course id.
 $action  = required_param('action', PARAM_ALPHANUMEXT);
 
 $PAGE->set_url(new moodle_url('/enrol/ajax.php', array('id'=>$id, 'action'=>$action)));
@@ -49,7 +47,7 @@ require_login($course);
 require_capability('moodle/course:enrolreview', $context);
 require_sesskey();
 
-echo $OUTPUT->header(); // send headers
+echo $OUTPUT->header(); // Send headers.
 
 $manager = new course_enrolment_manager($PAGE, $course);
 
@@ -113,11 +111,14 @@ switch ($action) {
 
         $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
         $instances = $manager->get_enrolment_instances();
-        $plugins = $manager->get_enrolment_plugins();
+        $plugins = $manager->get_enrolment_plugins(true); // Do not allow actions on disabled plugins.
         if (!array_key_exists($enrolid, $instances)) {
             throw new enrol_ajax_exception('invalidenrolinstance');
         }
         $instance = $instances[$enrolid];
+        if (!isset($plugins[$instance->enrol])) {
+            throw new enrol_ajax_exception('enrolnotpermitted');
+        }
         $plugin = $plugins[$instance->enrol];
         if ($plugin->allow_enrol($instance) && has_capability('enrol/'.$plugin->get_name().':enrol', $context)) {
             $plugin->enrol_user($instance, $user->id, $roleid, $timestart, $timeend);
@@ -135,4 +136,4 @@ switch ($action) {
         throw new enrol_ajax_exception('unknowajaxaction');
 }
 
-echo json_encode($outcome);
\ No newline at end of file
+echo json_encode($outcome);
index 8ee7300..05980e6 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * This file contains form for bulk changing user enrolments.
  *
- * @package    core
- * @subpackage enrol
+ * @package    enrol_manual
  * @copyright  2011 Sam Hemelryk
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -29,7 +27,7 @@ defined('MOODLE_INTERNAL') || die();
 require_once("$CFG->dirroot/enrol/bulkchange_forms.php");
 
 /**
- * The form to collect required information when bulk editing users enrolments
+ * The form to collect required information when bulk editing users enrolments.
  *
  * @copyright 2011 Sam Hemelryk
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
index 561ef29..5f14032 100644 (file)
@@ -26,6 +26,7 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
+    /* Add, edit or remove manual enrol instance. */
     'enrol/manual:config' => array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_COURSE,
@@ -34,6 +35,7 @@ $capabilities = array(
         )
     ),
 
+    /* Enrol anybody. */
     'enrol/manual:enrol' => array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_COURSE,
@@ -43,6 +45,7 @@ $capabilities = array(
         )
     ),
 
+    /* Manage enrolments of users. */
     'enrol/manual:manage' => array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_COURSE,
@@ -52,6 +55,7 @@ $capabilities = array(
         )
     ),
 
+    /* Unenrol anybody (including self) - watch out for data loss. */
     'enrol/manual:unenrol' => array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_COURSE,
@@ -61,6 +65,7 @@ $capabilities = array(
         )
     ),
 
+    /* Unenrol self - watch out for data loss. */
     'enrol/manual:unenrolself' => array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_COURSE,
@@ -69,4 +74,3 @@ $capabilities = array(
     ),
 
 );
-
index 3d99542..9958435 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Manual enrol plugin installation script
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2010 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 978a6eb..c4ff53d 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -19,8 +18,7 @@
  * Adds new instance of enrol_manual to specified course
  * or edits current instance.
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2010 Petr Skoda  {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -49,14 +47,14 @@ $plugin = enrol_get_plugin('manual');
 if ($instances = $DB->get_records('enrol', array('courseid'=>$course->id, 'enrol'=>'manual'), 'id ASC')) {
     $instance = array_shift($instances);
     if ($instances) {
-        // oh - we allow only one instance per course!!
+        // Oh - we allow only one instance per course!!
         foreach ($instances as $del) {
             $plugin->delete_instance($del);
         }
     }
 } else {
     require_capability('moodle/course:enrolconfig', $context);
-    // no instance yet, we have to add new instance
+    // No instance yet, we have to add new instance.
     navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id)));
     $instance = new stdClass();
     $instance->id       = null;
index 7ff2792..eb21099 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -19,8 +18,7 @@
  * Adds new instance of enrol_manual to specified course
  * or edits current instance.
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2010 Petr Skoda  {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -62,4 +60,4 @@ class enrol_manual_edit_form extends moodleform {
 
         $this->set_data($instance);
     }
-}
\ No newline at end of file
+}
index 2d8a700..538f458 100644 (file)
  * This page allows the current user to edit a manual user enrolment.
  * It is not compatible with the frontpage.
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2011 Sam Hemelryk
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 require('../../config.php');
 require_once("$CFG->dirroot/enrol/locallib.php");
-require_once("$CFG->dirroot/enrol/renderer.php"); // Required for the course enrolment manager table
+require_once("$CFG->dirroot/enrol/renderer.php"); // Required for the course enrolment manager table.
 require_once("$CFG->dirroot/enrol/manual/editenrolment_form.php");
 
-$ueid   = required_param('ue', PARAM_INT); // user enrolment id
+$ueid   = required_param('ue', PARAM_INT); // User enrolment id.
 $filter = optional_param('ifilter', 0, PARAM_INT);
 
-// Get the user enrolment object
-$ue     = $DB->get_record('user_enrolments', array('id' => $ueid), '*', MUST_EXIST);
-// Get the user for whom the enrolment is
-$user   = $DB->get_record('user', array('id'=>$ue->userid), '*', MUST_EXIST);
-// Get the course the enrolment is to
-list($ctxsql, $ctxjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
-$sql = "SELECT c.* $ctxsql
+// Get the user enrolment object.
+$ue = $DB->get_record('user_enrolments', array('id' => $ueid), '*', MUST_EXIST);
+// Get the user for whom the enrolment is.
+$user = $DB->get_record('user', array('id'=>$ue->userid), '*', MUST_EXIST);
+// Get the course the enrolment is to.
+$sql = "SELECT c.*
           FROM {course} c
-     LEFT JOIN {enrol} e ON e.courseid = c.id
-               $ctxjoin
+          JOIN {enrol} e ON e.courseid = c.id
          WHERE e.id = :enrolid";
 $params = array('enrolid' => $ue->enrolid);
 $course = $DB->get_record_sql($sql, $params, MUST_EXIST);
-context_instance_preload($course);
 
-// Make sure its not the front page course
+// Make sure its not the front page course.
 if ($course->id == SITEID) {
     redirect(new moodle_url('/'));
 }
 
-// Obviously
+// Obviously.
 require_login($course);
-// Make sure the user can manage manual enrolments for this course
+// Make sure the user can manage manual enrolments for this course.
 require_capability("enrol/manual:manage", context_course::instance($course->id, MUST_EXIST));
 
-// Get the enrolment manager for this course
+// Get the enrolment manager for this course.
 $manager = new course_enrolment_manager($PAGE, $course, $filter);
 // Get an enrolment users table object. Doign this will automatically retrieve the the URL params
 // relating to table the user was viewing before coming here, and allows us to return the user to the
@@ -70,7 +66,7 @@ $table = new course_enrolment_users_table($manager, $PAGE);
 $usersurl = new moodle_url('/enrol/users.php', array('id' => $course->id));
 // The URl to return the user too after this screen.
 $returnurl = new moodle_url($usersurl, $manager->get_url_params()+$table->get_url_params());
-// The URL of this page
+// The URL of this page.
 $url = new moodle_url('/enrol/manual/editenrolment.php', $returnurl->params());
 
 $PAGE->set_url($url);
@@ -88,9 +84,7 @@ $mform->set_data($PAGE->url->params());
 // Check the form hasn't been cancelled
 if ($mform->is_cancelled()) {
     redirect($returnurl);
-} else if ($mform->is_submitted() && $mform->is_validated() && confirm_sesskey()) {
-    // The forms been submit, validated and the sesskey has been checked ... edit the enrolment.
-    $data = $mform->get_data();
+} else if ($data = $mform->get_data()) {
     if ($manager->edit_enrolment($ue, $data)) {
         redirect($returnurl);
     }
@@ -107,4 +101,4 @@ $PAGE->navbar->add($fullname);
 echo $OUTPUT->header();
 echo $OUTPUT->heading($fullname);
 $mform->display();
-echo $OUTPUT->footer();
\ No newline at end of file
+echo $OUTPUT->footer();
index ea9205d..b73fc7c 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Contains the form used to edit manual enrolments for a user.
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2011 Sam Hemelryk
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -80,4 +78,4 @@ class enrol_manual_user_enrolment_form extends moodleform {
 
         return $errors;
     }
-}
\ No newline at end of file
+}
index 94fde81..01686da 100644 (file)
@@ -14,7 +14,6 @@
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
-
 /**
  * External course participation api.
  *
@@ -32,7 +31,7 @@ defined('MOODLE_INTERNAL') || die();
 require_once("$CFG->libdir/externallib.php");
 
 /**
- * Manual enrolment external functions
+ * Manual enrolment external functions.
  *
  * @package    enrol_manual
  * @category   external
@@ -43,7 +42,7 @@ require_once("$CFG->libdir/externallib.php");
 class enrol_manual_external extends external_api {
 
     /**
-     * Returns description of method parameters
+     * Returns description of method parameters.
      *
      * @return external_function_parameters
      * @since Moodle 2.2
@@ -68,7 +67,7 @@ class enrol_manual_external extends external_api {
     }
 
     /**
-     * Enrolment of users
+     * Enrolment of users.
      *
      * Function throw an exception at the first error encountered.
      * @param array $enrolments  An array of user enrolment
@@ -82,24 +81,24 @@ class enrol_manual_external extends external_api {
         $params = self::validate_parameters(self::enrol_users_parameters(),
                 array('enrolments' => $enrolments));
 
-        $transaction = $DB->start_delegated_transaction(); //rollback all enrolment if an error occurs
-                                                           //(except if the DB doesn't support it)
+        $transaction = $DB->start_delegated_transaction(); // Rollback all enrolment if an error occurs
+                                                           // (except if the DB doesn't support it).
 
-        //retrieve the manual enrolment plugin
+        // Retrieve the manual enrolment plugin.
         $enrol = enrol_get_plugin('manual');
         if (empty($enrol)) {
             throw new moodle_exception('manualpluginnotinstalled', 'enrol_manual');
         }
 
         foreach ($params['enrolments'] as $enrolment) {
-            // Ensure the current user is allowed to run this function in the enrolment context
+            // Ensure the current user is allowed to run this function in the enrolment context.
             $context = context_course::instance($enrolment['courseid'], IGNORE_MISSING);
             self::validate_context($context);
 
-            //check that the user has the permission to manual enrol
+            // Check that the user has the permission to manual enrol.
             require_capability('enrol/manual:enrol', $context);
 
-            //throw an exception if user is not able to assign the role
+            // Throw an exception if user is not able to assign the role.
             $roles = get_assignable_roles($context);
             if (!key_exists($enrolment['roleid'], $roles)) {
                 $errorparams = new stdClass();
@@ -109,7 +108,7 @@ class enrol_manual_external extends external_api {
                 throw new moodle_exception('wsusercannotassign', 'enrol_manual', '', $errorparams);
             }
 
-            //check manual enrolment plugin instance is enabled/exist
+            // Check manual enrolment plugin instance is enabled/exist.
             $enrolinstances = enrol_get_instances($enrolment['courseid'], true);
             foreach ($enrolinstances as $courseenrolinstance) {
               if ($courseenrolinstance->enrol == "manual") {
@@ -123,7 +122,7 @@ class enrol_manual_external extends external_api {
               throw new moodle_exception('wsnoinstance', 'enrol_manual', $errorparams);
             }
 
-            //check that the plugin accept enrolment (it should always the case, it's hard coded in the plugin)
+            // Check that the plugin accept enrolment (it should always the case, it's hard coded in the plugin).
             if (!$enrol->allow_enrol($instance)) {
                 $errorparams = new stdClass();
                 $errorparams->roleid = $enrolment['roleid'];
@@ -132,7 +131,7 @@ class enrol_manual_external extends external_api {
                 throw new moodle_exception('wscannotenrol', 'enrol_manual', '', $errorparams);
             }
 
-            //finally proceed the enrolment
+            // Finally proceed the enrolment.
             $enrolment['timestart'] = isset($enrolment['timestart']) ? $enrolment['timestart'] : 0;
             $enrolment['timeend'] = isset($enrolment['timeend']) ? $enrolment['timeend'] : 0;
             $enrolment['status'] = (isset($enrolment['suspend']) && !empty($enrolment['suspend'])) ?
@@ -147,7 +146,7 @@ class enrol_manual_external extends external_api {
     }
 
     /**
-     * Returns description of method result value
+     * Returns description of method result value.
      *
      * @return null
      * @since Moodle 2.2
@@ -159,7 +158,7 @@ class enrol_manual_external extends external_api {
 }
 
 /**
- * Deprecated manual enrolment external functions
+ * Deprecated manual enrolment external functions.
  *
  * @package    enrol_manual
  * @copyright  2011 Jerome Mouneyrac
@@ -172,7 +171,7 @@ class enrol_manual_external extends external_api {
 class moodle_enrol_manual_external extends external_api {
 
     /**
-     * Returns description of method parameters
+     * Returns description of method parameters.
      *
      * @return external_function_parameters
      * @since Moodle 2.0
@@ -199,7 +198,7 @@ class moodle_enrol_manual_external extends external_api {
     }
 
     /**
-     * Returns description of method result value
+     * Returns description of method result value.
      *
      * @return nul
      * @since Moodle 2.0
index 5320f6a..2cf94bb 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Manual enrolment plugin main library file.
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2010 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -29,22 +27,22 @@ defined('MOODLE_INTERNAL') || die();
 class enrol_manual_plugin extends enrol_plugin {
 
     public function roles_protected() {
-        // users may tweak the roles later
+        // Users may tweak the roles later.
         return false;
     }
 
     public function allow_enrol(stdClass $instance) {
-        // users with enrol cap may unenrol other users manually manually
+        // Users with enrol cap may unenrol other users manually manually.
         return true;
     }
 
     public function allow_unenrol(stdClass $instance) {
-        // users with unenrol cap may unenrol other users manually manually
+        // Users with unenrol cap may unenrol other users manually manually.
         return true;
     }
 
     public function allow_manage(stdClass $instance) {
-        // users with manage cap may tweak period and status
+        // Users with manage cap may tweak period and status.
         return true;
     }
 
@@ -52,7 +50,7 @@ class enrol_manual_plugin extends enrol_plugin {
      * Returns link to manual enrol UI if exists.
      * Does the access control tests automatically.
      *
-     * @param object $instance
+     * @param stdClass $instance
      * @return moodle_url
      */
     public function get_manual_enrol_link($instance) {
@@ -96,7 +94,7 @@ class enrol_manual_plugin extends enrol_plugin {
     }
 
     /**
-     * Returns edit icons for the page with list of instances
+     * Returns edit icons for the page with list of instances.
      * @param stdClass $instance
      * @return array
      */
@@ -145,7 +143,7 @@ class enrol_manual_plugin extends enrol_plugin {
 
     /**
      * Add new instance of enrol plugin with default settings.
-     * @param object $course
+     * @param stdClass $course
      * @return int id of new instance, null if can not be created
      */
     public function add_default_instance($course) {
@@ -155,7 +153,7 @@ class enrol_manual_plugin extends enrol_plugin {
 
     /**
      * Add new instance of enrol plugin.
-     * @param object $course
+     * @param stdClass $course
      * @param array instance fields
      * @return int id of new instance, null if can not be created
      */
@@ -260,7 +258,7 @@ class enrol_manual_plugin extends enrol_plugin {
     }
 
     /**
-     * Gets an array of the user enrolment actions
+     * Gets an array of the user enrolment actions.
      *
      * @param course_enrolment_manager $manager
      * @param stdClass $ue A user enrolment object
@@ -284,7 +282,7 @@ class enrol_manual_plugin extends enrol_plugin {
     }
 
     /**
-     * The manual plugin has several bulk operations that can be performed
+     * The manual plugin has several bulk operations that can be performed.
      * @param course_enrolment_manager $manager
      * @return array
      */
index 1d09681..d7b8f0c 100644 (file)
@@ -17,8 +17,7 @@
 /**
  * Auxiliary manual user enrolment lib, the main purpose is to lower memory requirements...
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2010 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -30,7 +29,7 @@ require_once($CFG->dirroot . '/enrol/locallib.php');
 
 
 /**
- * Enrol candidates
+ * Enrol candidates.
  */
 class enrol_manual_potential_participant extends user_selector_base {
     protected $enrolid;
@@ -42,12 +41,12 @@ class enrol_manual_potential_participant extends user_selector_base {
 
     /**
      * Candidate users
-     * @param <type> $search
+     * @param string $search
      * @return array
      */
     public function find_users($search) {
         global $DB;
-        //by default wherecondition retrieves all users except the deleted, not confirmed and guest
+        // By default wherecondition retrieves all users except the deleted, not confirmed and guest.
         list($wherecondition, $params) = $this->search_sql($search, 'u');
         $params['enrolid'] = $this->enrolid;
 
@@ -92,7 +91,7 @@ class enrol_manual_potential_participant extends user_selector_base {
 }
 
 /**
- * Enroled users
+ * Enrolled users.
  */
 class enrol_manual_current_participant extends user_selector_base {
     protected $courseid;
@@ -105,12 +104,12 @@ class enrol_manual_current_participant extends user_selector_base {
 
     /**
      * Candidate users
-     * @param <type> $search
+     * @param string $search
      * @return array
      */
     public function find_users($search) {
         global $DB;
-        //by default wherecondition retrieves all users except the deleted, not confirmed and guest
+        // By default wherecondition retrieves all users except the deleted, not confirmed and guest.
         list($wherecondition, $params) = $this->search_sql($search, 'u');
         $params['enrolid'] = $this->enrolid;
 
@@ -182,7 +181,6 @@ class enrol_manual_editselectedusers_operation extends enrol_bulk_enrolment_oper
     /**
      * Processes the bulk operation request for the given userids with the provided properties.
      *
-     * @global moodle_database $DB
      * @param course_enrolment_manager $manager
      * @param array $userids
      * @param stdClass $properties The data returned by the form.
@@ -194,7 +192,7 @@ class enrol_manual_editselectedusers_operation extends enrol_bulk_enrolment_oper
             return false;
         }
 
-        // Get all of the user enrolment id's
+        // Get all of the user enrolment id's.
         $ueids = array();
         $instances = array();
         foreach ($users as $user) {
@@ -237,15 +235,15 @@ class enrol_manual_editselectedusers_operation extends enrol_bulk_enrolment_oper
             return true;
         }
 
-        // Update the modifierid
+        // Update the modifierid.
         $updatesql[] = 'modifierid = :modifierid';
         $params['modifierid'] = (int)$USER->id;
 
-        // Update the time modified
+        // Update the time modified.
         $updatesql[] = 'timemodified = :timemodified';
         $params['timemodified'] = time();
 
-        // Build the SQL statement
+        // Build the SQL statement.
         $updatesql = join(', ', $updatesql);
         $sql = "UPDATE {user_enrolments}
                    SET $updatesql
@@ -353,4 +351,102 @@ class enrol_manual_deleteselectedusers_operation extends enrol_bulk_enrolment_op
         }
         return true;
     }
-}
\ No newline at end of file
+}
+
+/**
+ * Migrates all enrolments of the given plugin to enrol_manual plugin,
+ * this is used for example during plugin uninstallation.
+ *
+ * NOTE: this function does not trigger role and enrolment related events.
+ *
+ * @param string $enrol  The enrolment method.
+ */
+function enrol_manual_migrate_plugin_enrolments($enrol) {
+    global $DB;
+
+    if ($enrol === 'manual') {
+        // We can not migrate to self.
+        return;
+    }
+
+    $manualplugin = enrol_get_plugin('manual');
+
+    $params = array('enrol'=>$enrol);
+    $sql = "SELECT e.id, e.courseid, e.status, MIN(me.id) AS mid, COUNT(ue.id) AS cu
+              FROM {enrol} e
+              JOIN {user_enrolments} ue ON (ue.enrolid = e.id)
+              JOIN {course} c ON (c.id = e.courseid)
+         LEFT JOIN {enrol} me ON (me.courseid = e.courseid AND me.enrol='manual')
+             WHERE e.enrol = :enrol
+          GROUP BY e.id, e.courseid, e.status
+          ORDER BY e.id";
+    $rs = $DB->get_recordset_sql($sql, $params);
+
+    foreach($rs as $e) {
+        $minstance = false;
+        if (!$e->mid) {
+            // Manual instance does not exist yet, add a new one.
+            $course = $DB->get_record('course', array('id'=>$e->courseid), '*', MUST_EXIST);
+            if ($minstance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'manual'))) {
+                // Already created by previous iteration.
+                $e->mid = $minstance->id;
+            } else if ($e->mid = $manualplugin->add_default_instance($course)) {
+                $minstance = $DB->get_record('enrol', array('id'=>$e->mid));
+                if ($e->status != ENROL_INSTANCE_ENABLED) {
+                    $DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$e->mid));
+                    $minstance->status = ENROL_INSTANCE_DISABLED;
+                }
+            }
+        } else {
+            $minstance = $DB->get_record('enrol', array('id'=>$e->mid));
+        }
+
+        if (!$minstance) {
+            // This should never happen unless adding of default instance fails unexpectedly.
+            continue;
+        }
+
+        // First delete potential role duplicates.
+        $params = array('id'=>$e->id, 'component'=>'enrol_'.$enrol, 'empty'=>$DB->sql_empty());
+        $sql = "SELECT ra.id
+                  FROM {role_assignments} ra
+                  JOIN {role_assignments} mra ON (mra.contextid = ra.contextid AND mra.userid = ra.userid AND mra.roleid = ra.roleid AND mra.component = :empty AND mra.itemid = 0)
+                 WHERE ra.component = :component AND ra.itemid = :id";
+        $ras = $DB->get_records_sql($sql, $params);
+        $ras = array_keys($ras);
+        $DB->delete_records_list('role_assignments', 'id', $ras);
+        unset($ras);
+
+        // Migrate roles.
+        $sql = "UPDATE {role_assignments}
+                   SET itemid = 0, component = :empty
+                 WHERE itemid = :id AND component = :component";
+        $params = array('empty'=>$DB->sql_empty(), 'id'=>$e->id, 'component'=>'enrol_'.$enrol);
+        $DB->execute($sql, $params);
+
+        // Delete potential enrol duplicates.
+        $params = array('id'=>$e->id, 'mid'=>$e->mid);
+        $sql = "SELECT ue.id
+                  FROM {user_enrolments} ue
+                  JOIN {user_enrolments} mue ON (mue.userid = ue.userid AND mue.enrolid = :mid)
+                 WHERE ue.enrolid = :id";
+        $ues = $DB->get_records_sql($sql, $params);
+        $ues = array_keys($ues);
+        $DB->delete_records_list('user_enrolments', 'id', $ues);
+        unset($ues);
+
+        // Migrate to manual enrol instance.
+        $params = array('id'=>$e->id, 'mid'=>$e->mid);
+        if ($e->status != ENROL_INSTANCE_ENABLED and $minstance->status == ENROL_INSTANCE_ENABLED) {
+            $status = ", status = :disabled";
+            $params['disabled'] = ENROL_USER_SUSPENDED;
+        } else {
+            $status = "";
+        }
+        $sql = "UPDATE {user_enrolments}
+                   SET enrolid = :mid $status
+                 WHERE enrolid = :id";
+        $DB->execute($sql, $params);
+    }
+    $rs->close();
+}
index 0a4f698..46d1b77 100644 (file)
@@ -17,8 +17,7 @@
 /**
  * Manual user enrolment UI.
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2010 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -47,7 +46,7 @@ $roles = get_assignable_roles($context);
 $roles = array('0'=>get_string('none')) + $roles;
 
 if (!isset($roles[$roleid])) {
-    // weird - security always first!
+    // Weird - security always first!
     $roleid = 0;
 }
 
@@ -88,14 +87,14 @@ $timeformat = get_string('strftimedatefullshort');
 $today = time();
 $today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0);
 
-// enrolment start
+// Enrolment start.
 $basemenu = array();
 if ($course->startdate > 0) {
     $basemenu[2] = get_string('coursestart') . ' (' . userdate($course->startdate, $timeformat) . ')';
 }
 $basemenu[3] = get_string('today') . ' (' . userdate($today, $timeformat) . ')' ;
 
-// process add and removes
+// Process add and removes.
 if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) {
     $userstoassign = $potentialuserselector->get_selected_users();
     if (!empty($userstoassign)) {
@@ -126,7 +125,7 @@ if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) {
     }
 }
 
-// Process incoming role unassignments
+// Process incoming role unassignments.
 if (optional_param('remove', false, PARAM_BOOL) && confirm_sesskey()) {
     $userstounassign = $currentuserselector->get_selected_users();
     if (!empty($userstounassign)) {
index 13d72ed..79686aa 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Manual enrolment plugin settings and presets.
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2010 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -55,4 +53,3 @@ if ($ADMIN->fulltree) {
             get_string('defaultrole', 'role'), '', $student->id, $options));
     }
 }
-
diff --git a/enrol/manual/tests/lib_test.php b/enrol/manual/tests/lib_test.php
new file mode 100644 (file)
index 0000000..745bac0
--- /dev/null
@@ -0,0 +1,204 @@
+<?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/>.
+
+/**
+ * Manual enrolment tests.
+ *
+ * @package    enrol_manual
+ * @category   phpunit
+ * @copyright  2012 Petr Skoda {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+
+/**
+ * Manual enrolment tests.
+ *
+ * @package    enrol_manual
+ * @category   phpunit
+ * @copyright  2012 Petr Skoda {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class enrol_manual_lib_testcase extends advanced_testcase {
+    /**
+     * Test enrol migration function used when uninstalling enrol plugins.
+     */
+    public function test_migrate_plugin_enrolments() {
+        global $DB, $CFG;
+        require_once($CFG->dirroot.'/enrol/manual/locallib.php');
+
+        $this->resetAfterTest();
+
+        $manplugin = enrol_get_plugin('manual');
+
+        // Setup a few courses and users.
+
+        $studentrole = $DB->get_record('role', array('shortname'=>'student'));
+        $this->assertNotEmpty($studentrole);
+        $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
+        $this->assertNotEmpty($teacherrole);
+
+        $course1 = $this->getDataGenerator()->create_course();
+        $course2 = $this->getDataGenerator()->create_course();
+        $course3 = $this->getDataGenerator()->create_course();
+        $course4 = $this->getDataGenerator()->create_course();
+        $course5 = $this->getDataGenerator()->create_course();
+
+        $context1 = context_course::instance($course1->id);
+        $context2 = context_course::instance($course2->id);
+        $context3 = context_course::instance($course3->id);
+        $context4 = context_course::instance($course4->id);
+
+        $user1 = $this->getDataGenerator()->create_user();
+        $user2 = $this->getDataGenerator()->create_user();
+        $user3 = $this->getDataGenerator()->create_user();
+        $user4 = $this->getDataGenerator()->create_user();
+
+        // We expect manual, self and guest instances to be created by default.
+
+        $this->assertEquals(5, $DB->count_records('enrol', array('enrol'=>'manual')));
+        $this->assertEquals(5, $DB->count_records('enrol', array('enrol'=>'self')));
+        $this->assertEquals(5, $DB->count_records('enrol', array('enrol'=>'guest')));
+        $this->assertEquals(15, $DB->count_records('enrol', array()));
+
+        $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
+
+        // Enrol some users to manual instances.
+
+        $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
+        $DB->set_field('enrol', 'status', ENROL_INSTANCE_DISABLED, array('id'=>$maninstance1->id));
+        $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
+        $maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
+        $DB->delete_records('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'));
+        $DB->delete_records('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'));
+        $DB->delete_records('enrol', array('courseid'=>$course5->id, 'enrol'=>'manual'));
+
+        $manplugin->enrol_user($maninstance1, $user1->id, $studentrole->id);
+        $manplugin->enrol_user($maninstance1, $user2->id, $studentrole->id);
+        $manplugin->enrol_user($maninstance1, $user3->id, $teacherrole->id);
+        $manplugin->enrol_user($maninstance2, $user3->id, $teacherrole->id);
+
+        $this->assertEquals(4, $DB->count_records('user_enrolments', array()));
+
+        // Set up some bogus enrol plugin instances and enrolments.
+
+        $xxxinstance1 = $DB->insert_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'xxx', 'status'=>ENROL_INSTANCE_ENABLED));
+        $xxxinstance1 = $DB->get_record('enrol', array('id'=>$xxxinstance1));
+        $xxxinstance3 = $DB->insert_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'xxx', 'status'=>ENROL_INSTANCE_DISABLED));
+        $xxxinstance3 = $DB->get_record('enrol', array('id'=>$xxxinstance3));
+        $xxxinstance4 = $DB->insert_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'xxx', 'status'=>ENROL_INSTANCE_ENABLED));
+        $xxxinstance4 = $DB->get_record('enrol', array('id'=>$xxxinstance4));
+        $xxxinstance4b = $DB->insert_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'xxx', 'status'=>ENROL_INSTANCE_DISABLED));
+        $xxxinstance4b = $DB->get_record('enrol', array('id'=>$xxxinstance4b));
+
+
+        $DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance1->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_SUSPENDED));
+        role_assign($studentrole->id, $user1->id, $context1->id, 'enrol_xxx', $xxxinstance1->id);
+        role_assign($teacherrole->id, $user1->id, $context1->id, 'enrol_xxx', $xxxinstance1->id);
+        $DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance1->id, 'userid'=>$user4->id, 'status'=>ENROL_USER_ACTIVE));
+        role_assign($studentrole->id, $user4->id, $context1->id, 'enrol_xxx', $xxxinstance1->id);
+        $this->assertEquals(2, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance1->id)));
+        $this->assertEquals(6, $DB->count_records('role_assignments', array('contextid'=>$context1->id)));
+
+
+        $DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance3->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_ACTIVE));
+        role_assign($studentrole->id, $user1->id, $context3->id, 'enrol_xxx', $xxxinstance3->id);
+        $DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance3->id, 'userid'=>$user2->id, 'status'=>ENROL_USER_SUSPENDED));
+        $this->assertEquals(2, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance3->id)));
+        $this->assertEquals(1, $DB->count_records('role_assignments', array('contextid'=>$context3->id)));
+
+        $DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance4->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_ACTIVE));
+        role_assign($studentrole->id, $user1->id, $context4->id, 'enrol_xxx', $xxxinstance4->id);
+        $DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance4->id, 'userid'=>$user2->id, 'status'=>ENROL_USER_ACTIVE));
+        role_assign($studentrole->id, $user2->id, $context4->id, 'enrol_xxx', $xxxinstance4->id);
+        $DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance4b->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_SUSPENDED));
+        role_assign($teacherrole->id, $user1->id, $context4->id, 'enrol_xxx', $xxxinstance4b->id);
+        $DB->insert_record('user_enrolments', array('enrolid'=>$xxxinstance4b->id, 'userid'=>$user4->id, 'status'=>ENROL_USER_ACTIVE));
+        role_assign($teacherrole->id, $user4->id, $context4->id, 'enrol_xxx', $xxxinstance4b->id);
+        $this->assertEquals(2, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance4->id)));
+        $this->assertEquals(2, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance4b->id)));
+        $this->assertEquals(4, $DB->count_records('role_assignments', array('contextid'=>$context4->id)));
+
+        // Finally do the migration.
+
+        enrol_manual_migrate_plugin_enrolments('xxx');
+
+        // Verify results.
+
+        $this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual')));
+        $this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course1->id, 'enrol'=>'xxx')));
+        $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
+        $this->assertEquals(ENROL_INSTANCE_DISABLED, $maninstance1->status);
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_ACTIVE)));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user2->id, 'status'=>ENROL_USER_ACTIVE)));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user3->id, 'status'=>ENROL_USER_ACTIVE)));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance1->id, 'userid'=>$user4->id, 'status'=>ENROL_USER_ACTIVE)));
+        $this->assertEquals(4, $DB->count_records('user_enrolments', array('enrolid'=>$maninstance1->id)));
+        $this->assertEquals(0, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance1->id)));
+        $this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>$DB->sql_empty(), 'userid'=>$user1->id, 'roleid'=>$studentrole->id, 'contextid'=>$context1->id)));
+        $this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>$DB->sql_empty(), 'userid'=>$user1->id, 'roleid'=>$teacherrole->id, 'contextid'=>$context1->id)));
+        $this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>$DB->sql_empty(), 'userid'=>$user2->id, 'roleid'=>$studentrole->id, 'contextid'=>$context1->id)));
+        $this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>$DB->sql_empty(), 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'contextid'=>$context1->id)));
+        $this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>$DB->sql_empty(), 'userid'=>$user4->id, 'roleid'=>$studentrole->id, 'contextid'=>$context1->id)));
+        $this->assertEquals(5, $DB->count_records('role_assignments', array('contextid'=>$context1->id)));
+
+
+        $this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual')));
+        $this->assertEquals(0, $DB->count_records('enrol', array('courseid'=>$course2->id, 'enrol'=>'xxx')));
+        $maninstance2 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
+        $this->assertEquals(ENROL_INSTANCE_ENABLED, $maninstance2->status);
+
+
+        $this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual')));
+        $this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course3->id, 'enrol'=>'xxx')));
+        $maninstance3 = $DB->get_record('enrol', array('courseid'=>$course3->id, 'enrol'=>'manual'), '*', MUST_EXIST);
+        $this->assertEquals(ENROL_INSTANCE_DISABLED, $maninstance3->status);
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance3->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_ACTIVE)));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance3->id, 'userid'=>$user2->id, 'status'=>ENROL_USER_SUSPENDED)));
+        $this->assertEquals(2, $DB->count_records('user_enrolments', array('enrolid'=>$maninstance3->id)));
+        $this->assertEquals(0, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance3->id)));
+        $this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>$DB->sql_empty(), 'userid'=>$user1->id, 'roleid'=>$studentrole->id, 'contextid'=>$context3->id)));
+        $this->assertEquals(1, $DB->count_records('role_assignments', array('contextid'=>$context3->id)));
+
+
+        $this->assertEquals(1, $DB->count_records('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual')));
+        $this->assertEquals(2, $DB->count_records('enrol', array('courseid'=>$course4->id, 'enrol'=>'xxx')));
+        $maninstance4 = $DB->get_record('enrol', array('courseid'=>$course4->id, 'enrol'=>'manual'), '*', MUST_EXIST);
+        $this->assertEquals(ENROL_INSTANCE_ENABLED, $maninstance4->status);
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance4->id, 'userid'=>$user1->id, 'status'=>ENROL_USER_ACTIVE)));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance4->id, 'userid'=>$user2->id, 'status'=>ENROL_USER_ACTIVE)));
+        $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$maninstance4->id, 'userid'=>$user4->id, 'status'=>ENROL_USER_SUSPENDED)));
+        $this->assertEquals(3, $DB->count_records('user_enrolments', array('enrolid'=>$maninstance4->id)));
+        $this->assertEquals(0, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance4->id)));
+        $this->assertEquals(0, $DB->count_records('user_enrolments', array('enrolid'=>$xxxinstance4b->id)));
+        $this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>$DB->sql_empty(), 'userid'=>$user1->id, 'roleid'=>$studentrole->id, 'contextid'=>$context4->id)));
+        $this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>$DB->sql_empty(), 'userid'=>$user1->id, 'roleid'=>$teacherrole->id, 'contextid'=>$context4->id)));
+        $this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>$DB->sql_empty(), 'userid'=>$user2->id, 'roleid'=>$studentrole->id, 'contextid'=>$context4->id)));
+        $this->assertTrue($DB->record_exists('role_assignments', array('itemid'=>0, 'component'=>$DB->sql_empty(), 'userid'=>$user4->id, 'roleid'=>$teacherrole->id, 'contextid'=>$context4->id)));
+        $this->assertEquals(4, $DB->count_records('role_assignments', array('contextid'=>$context4->id)));
+
+
+        $this->assertEquals(0, $DB->count_records('enrol', array('courseid'=>$course5->id, 'enrol'=>'manual')));
+        $this->assertEquals(0, $DB->count_records('enrol', array('courseid'=>$course5->id, 'enrol'=>'xxx')));
+
+        // Make sure wrong params do not produce errors or notices.
+
+        enrol_manual_migrate_plugin_enrolments('manual');
+        enrol_manual_migrate_plugin_enrolments('yyyy');
+    }
+}
index fb1744d..c7304fb 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Manual enrolment plugin - support for user self unenrolment.
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2010 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -41,7 +39,7 @@ require_login($course);
 
 $plugin = enrol_get_plugin('manual');
 
-// security defined inside following function
+// Security defined inside following function.
 if (!$plugin->get_unenrolself_link($instance)) {
     redirect(new moodle_url('/course/view.php', array('id'=>$course->id)));
 }
@@ -51,7 +49,7 @@ $PAGE->set_title($plugin->get_instance_name($instance));
 
 if ($confirm and confirm_sesskey()) {
     $plugin->unenrol_user($instance, $USER->id);
-    add_to_log($course->id, 'course', 'unenrol', '../enrol/users.php?id='.$course->id, $course->id); //there should be userid somewhere!
+    add_to_log($course->id, 'course', 'unenrol', '../enrol/users.php?id='.$course->id, $course->id); //TODO: there should be userid somewhere!
     redirect(new moodle_url('/index.php'));
 }
 
index 8d2ff58..2107a67 100644 (file)
@@ -17,8 +17,7 @@
 /**
  * Manual enrolment plugin version specification.
  *
- * @package    enrol
- * @subpackage manual
+ * @package    enrol_manual
  * @copyright  2010 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index fafbfd7..c7fa8ea 100644 (file)
@@ -449,7 +449,7 @@ class course_enrolment_table extends html_table implements renderable {
 
         // Collect the bulk operations for the currently filtered plugin if there is one.
         $plugin = $manager->get_filtered_enrolment_plugin();
-        if ($plugin) {
+        if ($plugin and enrol_is_enabled($plugin->get_name())) {
             $this->bulkoperations = $plugin->get_bulk_operations($manager);
         }
     }
index 314720c..9cdd3c3 100644 (file)
@@ -26,6 +26,7 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
+    /* Add or edit enrol-self instance in course. */
     'enrol/self:config' => array(
 
         'captype' => 'write',
@@ -36,6 +37,7 @@ $capabilities = array(
         )
     ),
 
+    /* Manage user self-enrolments. */
     'enrol/self:manage' => array(
 
         'captype' => 'write',
@@ -46,6 +48,7 @@ $capabilities = array(
         )
     ),
 
+    /* Voluntarily unenrol self from course - watch out for data loss. */
     'enrol/self:unenrolself' => array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_COURSE,
@@ -54,6 +57,7 @@ $capabilities = array(
         )
     ),
 
+    /* Unenrol anybody from course (including self) -  watch out for data loss. */
     'enrol/self:unenrol' => array(
         'captype' => 'write',
         'contextlevel' => CONTEXT_COURSE,
@@ -64,5 +68,3 @@ $capabilities = array(
     ),
 
 );
-
-
index 82d8c2f..320fc08 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Self enrol plugin installation script
  *
- * @package    enrol
- * @subpackage self
+ * @package    enrol_self
  * @copyright  2010 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 4b38df4..97448ca 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -19,8 +18,7 @@
  * Adds new instance of enrol_self to specified course
  * or edits current instance.
  *
- * @package    enrol
- * @subpackage self
+ * @package    enrol_self
  * @copyright  2010 Petr Skoda  {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -29,7 +27,7 @@ require('../../config.php');
 require_once('edit_form.php');
 
 $courseid   = required_param('courseid', PARAM_INT);
-$instanceid = optional_param('id', 0, PARAM_INT); // instanceid
+$instanceid = optional_param('id', 0, PARAM_INT);
 
 $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
 $context = context_course::instance($course->id, MUST_EXIST);
@@ -51,11 +49,12 @@ if ($instanceid) {
     $instance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'self', 'id'=>$instanceid), '*', MUST_EXIST);
 } else {
     require_capability('moodle/course:enrolconfig', $context);
-    // no instance yet, we have to add new instance
+    // No instance yet, we have to add new instance.
     navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id)));
     $instance = new stdClass();
-    $instance->id       = null;
-    $instance->courseid = $course->id;
+    $instance->id         = null;
+    $instance->courseid   = $course->id;
+    $instance->customint5 = 0;
 }
 
 $mform = new enrol_self_edit_form(NULL, array($instance, $plugin, $context));
@@ -74,6 +73,7 @@ if ($mform->is_cancelled()) {
         $instance->customint2     = $data->customint2;
         $instance->customint3     = $data->customint3;
         $instance->customint4     = $data->customint4;
+        $instance->customint5     = $data->customint5;
         $instance->customtext1    = $data->customtext1;
         $instance->roleid         = $data->roleid;
         $instance->enrolperiod    = $data->enrolperiod;
@@ -88,7 +88,7 @@ if ($mform->is_cancelled()) {
 
     } else {
         $fields = array('status'=>$data->status, 'name'=>$data->name, 'password'=>$data->password, 'customint1'=>$data->customint1, 'customint2'=>$data->customint2,
-                        'customint3'=>$data->customint3, 'customint4'=>$data->customint4, 'customtext1'=>$data->customtext1,
+                        'customint3'=>$data->customint3, 'customint4'=>$data->customint4, 'customint5'=>$data->customint5, 'customtext1'=>$data->customtext1,
                         'roleid'=>$data->roleid, 'enrolperiod'=>$data->enrolperiod, 'enrolstartdate'=>$data->enrolstartdate, 'enrolenddate'=>$data->enrolenddate);
         $plugin->add_instance($course, $fields);
     }
index 7f77cfc..f094b9b 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -19,8 +18,7 @@
  * Adds new instance of enrol_self to specified course
  * or edits current instance.
  *
- * @package    enrol
- * @subpackage self
+ * @package    enrol_self
  * @copyright  2010 Petr Skoda  {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -32,6 +30,8 @@ require_once($CFG->libdir.'/formslib.php');
 class enrol_self_edit_form extends moodleform {
 
     function definition() {
+        global $DB;
+
         $mform = $this->_form;
 
         list($instance, $plugin, $context) = $this->_customdata;
@@ -100,6 +100,38 @@ class enrol_self_edit_form extends moodleform {
         $mform->addHelpButton('customint3', 'maxenrolled', 'enrol_self');
         $mform->setType('customint3', PARAM_INT);
 
+        $cohorts = array(0 => get_string('no'));
+        list($sqlparents, $params) = $DB->get_in_or_equal($context->get_parent_context_ids(), SQL_PARAMS_NAMED);
+        $params['current'] = $instance->customint5;
+        $sql = "SELECT id, name, idnumber, contextid
+                  FROM {cohort}
+                 WHERE contextid $sqlparents OR id = :current
+              ORDER BY name ASC, idnumber ASC";
+        $rs = $DB->get_recordset_sql($sql, $params);
+        foreach ($rs as $c) {
+            $ccontext = context::instance_by_id($c->contextid);
+            if ($c->id != $instance->customint5 and !has_capability('moodle/cohort:view', $ccontext)) {
+                continue;
+            }
+            $cohorts[$c->id] = format_string($c->name, true, array('context'=>$context));
+            if ($c->idnumber) {
+                $cohorts[$c->id] .= ' ['.s($c->idnumber).']';
+            }
+        }
+        if (!isset($cohorts[$instance->customint5])) {
+            // Somebody deleted a cohort, better keep the wrong value so that random ppl can not enrol.
+            $cohorts[$instance->customint5] = get_string('unknowncohort', 'cohort', $instance->customint5);
+        }
+        $rs->close();
+        if (count($cohorts) > 1) {
+            $mform->addElement('select', 'customint5', get_string('cohortonly', 'enrol_self'), $cohorts);
+            $mform->addHelpButton('customint5', 'cohortonly', 'enrol_self');
+        } else {
+            $mform->addElement('hidden', 'customint5');
+            $mform->setType('customint5', PARAM_INT);
+            $mform->setConstant('customint5', 0);
+        }
+
         $mform->addElement('advcheckbox', 'customint4', get_string('sendcoursewelcomemessage', 'enrol_self'));
         $mform->setDefault('customint4', $plugin->get_config('sendcoursewelcomemessage'));
         $mform->addHelpButton('customint4', 'sendcoursewelcomemessage', 'enrol_self');
@@ -159,7 +191,7 @@ class enrol_self_edit_form extends moodleform {
     }
 
     /**
-    * Gets a list of roles that this user can assign for the course as the default for self-enrolment
+    * Gets a list of roles that this user can assign for the course as the default for self-enrolment.
     *
     * @param context $context the context.
     * @param integer $defaultrole the id of the role that is set as the default for self-enrolment
index 418359e..8af223f 100644 (file)
  * This page allows the current user to edit a self user enrolment.
  * It is not compatible with the frontpage.
  *
- * @package    enrol
- * @subpackage self
+ * @package    enrol_self
  * @copyright  2011 Sam Hemelryk
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 require('../../config.php');
-require_once("$CFG->dirroot/enrol/locallib.php"); // Required for the course enrolment manager
-require_once("$CFG->dirroot/enrol/renderer.php"); // Required for the course enrolment users table
-require_once("$CFG->dirroot/enrol/self/editenrolment_form.php"); // Forms for this page
-
-$ueid   = required_param('ue', PARAM_INT); // user enrolment id
-$filter = optional_param('ifilter', 0, PARAM_INT); // table filter for return url
-
-// Get the user enrolment object
-$ue     = $DB->get_record('user_enrolments', array('id' => $ueid), '*', MUST_EXIST);
-// Get the user for whom the enrolment is
-$user   = $DB->get_record('user', array('id'=>$ue->userid), '*', MUST_EXIST);
-// Get the course the enrolment is to
-list($ctxsql, $ctxjoin) = context_instance_preload_sql('c.id', CONTEXT_COURSE, 'ctx');
-$sql = "SELECT c.* $ctxsql
+require_once("$CFG->dirroot/enrol/locallib.php"); // Required for the course enrolment manager.
+require_once("$CFG->dirroot/enrol/renderer.php"); // Required for the course enrolment users table.
+require_once("$CFG->dirroot/enrol/self/editenrolment_form.php"); // Forms for this page.
+
+$ueid   = required_param('ue', PARAM_INT);
+$filter = optional_param('ifilter', 0, PARAM_INT); // Table filter for return url.
+
+// Get the user enrolment object.
+$ue = $DB->get_record('user_enrolments', array('id' => $ueid), '*', MUST_EXIST);
+// Get the user for whom the enrolment is.
+$user = $DB->get_record('user', array('id'=>$ue->userid), '*', MUST_EXIST);
+// Get the course the enrolment is to.
+$sql = "SELECT c.*
           FROM {course} c
-     LEFT JOIN {enrol} e ON e.courseid = c.id
-               $ctxjoin
+          JOIN {enrol} e ON e.courseid = c.id
          WHERE e.id = :enrolid";
 $params = array('enrolid' => $ue->enrolid);
 $course = $DB->get_record_sql($sql, $params, MUST_EXIST);
-context_instance_preload($course);
 
-// Make sure the course isn't the front page
+// Make sure the course isn't the front page.
 if ($course->id == SITEID) {
     redirect(new moodle_url('/'));
 }
 
-// Obvioulsy
+// Do not allow any changes if plugin disabled.
+if (!enrol_is_enabled('self')) {
+    redirect(new moodle_url('/course/view.php', array('id'=>$course->id)));
+}
+
+// Obviously.
 require_login($course);
-// The user must be able to manage self enrolments within the course
+// The user must be able to manage self enrolments within the course.
 require_capability("enrol/self:manage", context_course::instance($course->id, MUST_EXIST));
 
-// Get the enrolment manager for this course
+// Get the enrolment manager for this course.
 $manager = new course_enrolment_manager($PAGE, $course, $filter);
-// Get an enrolment users table object. Doign this will automatically retrieve the the URL params
+// Get an enrolment users table object. Doing this will automatically retrieve the the URL params
 // relating to table the user was viewing before coming here, and allows us to return the user to the
 // exact page of the users screen they can from.
 $table = new course_enrolment_users_table($manager, $PAGE);
@@ -70,30 +71,28 @@ $table = new course_enrolment_users_table($manager, $PAGE);
 $usersurl = new moodle_url('/enrol/users.php', array('id' => $course->id));
 // The URl to return the user too after this screen.
 $returnurl = new moodle_url($usersurl, $manager->get_url_params()+$table->get_url_params());
-// The URL of this page
+// The URL of this page.
 $url = new moodle_url('/enrol/self/editenrolment.php', $returnurl->params());
 
 $PAGE->set_url($url);
 $PAGE->set_pagelayout('admin');
 navigation_node::override_active_url($usersurl);
 
-// Gets the compontents of the user enrolment
+// Gets the components of the user enrolment.
 list($instance, $plugin) = $manager->get_user_enrolment_components($ue);
-// Check that the user can manage this instance, and that the instance is of the correct type
+// Check that the user can manage this instance, and that the instance is of the correct type.
 if (!$plugin->allow_manage($instance) || $instance->enrol != 'self' || !($plugin instanceof enrol_self_plugin)) {
     print_error('erroreditenrolment', 'enrol');
 }
 
-// Get the self enrolment edit form
+// Get the self enrolment edit form.
 $mform = new enrol_self_user_enrolment_form($url, array('user'=>$user, 'course'=>$course, 'ue'=>$ue));
 $mform->set_data($PAGE->url->params());
 
-// Check the form hasn't been cancelled
 if ($mform->is_cancelled()) {
     redirect($returnurl);
-} else if ($mform->is_submitted() && $mform->is_validated() && confirm_sesskey()) {
-    // The forms been submit, validated and the sesskey has been checked ... edit the enrolment.
-    $data = $mform->get_data();
+
+} else if ($data = $mform->get_data()) {
     if ($manager->edit_enrolment($ue, $data)) {
         redirect($returnurl);
     }
@@ -110,4 +109,4 @@ $PAGE->navbar->add($fullname);
 echo $OUTPUT->header();
 echo $OUTPUT->heading($fullname);
 $mform->display();
-echo $OUTPUT->footer();
\ No newline at end of file
+echo $OUTPUT->footer();
index 0143122..24d6525 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Contains the form used to edit self enrolments for a user.
  *
- * @package    enrol
- * @subpackage self
+ * @package    enrol_self
  * @copyright  2011 Sam Hemelryk
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -80,4 +78,4 @@ class enrol_self_user_enrolment_form extends moodleform {
 
         return $errors;
     }
-}
\ No newline at end of file
+}
index 95595fc..06ba0e4 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * Strings for component 'enrol_self', language 'en', branch 'MOODLE_20_STABLE'
+ * Strings for component 'enrol_self', language 'en'.
  *
- * @package    enrol
- * @subpackage self
+ * @package    enrol_self
  * @copyright  2010 Petr Skoda  {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+$string['cohortnonmemberinfo'] = 'Only members of cohort \'{$a}\' can self-enrol.';
+$string['cohortonly'] = 'Only cohort members';
+$string['cohortonly_help'] = 'Self enrolment may be restricted to members of a specified cohort only. Note that changing this setting has no effect on existing enrolments.';
 $string['customwelcomemessage'] = 'Custom welcome message';
 $string['customwelcomemessage_help'] = 'A custom welcome message may be added as plain text or Moodle-auto format, including HTML tags and multi-lang tags.
 
index 771ec76..fda2414 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Self enrolment plugin.
  *
- * @package    enrol
- * @subpackage self
+ * @package    enrol_self
  * @copyright  2010 Petr Skoda  {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -66,7 +64,7 @@ class enrol_self_plugin extends enrol_plugin {
     /**
      * Returns localised name of enrol instance
      *
-     * @param object $instance (null is accepted too)
+     * @param stdClass $instance (null is accepted too)
      * @return string
      */
     public function get_instance_name($instance) {
@@ -86,28 +84,38 @@ class enrol_self_plugin extends enrol_plugin {
     }
 
     public function roles_protected() {
-        // users may tweak the roles later
+        // Users may tweak the roles later.
         return false;
     }
 
     public function allow_unenrol(stdClass $instance) {
-        // users with unenrol cap may unenrol other users manually manually
+        // Users with unenrol cap may unenrol other users manually manually.
         return true;
     }
 
     public function allow_manage(stdClass $instance) {
-        // users with manage cap may tweak period and status
+        // Users with manage cap may tweak period and status.
         return true;
     }
 
     public function show_enrolme_link(stdClass $instance) {
-        return ($instance->status == ENROL_INSTANCE_ENABLED);
+        global $CFG, $USER;
+
+        if ($instance->status != ENROL_INSTANCE_ENABLED) {
+            return false;
+        }
+        if ($instance->customint5) {
+            require_once("$CFG->dirroot/cohort/lib.php");
+            return cohort_is_member($instance->customint5, $USER->id);
+        }
+        return true;
     }
 
     /**
      * Sets up navigation entries.
      *
-     * @param object $instance
+     * @param stdClass $instancesnode
+     * @param stdClass $instance
      * @return void
      */
     public function add_course_navigation($instancesnode, stdClass $instance) {
@@ -156,7 +164,7 @@ class enrol_self_plugin extends enrol_plugin {
         if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/self:config', $context)) {
             return NULL;
         }
-        // multiple instances supported - different roles with different password
+        // Multiple instances supported - different roles with different password.
         return new moodle_url('/enrol/self/edit.php', array('courseid'=>$courseid));
     }
 
@@ -171,7 +179,7 @@ class enrol_self_plugin extends enrol_plugin {
         global $CFG, $OUTPUT, $SESSION, $USER, $DB;
 
         if (isguestuser()) {
-            // can not enrol guest!!
+            // Can not enrol guest!!
             return null;
         }
         if ($DB->record_exists('user_enrolments', array('userid'=>$USER->id, 'enrolid'=>$instance->id))) {
@@ -189,6 +197,18 @@ class enrol_self_plugin extends enrol_plugin {
             return null;
         }
 
+        if ($instance->customint5) {
+            require_once("$CFG->dirroot/cohort/lib.php");
+            if (!cohort_is_member($instance->customint5, $USER->id)) {
+                $cohort = $DB->get_record('cohort', array('id'=>$instance->customint5));
+                if (!$cohort) {
+                    return null;
+                }
+                $a = format_string($cohort->name, true, array('context'=>context::instance_by_id($cohort->contextid)));
+                return $OUTPUT->box(markdown_to_html(get_string('cohortnonmemberinfo', 'enrol_self', $a)));
+            }
+        }
+
         require_once("$CFG->dirroot/enrol/self/locallib.php");
         require_once("$CFG->dirroot/group/lib.php");
 
@@ -206,7 +226,7 @@ class enrol_self_plugin extends enrol_plugin {
                 }
 
                 $this->enrol_user($instance, $USER->id, $instance->roleid, $timestart, $timeend);
-                add_to_log($instance->courseid, 'course', 'enrol', '../enrol/users.php?id='.$instance->courseid, $instance->courseid); //there should be userid somewhere!
+                add_to_log($instance->courseid, 'course', 'enrol', '../enrol/users.php?id='.$instance->courseid, $instance->courseid); //TODO: There should be userid somewhere!
 
                 if ($instance->password and $instance->customint1 and $data->enrolpassword !== $instance->password) {
                     // it must be a group enrolment, let's assign group too
@@ -221,7 +241,7 @@ class enrol_self_plugin extends enrol_plugin {
                         }
                     }
                 }
-                // send welcome
+                // Send welcome message.
                 if ($instance->customint4) {
                     $this->email_welcome_message($instance, $USER);
                 }
@@ -237,7 +257,7 @@ class enrol_self_plugin extends enrol_plugin {
 
     /**
      * Add new instance of enrol plugin with default settings.
-     * @param object $course
+     * @param stdClass $course
      * @return int id of new instance
      */
     public function add_default_instance($course) {
@@ -245,6 +265,7 @@ class enrol_self_plugin extends enrol_plugin {
                         'customint2'  => $this->get_config('longtimenosee'),
                         'customint3'  => $this->get_config('maxenrolled'),
                         'customint4'  => $this->get_config('sendcoursewelcomemessage'),
+                        'customint5'  => 0,
                         'enrolperiod' => $this->get_config('enrolperiod', 0),
                         'status'      => $this->get_config('status'),
                         'roleid'      => $this->get_config('roleid', 0));
@@ -257,10 +278,10 @@ class enrol_self_plugin extends enrol_plugin {
     }
 
     /**
-     * Send welcome email to specified user
+     * Send welcome email to specified user.
      *
-     * @param object $instance
-     * @param object $user user record
+     * @param stdClass $instance
+     * @param stdClass $user user record
      * @return void
      */
     protected function email_welcome_message($instance, $user) {
@@ -304,12 +325,12 @@ class enrol_self_plugin extends enrol_plugin {
             $contact = generate_email_supportuser();
         }
 
-        //directly emailing welcome message rather than using messaging
+        // Directly emailing welcome message rather than using messaging.
         email_to_user($user, $contact, $subject, $messagetext, $messagehtml);
     }
 
     /**
-     * Enrol self cron support
+     * Enrol self cron support.
      * @return void
      */
     public function cron() {
@@ -323,10 +344,10 @@ class enrol_self_plugin extends enrol_plugin {
 
         $now = time();
 
-        //note: the logic of self enrolment guarantees that user logged in at least once (=== u.lastaccess set)
-        //      and that user accessed course at least once too (=== user_lastaccess record exists)
+        // Note: the logic of self enrolment guarantees that user logged in at least once (=== u.lastaccess set)
+        //       and that user accessed course at least once too (=== user_lastaccess record exists).
 
-        // first deal with users that did not log in for a really long time
+        // First deal with users that did not log in for a really long time.
         $sql = "SELECT e.*, ue.userid
                   FROM {user_enrolments} ue
                   JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = 'self' AND e.customint2 > 0)
@@ -341,7 +362,7 @@ class enrol_self_plugin extends enrol_plugin {
         }
         $rs->close();
 
-        // now unenrol from course user did not visit for a long time
+        // Now unenrol from course user did not visit for a long time.
         $sql = "SELECT e.*, ue.userid
                   FROM {user_enrolments} ue
                   JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = 'self' AND e.customint2 > 0)
@@ -360,7 +381,7 @@ class enrol_self_plugin extends enrol_plugin {
     }
 
      /**
-     * Gets an array of the user enrolment actions
+     * Gets an array of the user enrolment actions.
      *
      * @param course_enrolment_manager $manager
      * @param stdClass $ue A user enrolment object
@@ -388,7 +409,7 @@ class enrol_self_plugin extends enrol_plugin {
  * Indicates API features that the enrol plugin supports.
  *
  * @param string $feature
- * @return mixed True if yes (some features may use other values)
+ * @return mixed true if yes (some features may use other values)
  */
 function enrol_self_supports($feature) {
     switch($feature) {
index a189e7d..df78a2c 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Self enrol plugin implementation.
  *
- * @package    enrol
- * @subpackage self
+ * @package    enrol_self
  * @copyright  2010 Petr Skoda  {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -33,7 +31,7 @@ class enrol_self_enrol_form extends moodleform {
     protected $toomany = false;
 
     /**
-     * Overriding this function to get unique form id for multiple self enrolments
+     * Overriding this function to get unique form id for multiple self enrolments.
      *
      * @return string form identifier
      */
@@ -54,10 +52,10 @@ class enrol_self_enrol_form extends moodleform {
         $mform->addElement('header', 'selfheader', $heading);
 
         if ($instance->customint3 > 0) {
-            // max enrol limit specified
+            // Max enrol limit specified.
             $count = $DB->count_records('user_enrolments', array('enrolid'=>$instance->id));
             if ($count >= $instance->customint3) {
-                // bad luck, no more self enrolments here
+                // Bad luck, no more self enrolments here.
                 $this->toomany = true;
                 $mform->addElement('static', 'notice', '', get_string('maxenrolledreached', 'enrol_self'));
                 return;
@@ -65,7 +63,7 @@ class enrol_self_enrol_form extends moodleform {
         }
 
         if ($instance->password) {
-            //change the id of self enrolment key input as there can be multiple self enrolment methods
+            // Change the id of self enrolment key input as there can be multiple self enrolment methods.
             $mform->addElement('passwordunmask', 'enrolpassword', get_string('password', 'enrol_self'),
                     array('id' => 'enrolpassword_'.$instance->id));
         } else {
@@ -109,7 +107,7 @@ class enrol_self_enrol_form extends moodleform {
                         }
                     }
                     if (!$found) {
-                        // we can not hint because there are probably multiple passwords
+                        // We can not hint because there are probably multiple passwords.
                         $errors['enrolpassword'] = get_string('passwordinvalid', 'enrol_self');
                     }
 
index bab0909..c8c2f02 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Self enrolment plugin settings and presets.
  *
- * @package    enrol
- * @subpackage self
+ * @package    enrol_self
  * @copyright  2010 Petr Skoda  {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 02670f6..7e7d269 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
@@ -18,8 +17,7 @@
 /**
  * Self enrolment plugin - support for user self unenrolment.
  *
- * @package    enrol
- * @subpackage self
+ * @package    enrol_self
  * @copyright  2010 Petr Skoda  {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
@@ -41,7 +39,7 @@ require_login($course);
 
 $plugin = enrol_get_plugin('self');
 
-// security defined inside following function
+// Security defined inside following function.
 if (!$plugin->get_unenrolself_link($instance)) {
     redirect(new moodle_url('/course/view.php', array('id'=>$course->id)));
 }
@@ -51,7 +49,7 @@ $PAGE->set_title($plugin->get_instance_name($instance));
 
 if ($confirm and confirm_sesskey()) {
     $plugin->unenrol_user($instance, $USER->id);
-    add_to_log($course->id, 'course', 'unenrol', '../enrol/users.php?id='.$course->id, $course->id); //there should be userid somewhere!
+    add_to_log($course->id, 'course', 'unenrol', '../enrol/users.php?id='.$course->id, $course->id); //TODO: there should be userid somewhere!
     redirect(new moodle_url('/index.php'));
 }
 
index 73f1cde..1153b05 100644 (file)
 /**
  * Self enrolment plugin version specification.
  *
- * @package    enrol
- * @subpackage self
+ * @package    enrol_self
  * @copyright  2010 Petr Skoda  {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012061700;        // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2012061700;        // Requires this Moodle version
+$plugin->version   = 2012082300;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->requires  = 2012082300;        // Requires this Moodle version
 $plugin->component = 'enrol_self';      // Full name of the plugin (used for diagnostics)
 $plugin->cron      = 180;
\ No newline at end of file
index 868912d..8fcd760 100644 (file)
@@ -8,6 +8,9 @@ required changes in code:
 * use role_get_name() or role_fix_names() if you need any role names, using role.name
   directly from database is not correct any more
 
+other changes:
+* course enrolment manager now works with disabled plugins too
+
 
 === 2.2 ===
 
index f6001d2..4d8e3ae 100644 (file)
@@ -82,7 +82,7 @@ class core_files_external extends external_api {
         if (empty($fileinfo['contextid'])) {
             $context  = get_system_context();
         } else {
-            $context  = get_context_instance_by_id($fileinfo['contextid']);
+            $context  = context::instance_by_id($fileinfo['contextid']);
         }
         if (empty($fileinfo['component'])) {
             $fileinfo['component'] = null;
@@ -272,7 +272,7 @@ class core_files_external extends external_api {
         }
 
         if (!empty($fileinfo['contextid'])) {
-            $context = get_context_instance_by_id($fileinfo['contextid']);
+            $context = context::instance_by_id($fileinfo['contextid']);
         } else {
             $context = get_system_context();
         }
index cfa14e0..6a648b0 100644 (file)
@@ -965,7 +965,7 @@ class files_tree_viewer implements renderable {
         $this->path = array();
         while ($level) {
             $params = $level->get_params();
-            $context = get_context_instance_by_id($params['contextid']);
+            $context = context::instance_by_id($params['contextid']);
             // $this->context is current context
             if ($context->id != $this->context->id or empty($params['filearea'])) {
                 break;
index 9ba698a..61fe8e7 100644 (file)
@@ -89,7 +89,7 @@ function filter_algebra_image($imagefile, $tex= "", $height="", $width="", $alig
 }
 
 class filter_algebra extends moodle_text_filter {
-    function filter($text, array $options = array()){
+    public function filter($text, array $options = array()){
         global $CFG, $DB;
 
         /// Do a quick check using stripos to avoid unnecessary wor
@@ -114,9 +114,6 @@ class filter_algebra extends moodle_text_filter {
 #        return $text;
 #    }
 
-
-        $text .= ' ';
-
         preg_match_all('/@(@@+)([^@])/',$text,$matches);
         for ($i=0;$i<count($matches[0]);$i++) {
             $replacement = str_replace('@','&#x00040;',$matches[1][$i]).$matches[2][$i];
@@ -129,6 +126,17 @@ class filter_algebra extends moodle_text_filter {
         preg_match_all('/<algebra>(.+?)<\/algebra>|@@(.+?)@@/is', $text, $matches);
         for ($i=0; $i<count($matches[0]); $i++) {
             $algebra = $matches[1][$i] . $matches[2][$i];
+
+            // Look for some common false positives, and skip processing them.
+            if ($algebra == 'PLUGINFILE' || $algebra == 'DRAFTFILE') {
+                // Raw pluginfile URL.
+                continue;
+            }
+            if (preg_match('/^ -\d+(,\d+)? \+\d+(,\d+)? $/', $algebra)) {
+                // Part of a unified diff.
+                continue;
+            }
+
             $algebra = str_replace('<nolink>','',$algebra);
             $algebra = str_replace('</nolink>','',$algebra);
             $algebra = str_replace('<span class="nolink">','',$algebra);
@@ -159,7 +167,7 @@ class filter_algebra extends moodle_text_filter {
                $algebra = str_replace('upsilon','zupslon',$algebra);
                $algebra = preg_replace('!\r\n?!',' ',$algebra);
                $algebra = escapeshellarg($algebra);
-               if ( (PHP_OS == "WINNT") || (PHP_OS == "WIN32") || (PHP_OS == "Windows") ) {
+               if ( (PHP_OS == "WINNT") || (PHP_OS == "WIN32") || (PHP_OS == "Windows")) {
                   $cmd  = "cd $CFG->dirroot\\filter\\algebra & algebra2tex.pl $algebra";
                } else {
                   $cmd  = "cd $CFG->dirroot/filter/algebra; ./algebra2tex.pl $algebra";
@@ -220,6 +228,7 @@ class filter_algebra extends moodle_text_filter {
                   $texexp = preg_replace('/\\\int\\\left\((.+?d[a-z])\\\right\)/s','\int '. "\$1 ",$texexp);
                   $texexp = preg_replace('/\\\lim\\\left\((.+?),(.+?),(.+?)\\\right\)/s','\lim_'. "{\$2\\to \$3}\$1 ",$texexp);
                   $texexp = str_replace('\mbox', '', $texexp); // now blacklisted in tex, sorry
+                  $texcache = new stdClass();
                   $texcache->filter = 'algebra';
                   $texcache->version = 1;
                   $texcache->md5key = $md5;
diff --git a/filter/algebra/tests/filter_test.php b/filter/algebra/tests/filter_test.php
new file mode 100644 (file)
index 0000000..6c7db8f
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Unit test for the filter_algebra
+ *
+ * @package    filter_algebra
+ * @category   phpunit
+ * @copyright  2012 Tim Hunt
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot . '/filter/algebra/filter.php');
+
+
+/**
+ * Unit tests for filter_algebra.
+ *
+ * Note that this only tests some of the filter logic. It does not acutally test
+ * the normal case of the filter working, because I cannot make it work on my
+ * test server, and if it does not work here, it probably does not also work
+ * for other people. A failing test will be irritating noise.
+ *
+ * @copyright  2012 Tim Hunt
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class filter_algebra_testcase extends basic_testcase {
+
+    protected $filter;
+
+    protected function setUp() {
+        parent::setUp();
+        $this->filter = new filter_algebra(context_system::instance(), array());
+    }
+
+    function test_algebra_filter_no_algebra() {
+        $this->assertEquals('<p>Look no algebra!</p>',
+                $this->filter->filter('<p>Look no algebra!</p>'));
+    }
+
+
+    function test_algebra_filter_pluginfile() {
+        $this->assertEquals('<img src="@@PLUGINFILE@@/photo.jpg">',
+                $this->filter->filter('<img src="@@PLUGINFILE@@/photo.jpg">'));
+    }
+
+    function test_algebra_filter_draftfile() {
+        $this->assertEquals('<img src="@@DRAFTFILE@@/photo.jpg">',
+                $this->filter->filter('<img src="@@DRAFTFILE@@/photo.jpg">'));
+    }
+
+    function test_algebra_filter_unified_diff() {
+        $diff = '
+diff -u -r1.1 Worksheet.php
+--- Worksheet.php   26 Sep 2003 04:18:02 -0000  1.1
++++ Worksheet.php   18 Nov 2009 03:58:50 -0000
+@@ -1264,10 +1264,10 @@
+         }
+
+         // Strip the = or @ sign at the beginning of the formula string
+-        if (ereg("^=",$formula)) {
++        if (preg_match("/^=/",$formula)) {
+             $formula = preg_replace("/(^=)/","",$formula);
+         }
+-        elseif(ereg("^@",$formula)) {
++        elseif(preg_match("/^@/",$formula)) {
+             $formula = preg_replace("/(^@)/","",$formula);
+         }
+         else {
+';
+        $this->assertEquals('<pre>' . $diff . '</pre>',
+                $this->filter->filter('<pre>' . $diff . '</pre>'));
+    }
+}
index 6ada6f6..11c236c 100644 (file)
@@ -76,7 +76,6 @@ $string['save'] = 'Save';
 $string['saveguide'] = 'Save marking guide and make it ready';
 $string['saveguidedraft'] = 'Save as draft';
 $string['score'] = 'score';
-$string['showdescriptionstudent'] = 'Display description to those being graded';
 $string['showmarkerdesc'] = 'Show marker criterion descriptions';
 $string['showmarkspercriterionstudents'] = 'Show marks per criterion to students';
 $string['showstudentdesc'] = 'Show student criterion descriptions';
index 1990064..15ef0d7 100644 (file)
@@ -506,6 +506,7 @@ class gradingform_guide_controller extends gradingform_controller {
         $comments = $this->definition->guide_comment;
         $options = $this->get_options();
         $guide = '';
+        $guide .= $output->box($this->get_formatted_description(), 'gradingform_guide-description');
         if (has_capability('moodle/grade:managegradingforms', $page->context)) {
             $guide .= $output->display_guide_mapping_explained($this->get_min_max_score());
             $guide .= $output->display_guide($criteria, $comments, $options, self::DISPLAY_PREVIEW, 'guide');
@@ -872,10 +873,8 @@ class gradingform_guide_instance extends gradingform_instance {
             $html .= html_writer::tag('div', get_string('restoredfromdraft', 'gradingform_guide'),
                 array('class' => 'gradingform_guide-restored'));
         }
-        if (!empty($options['showdescriptionteacher'])) {
-            $html .= html_writer::tag('div', $this->get_controller()->get_formatted_description(),
-                array('class' => 'gradingform_guide-description'));
-        }
+        $html .= html_writer::tag('div', $this->get_controller()->get_formatted_description(),
+            array('class' => 'gradingform_guide-description'));
         $html .= $this->get_controller()->get_renderer($page)->display_guide($criteria, $comments, $options, $mode,
             $gradingformelement->getName(), $value, $this->validationerrors);
         return $html;
index ba8aa5d..a2c6501 100644 (file)
@@ -49,8 +49,5 @@ $PAGE->set_heading($title);
 
 echo $OUTPUT->header();
 echo $OUTPUT->heading($title);
-if (!empty($options['showdescriptionstudent'])) {
-    echo $OUTPUT->box($controller->get_formatted_description(), 'gradingform_guide-description');
-}
 echo $controller->render_preview($PAGE);
 echo $OUTPUT->footer();
index ae97eee..247724d 100644 (file)
@@ -508,6 +508,14 @@ class gradingform_rubric_controller extends gradingform_controller {
         $criteria = $this->definition->rubric_criteria;
         $options = $this->get_options();
         $rubric = '';
+        if (has_capability('moodle/grade:managegradingforms', $page->context)) {
+            $showdescription = true;
+        } else {
+            $showdescription = $options['showdescriptionstudent'];
+        }
+        if ($showdescription) {
+            $rubric .= $output->box($this->get_formatted_description(), 'gradingform_rubric-description');
+        }
         if (has_capability('moodle/grade:managegradingforms', $page->context)) {
             $rubric .= $output->display_rubric_mapping_explained($this->get_min_max_score());
             $rubric .= $output->display_rubric($criteria, $options, self::DISPLAY_PREVIEW, 'rubric');
index 1a71458..babdef4 100644 (file)
@@ -49,8 +49,5 @@ $PAGE->set_heading($title);
 
 echo $OUTPUT->header();
 echo $OUTPUT->heading($title);
-if (!empty($options['showdescriptionstudent'])) {
-    echo $OUTPUT->box($controller->get_formatted_description(), 'gradingform_rubric-description');
-}
 echo $controller->render_preview($PAGE);
 echo $OUTPUT->footer();
index c6e8186..0a3de68 100644 (file)
@@ -223,7 +223,7 @@ class grading_manager {
         global $DB;
 
         $this->areacache = $DB->get_record('grading_areas', array('id' => $areaid), '*', MUST_EXIST);
-        $this->context = get_context_instance_by_id($this->areacache->contextid, MUST_EXIST);
+        $this->context = context::instance_by_id($this->areacache->contextid, MUST_EXIST);
         $this->component = $this->areacache->component;
         $this->area = $this->areacache->areaname;
     }
index 954f91f..f796640 100644 (file)
@@ -57,7 +57,7 @@ if (!is_null($areaid)) {
     if (is_null($contextid) or is_null($component) or is_null($area)) {
         throw new coding_exception('The caller script must identify the gradable area.');
     }
-    $context = get_context_instance_by_id($contextid, MUST_EXIST);
+    $context = context::instance_by_id($contextid, MUST_EXIST);
     $manager = get_grading_manager($context, $component, $area);
 }
 
@@ -233,7 +233,6 @@ if (!empty($method)) {
             $tag = html_writer::tag('span', get_string('statusdraft', 'core_grading'), array('class' => 'status draft'));
         }
         echo $output->heading(s($definition->name) . ' ' . $tag, 3, 'definition-name');
-        echo $output->box($controller->get_formatted_description());
         echo $output->box($controller->render_preview($PAGE), 'definition-preview');
     }
 }
index 7765f82..37629eb 100644 (file)
@@ -2610,6 +2610,7 @@ abstract class grade_helper {
      * @return array
      */
     public static function get_info_letters($courseid) {
+        global $SITE;
         if (self::$letterinfo !== null) {
             return self::$letterinfo;
         }
@@ -2617,9 +2618,15 @@ abstract class grade_helper {
         $canmanage = has_capability('moodle/grade:manage', $context);
         $canmanageletters = has_capability('moodle/grade:manageletters', $context);
         if ($canmanage || $canmanageletters) {
+            // Redirect to system context when report is accessed from admin settings MDL-31633
+            if ($context->instanceid == $SITE->id) {
+                $param = array('edit' => 1);
+            } else {
+                $param = array('edit' => 1,'id' => $context->id);
+            }
             self::$letterinfo = array(
                 'view' => new grade_plugin_info('view', new moodle_url('/grade/edit/letter/index.php', array('id'=>$context->id)), get_string('view')),
-                'edit' => new grade_plugin_info('edit', new moodle_url('/grade/edit/letter/index.php', array('edit'=>1,'id'=>$context->id)), get_string('edit'))
+                'edit' => new grade_plugin_info('edit', new moodle_url('/grade/edit/letter/index.php', $param), get_string('edit'))
             );
         } else {
             self::$letterinfo = false;
index 0c17c81..f7599d7 100644 (file)
@@ -545,6 +545,9 @@ class core_group_external extends external_api {
             }
             require_capability('moodle/course:managegroups', $context);
 
+            if (!groups_remove_member_allowed($group, $user)) {
+                throw new moodle_exception('errorremovenotpermitted', 'group', '', fullname($user));
+            }
             groups_remove_member($group, $user);
         }
 
index 68d3385..e16bc01 100644 (file)
  *
  * @param mixed $grouporid  The group id or group object
  * @param mixed $userorid   The user id or user object
+ * @param string $component Optional component name e.g. 'enrol_imsenterprise'
+ * @param int $itemid Optional itemid associated with component
  * @return bool True if user added successfully or the user is already a
  * member of the group, false otherwise.
  */
-function groups_add_member($grouporid, $userorid) {
+function groups_add_member($grouporid, $userorid, $component=null, $itemid=0) {
     global $DB;
 
     if (is_object($userorid)) {
@@ -68,6 +70,25 @@ function groups_add_member($grouporid, $userorid) {
     $member->groupid   = $groupid;
     $member->userid    = $userid;
     $member->timeadded = time();
+    $member->component = '';
+    $member->itemid = 0;
+
+    // Check the component exists if specified
+    if (!empty($component)) {
+        $dir = get_component_directory($component);
+        if ($dir && is_dir($dir)) {
+            // Component exists and can be used
+            $member->component = $component;
+            $member->itemid = $itemid;
+        } else {
+            throw new coding_exception('Invalid call to groups_add_member(). An invalid component was specified');
+        }
+    }
+
+    if ($itemid !== 0 && empty($member->component)) {
+        // An itemid can only be specified if a valid component was found
+        throw new coding_exception('Invalid call to groups_add_member(). A component must be specified if an itemid is given');
+    }
 
     $DB->insert_record('groups_members', $member);
 
@@ -78,11 +99,62 @@ function groups_add_member($grouporid, $userorid) {
     $eventdata =&nbs