Merge branch 'w51_MDL-37125_m25_yui380' of git://github.com/skodak/moodle
authorDan Poltawski <dan@moodle.com>
Tue, 8 Jan 2013 06:29:32 +0000 (14:29 +0800)
committerDan Poltawski <dan@moodle.com>
Tue, 8 Jan 2013 06:29:32 +0000 (14:29 +0800)
444 files changed:
admin/filters.php
admin/settings/security.php
admin/tool/uploaduser/index.php
admin/user.php
auth/db/auth.php
auth/db/cli/sync_users.php
auth/db/db/install.php
auth/db/lang/en/auth_db.php
auth/db/tests/db_test.php [new file with mode: 0644]
auth/db/version.php
auth/shibboleth/index_form.html
auth/shibboleth/lang/en/auth_shibboleth.php
backup/backupfilesedit.php
backup/converter/moodle1/lib.php
backup/converter/moodle1/tests/lib_test.php
backup/moodle2/restore_stepslib.php
blocks/completionstatus/block_completionstatus.php
blocks/completionstatus/db/access.php
blocks/completionstatus/db/upgrade.php [new file with mode: 0644]
blocks/completionstatus/lang/en/block_completionstatus.php
blocks/completionstatus/version.php
blocks/course_summary/block_course_summary.php
blocks/course_summary/db/access.php
blocks/course_summary/db/upgrade.php [new file with mode: 0644]
blocks/course_summary/lang/en/block_course_summary.php
blocks/course_summary/version.php
blocks/dock.js
blocks/glossary_random/block_glossary_random.php
blocks/glossary_random/db/access.php
blocks/glossary_random/db/upgrade.php [new file with mode: 0644]
blocks/glossary_random/lang/en/block_glossary_random.php
blocks/glossary_random/version.php
blocks/mentees/block_mentees.php
blocks/mentees/db/access.php
blocks/mentees/db/upgrade.php [new file with mode: 0644]
blocks/mentees/lang/en/block_mentees.php
blocks/mentees/version.php
blocks/news_items/block_news_items.php
blocks/news_items/db/access.php
blocks/news_items/db/upgrade.php [new file with mode: 0644]
blocks/news_items/lang/en/block_news_items.php
blocks/news_items/version.php
blocks/online_users/block_online_users.php
blocks/online_users/db/access.php
blocks/online_users/db/upgrade.php [new file with mode: 0644]
blocks/online_users/lang/en/block_online_users.php
blocks/online_users/version.php
blocks/rss_client/backup/moodle2/restore_rss_client_stepslib.php
blocks/selfcompletion/block_selfcompletion.php
blocks/selfcompletion/db/access.php
blocks/selfcompletion/db/upgrade.php [new file with mode: 0644]
blocks/selfcompletion/lang/en/block_selfcompletion.php
blocks/selfcompletion/version.php
blocks/tags/edit_form.php
blocks/tags/lang/en/block_tags.php
blog/rsslib.php
cache/classes/loaders.php
cache/stores/static/lib.php
calendar/lib.php
calendar/managesubscriptions.php
calendar/renderer.php
comment/comment_post.php
course/category.php
course/dnduploadlib.php
course/lib.php
course/switchrole.php
enrol/category/cli/sync.php
enrol/category/lib.php
enrol/category/locallib.php
enrol/category/tests/sync_test.php
enrol/cohort/ajax.php
enrol/cohort/cli/sync.php
enrol/cohort/edit.php
enrol/cohort/lib.php
enrol/cohort/locallib.php
enrol/cohort/tests/sync_test.php
enrol/database/cli/sync.php
enrol/database/lib.php
enrol/database/tests/sync_test.php
enrol/ldap/lib.php
enrol/locallib.php
enrol/otherusers.php
enrol/renderer.php
files/renderer.php
filter/activitynames/db/install.php
filter/algebra/algebradebug.php
filter/algebra/pix.php
filter/manage.php
filter/mediaplugin/db/install.php
filter/tex/displaytex.php
filter/tex/pix.php
filter/tex/texdebug.php
filter/upgrade.txt
grade/edit/tree/lib.php
group/externallib.php
lang/en/admin.php
lang/en/block.php
lang/en/error.php
lang/en/moodle.php
lang/en/question.php
lang/en/repository.php
lib/adminlib.php
lib/authlib.php
lib/db/install.xml
lib/db/upgrade.php
lib/ddl/database_manager.php
lib/deprecatedlib.php
lib/editor/tinymce/lib.php
lib/editor/tinymce/plugins/dragmath/lib.php
lib/editor/tinymce/plugins/moodleemoticon/lib.php
lib/editor/tinymce/plugins/spellchecker/changelog.txt
lib/editor/tinymce/plugins/spellchecker/classes/GoogleSpell.php
lib/editor/tinymce/plugins/spellchecker/readme_moodle.txt
lib/editor/tinymce/readme_moodle.txt
lib/editor/tinymce/tiny_mce/3.5.7b/plugins/autolink/editor_plugin.js [deleted file]
lib/editor/tinymce/tiny_mce/3.5.7b/plugins/autosave/langs/en.js [deleted file]
lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/editor_plugin.js [deleted file]
lib/editor/tinymce/tiny_mce/3.5.7b/tiny_mce.js [deleted file]
lib/editor/tinymce/tiny_mce/3.5.8/langs/en.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/langs/en.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/license.txt [moved from lib/editor/tinymce/tiny_mce/3.5.7b/license.txt with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advhr/css/advhr.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advhr/css/advhr.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advhr/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advhr/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advhr/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advhr/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advhr/js/rule.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advhr/js/rule.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advhr/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advhr/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advhr/rule.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advhr/rule.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advimage/css/advimage.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advimage/css/advimage.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advimage/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advimage/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advimage/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advimage/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advimage/image.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advimage/image.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advimage/img/sample.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advimage/img/sample.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advimage/js/image.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advimage/js/image.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advimage/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advimage/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advlink/css/advlink.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advlink/css/advlink.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advlink/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advlink/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advlink/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advlink/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advlink/js/advlink.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advlink/js/advlink.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advlink/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advlink/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advlink/link.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advlink/link.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advlist/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advlist/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/advlist/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/advlist/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/autolink/editor_plugin.js [new file with mode: 0644]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/autolink/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/autolink/editor_plugin_src.js with 98% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/autoresize/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/autoresize/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/autoresize/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/autoresize/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/autosave/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/autosave/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/autosave/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/autosave/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/bbcode/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/bbcode/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/bbcode/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/bbcode/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/contextmenu/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/contextmenu/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/contextmenu/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/contextmenu/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/directionality/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/directionality/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/directionality/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/directionality/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/emotions.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/emotions.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-cool.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-cool.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-cry.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-cry.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-embarassed.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-embarassed.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-foot-in-mouth.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-foot-in-mouth.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-frown.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-frown.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-innocent.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-innocent.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-kiss.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-kiss.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-laughing.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-laughing.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-money-mouth.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-money-mouth.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-sealed.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-sealed.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-smile.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-smile.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-surprised.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-surprised.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-tongue-out.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-tongue-out.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-undecided.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-undecided.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-wink.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-wink.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/img/smiley-yell.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/img/smiley-yell.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/js/emotions.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/js/emotions.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/emotions/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/emotions/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/example/dialog.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/example/dialog.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/example/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/example/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/example/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/example/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/example/img/example.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/example/img/example.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/example/js/dialog.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/example/js/dialog.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/example/langs/en.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/example/langs/en.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/example/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/example/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/example_dependency/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/example_dependency/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/example_dependency/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/example_dependency/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/fullpage/css/fullpage.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/fullpage/css/fullpage.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/fullpage/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/fullpage/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/fullpage/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/fullpage/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/fullpage/fullpage.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/fullpage/fullpage.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/fullpage/js/fullpage.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/fullpage/js/fullpage.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/fullpage/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/fullpage/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/fullscreen/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/fullscreen/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/fullscreen/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/fullscreen/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/fullscreen/fullscreen.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/fullscreen/fullscreen.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/iespell/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/iespell/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/iespell/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/iespell/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/inlinepopups/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/inlinepopups/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/inlinepopups/skins/clearlooks2/img/alert.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/skins/clearlooks2/img/alert.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/inlinepopups/skins/clearlooks2/img/button.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/skins/clearlooks2/img/button.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/inlinepopups/skins/clearlooks2/img/corners.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/skins/clearlooks2/img/corners.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/inlinepopups/skins/clearlooks2/window.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/skins/clearlooks2/window.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/inlinepopups/template.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/inlinepopups/template.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/insertdatetime/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/insertdatetime/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/insertdatetime/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/insertdatetime/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/layer/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/layer/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/layer/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/layer/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/legacyoutput/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/legacyoutput/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/legacyoutput/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/legacyoutput/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/lists/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/lists/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/lists/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/lists/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/media/css/media.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/media/css/media.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/media/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/media/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/media/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/media/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/media/js/embed.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/media/js/embed.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/media/js/media.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/media/js/media.js with 90% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/media/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/media/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/media/media.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/media/media.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/media/moxieplayer.swf [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/media/moxieplayer.swf with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/nonbreaking/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/nonbreaking/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/nonbreaking/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/nonbreaking/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/noneditable/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/noneditable/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/noneditable/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/noneditable/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/pagebreak/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/pagebreak/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/pagebreak/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/pagebreak/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/paste/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/paste/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/paste/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/paste/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/paste/js/pastetext.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/paste/js/pastetext.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/paste/js/pasteword.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/paste/js/pasteword.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/paste/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/paste/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/paste/pastetext.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/paste/pastetext.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/paste/pasteword.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/paste/pasteword.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/preview/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/preview/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/preview/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/preview/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/preview/example.html [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/preview/example.html with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/preview/jscripts/embed.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/preview/jscripts/embed.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/preview/preview.html [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/preview/preview.html with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/print/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/print/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/print/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/print/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/save/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/save/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/save/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/save/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/searchreplace/css/searchreplace.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/searchreplace/css/searchreplace.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/searchreplace/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/searchreplace/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/searchreplace/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/searchreplace/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/searchreplace/js/searchreplace.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/searchreplace/js/searchreplace.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/searchreplace/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/searchreplace/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/searchreplace/searchreplace.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/searchreplace/searchreplace.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/spellchecker/css/content.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/spellchecker/css/content.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/spellchecker/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/spellchecker/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/spellchecker/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/spellchecker/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/spellchecker/img/wline.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/spellchecker/img/wline.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/style/css/props.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/style/css/props.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/style/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/style/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/style/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/style/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/style/js/props.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/style/js/props.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/style/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/style/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/style/props.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/style/props.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/style/readme.txt [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/style/readme.txt with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/tabfocus/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/tabfocus/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/tabfocus/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/tabfocus/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/cell.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/cell.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/css/cell.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/css/cell.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/css/row.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/css/row.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/css/table.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/css/table.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/editor_plugin.js [new file with mode: 0644]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/editor_plugin_src.js with 99% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/js/cell.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/js/cell.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/js/merge_cells.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/js/merge_cells.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/js/row.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/js/row.js with 91% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/js/table.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/js/table.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/merge_cells.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/merge_cells.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/row.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/row.htm with 89% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/table/table.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/table/table.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/template/blank.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/template/blank.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/template/css/template.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/template/css/template.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/template/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/template/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/template/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/template/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/template/js/template.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/template/js/template.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/template/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/template/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/template/template.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/template/template.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/visualblocks/css/visualblocks.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/visualblocks/css/visualblocks.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/visualblocks/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/visualblocks/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/visualblocks/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/visualblocks/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/visualchars/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/visualchars/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/visualchars/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/visualchars/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/wordcount/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/wordcount/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/wordcount/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/wordcount/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/abbr.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/abbr.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/acronym.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/acronym.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/attributes.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/attributes.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/cite.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/cite.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/css/attributes.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/css/attributes.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/css/popup.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/css/popup.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/del.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/del.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/editor_plugin.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/editor_plugin.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/editor_plugin_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/editor_plugin_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/ins.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/ins.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/js/abbr.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/js/abbr.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/js/acronym.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/js/acronym.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/js/attributes.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/js/attributes.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/js/cite.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/js/cite.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/js/del.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/js/del.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/js/element_common.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/js/element_common.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/js/ins.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/js/ins.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/plugins/xhtmlxtras/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/plugins/xhtmlxtras/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/about.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/about.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/anchor.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/anchor.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/charmap.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/charmap.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/color_picker.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/color_picker.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/editor_template.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/editor_template.js with 66% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/editor_template_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/editor_template_src.js with 96% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/image.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/image.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/img/colorpicker.jpg [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/img/colorpicker.jpg with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/img/flash.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/img/flash.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/img/icons.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/img/icons.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/img/iframe.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/img/iframe.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/img/pagebreak.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/img/pagebreak.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/img/quicktime.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/img/quicktime.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/img/realmedia.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/img/realmedia.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/img/shockwave.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/img/shockwave.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/img/trans.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/img/trans.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/img/video.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/img/video.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/img/windowsmedia.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/img/windowsmedia.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/js/about.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/js/about.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/js/anchor.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/js/anchor.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/js/charmap.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/js/charmap.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/js/color_picker.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/js/color_picker.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/js/image.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/js/image.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/js/link.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/js/link.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/js/source_editor.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/js/source_editor.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/langs/en.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/langs/en.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/langs/en_dlg.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/langs/en_dlg.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/link.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/link.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/shortcuts.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/shortcuts.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/default/content.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/default/content.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/default/dialog.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/default/dialog.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/default/img/buttons.png [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/default/img/buttons.png with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/default/img/items.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/default/img/items.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/default/img/menu_arrow.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/default/img/menu_arrow.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/default/img/menu_check.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/default/img/menu_check.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/default/img/progress.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/default/img/progress.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/default/img/tabs.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/default/img/tabs.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/default/ui.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/default/ui.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/highcontrast/content.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/highcontrast/content.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/highcontrast/dialog.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/highcontrast/dialog.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/highcontrast/ui.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/highcontrast/ui.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/o2k7/content.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/o2k7/content.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/o2k7/dialog.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/o2k7/dialog.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/o2k7/img/button_bg.png [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/o2k7/img/button_bg.png with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/o2k7/img/button_bg_black.png [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/o2k7/img/button_bg_black.png with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/o2k7/img/button_bg_silver.png [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/o2k7/img/button_bg_silver.png with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/o2k7/ui.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/o2k7/ui.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/o2k7/ui_black.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/o2k7/ui_black.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/skins/o2k7/ui_silver.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/skins/o2k7/ui_silver.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/advanced/source_editor.htm [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/advanced/source_editor.htm with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/simple/editor_template.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/simple/editor_template.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/simple/editor_template_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/simple/editor_template_src.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/simple/img/icons.gif [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/simple/img/icons.gif with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/simple/langs/en.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/simple/langs/en.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/simple/skins/default/content.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/simple/skins/default/content.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/simple/skins/default/ui.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/simple/skins/default/ui.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/simple/skins/o2k7/content.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/simple/skins/o2k7/content.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/simple/skins/o2k7/img/button_bg.png [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/simple/skins/o2k7/img/button_bg.png with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/themes/simple/skins/o2k7/ui.css [moved from lib/editor/tinymce/tiny_mce/3.5.7b/themes/simple/skins/o2k7/ui.css with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/tiny_mce.js [new file with mode: 0644]
lib/editor/tinymce/tiny_mce/3.5.8/tiny_mce_popup.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/tiny_mce_popup.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/tiny_mce_src.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/tiny_mce_src.js with 95% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/utils/editable_selects.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/utils/editable_selects.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/utils/form_utils.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/utils/form_utils.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/utils/mctabs.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/utils/mctabs.js with 100% similarity]
lib/editor/tinymce/tiny_mce/3.5.8/utils/validate.js [moved from lib/editor/tinymce/tiny_mce/3.5.7b/utils/validate.js with 100% similarity]
lib/editor/tinymce/upgrade.txt
lib/editor/tinymce/version.php
lib/filebrowser/file_info_context_course.php
lib/filebrowser/file_info_context_coursecat.php
lib/filelib.php
lib/filterlib.php
lib/moodlelib.php
lib/navigationlib.php
lib/outputlib.php
lib/outputrenderers.php
lib/outputrequirementslib.php
lib/pluginlib.php
lib/rsslib.php
lib/tests/authlib_test.php [new file with mode: 0644]
lib/tests/filter_test.php
lib/tests/textlib_test.php
lib/textlib.class.php
lib/thirdpartylibs.xml
lib/weblib.php
login/change_password.php
login/change_password_form.php
login/forgot_password.php
login/index.php
login/unlock_account.php [new file with mode: 0644]
mnet/lib.php
mod/assign/feedback/file/importziplib.php
mod/assign/feedback/file/locallib.php
mod/assign/feedback/offline/locallib.php
mod/assign/locallib.php
mod/assign/submission/comments/lib.php
mod/data/data.js
mod/data/edit.php
mod/data/field/file/field.class.php
mod/data/field/picture/field.class.php
mod/forum/db/services.php [new file with mode: 0644]
mod/forum/externallib.php [new file with mode: 0644]
mod/forum/lib.php
mod/forum/rsslib.php
mod/forum/subscribe.php
mod/forum/tests/externallib_test.php [new file with mode: 0644]
mod/forum/version.php
mod/quiz/lang/en/quiz.php
mod/quiz/mod_form.php
mod/quiz/settings.php
mod/scorm/report/reportlib.php
mod/upgrade.txt
mod/wiki/create.php
mod/wiki/filesedit.php
mod/wiki/pagelib.php
question/format/learnwise/format.php
question/format/learnwise/lang/en/qformat_learnwise.php
question/format/xml/format.php
question/preview.php
question/previewlib.php
question/type/multianswer/edit_multianswer_form.php
question/type/multianswer/question.php
question/type/multianswer/questiontype.php
question/type/multianswer/tests/helper.php
question/type/multianswer/tests/question_test.php
question/type/multianswer/tests/walkthrough_test.php
question/type/shortanswer/question.php
question/type/shortanswer/tests/question_test.php
report/outline/index.php
report/security/locallib.php
repository/s3/lib.php
tag/coursetags_add.php
theme/base/style/filemanager.css
user/files.php
user/profile.php
version.php

index c102666..64589cf 100644 (file)
@@ -35,7 +35,7 @@
     require_once($CFG->libdir . '/adminlib.php');
 
     $action = optional_param('action', '', PARAM_ALPHANUMEXT);
-    $filterpath = optional_param('filterpath', '', PARAM_PATH);
+    $filterpath = optional_param('filterpath', '', PARAM_SAFEDIR);
 
     require_login();
     $systemcontext = context_system::instance();
 
     case 'down':
         if (isset($filters[$filterpath])) {
-            $oldpos = $filters[$filterpath]->sortorder;
-            if ($oldpos <= count($filters)) {
-                filter_set_global_state($filterpath, $filters[$filterpath]->active, $oldpos + 1);
-            }
+            filter_set_global_state($filterpath, $filters[$filterpath]->active, 1);
         }
         break;
 
     case 'up':
         if (isset($filters[$filterpath])) {
             $oldpos = $filters[$filterpath]->sortorder;
-            if ($oldpos >= 1) {
-                filter_set_global_state($filterpath, $filters[$filterpath]->active, $oldpos - 1);
-            }
+            filter_set_global_state($filterpath, $filters[$filterpath]->active, -1);
         }
         break;
 
     case 'delete':
-        if (!empty($filternames[$filterpath])) {
-            $filtername = $filternames[$filterpath];
-        } else {
-            $filtername = $filterpath;
-        }
-
-        if (substr($filterpath, 0, 4) == 'mod/') {
-            $mod = basename($filterpath);
-            $a = new stdClass;
-            $a->filter = $filtername;
-            $a->module = get_string('modulename', $mod);
-            print_error('cannotdeletemodfilter', 'admin', $returnurl, $a);
-        }
-
         // If not yet confirmed, display a confirmation message.
         if (!optional_param('confirm', '', PARAM_BOOL)) {
+            $filtername = filter_get_name($filterpath);
+
             $title = get_string('deletefilterareyousure', 'admin', $filtername);
             echo $OUTPUT->header();
             echo $OUTPUT->heading($title);
         }
 
         // Do the deletion.
-        $title = get_string('deletingfilter', 'admin', $filtername);
+        $title = get_string('deletingfilter', 'admin', $filterpath);
         echo $OUTPUT->header();
         echo $OUTPUT->heading($title);
 
         filter_delete_all_for_filter($filterpath);
 
         $a = new stdClass;
-        $a->filter = $filtername;
-        $a->directory = $filterpath;
+        $a->filter = $filterpath;
+        $a->directory = "$CFG->dirroot/filter/$filterpath";
         echo $OUTPUT->box(get_string('deletefilterfiles', 'admin', $a), 'generalbox', 'notice');
         echo $OUTPUT->continue_button($returnurl);
         echo $OUTPUT->footer();
@@ -241,7 +224,7 @@ function get_table_row($filterinfo, $isfirstrow, $islastactive, $applytostrings)
     }
 
     // Disable/off/on
-    $select = new single_select(filters_action_url($filter, 'setstate'), 'newstate', $activechoices, $filterinfo->active, null, 'active' . basename($filter));
+    $select = new single_select(filters_action_url($filter, 'setstate'), 'newstate', $activechoices, $filterinfo->active, null, 'active' . $filter);
     $select->set_label(get_string('isactive', 'filters'), array('class' => 'accesshide'));
     $row[] = $OUTPUT->render($select);
 
@@ -263,25 +246,20 @@ function get_table_row($filterinfo, $isfirstrow, $islastactive, $applytostrings)
     $row[] = $updown;
 
     // Apply to strings.
-    $select = new single_select(filters_action_url($filter, 'setapplyto'), 'stringstoo', $applytochoices, $applytostrings, null, 'applyto' . basename($filter));
+    $select = new single_select(filters_action_url($filter, 'setapplyto'), 'stringstoo', $applytochoices, $applytostrings, null, 'applyto' . $filter);
     $select->set_label(get_string('applyto', 'filters'), array('class' => 'accesshide'));
     $select->disabled = $filterinfo->active == TEXTFILTER_DISABLED;
     $row[] = $OUTPUT->render($select);
 
     // Settings link, if required
     if (filter_has_global_settings($filter)) {
-        $row[] = '<a href="' . $CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=filtersetting' .
-                str_replace('/', '',$filter) . '">' . get_string('settings') . '</a>';
+        $row[] = '<a href="' . $CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=filtersetting' . $filter . '">' . get_string('settings') . '</a>';
     } else {
         $row[] = '';
     }
 
     // Delete
-    if (substr($filter, 0, 4) != 'mod/') {
-        $row[] = '<a href="' . filters_action_url($filter, 'delete') . '">' . get_string('delete') . '</a>';
-    } else {
-        $row[] = '';
-    }
+    $row[] = '<a href="' . filters_action_url($filter, 'delete') . '">' . get_string('delete') . '</a>';
 
     return $row;
 }
index 189bf87..94b379d 100644 (file)
@@ -59,6 +59,11 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
     $temp->add(new admin_setting_configcheckbox('cronclionly', new lang_string('cronclionly', 'admin'), new lang_string('configcronclionly', 'admin'), 0));
     $temp->add(new admin_setting_configpasswordunmask('cronremotepassword', new lang_string('cronremotepassword', 'admin'), new lang_string('configcronremotepassword', 'admin'), ''));
 
+    $options = array(0=>get_string('no'), 3=>3, 5=>5, 7=>7, 10=>10, 20=>20, 30=>30, 50=>50, 100=>100);
+    $temp->add(new admin_setting_configselect('lockoutthreshold', new lang_string('lockoutthreshold', 'admin'), new lang_string('lockoutthreshold_desc', 'admin'), 0, $options));
+    $temp->add(new admin_setting_configduration('lockoutwindow', new lang_string('lockoutwindow', 'admin'), new lang_string('lockoutwindow_desc', 'admin'), 60*30));
+    $temp->add(new admin_setting_configduration('lockoutduration', new lang_string('lockoutduration', 'admin'), new lang_string('lockoutduration_desc', 'admin'), 60*30));
+
     $temp->add(new admin_setting_configcheckbox('passwordpolicy', new lang_string('passwordpolicy', 'admin'), new lang_string('configpasswordpolicy', 'admin'), 1));
     $temp->add(new admin_setting_configtext('minpasswordlength', new lang_string('minpasswordlength', 'admin'), new lang_string('configminpasswordlength', 'admin'), 8, PARAM_INT));
     $temp->add(new admin_setting_configtext('minpassworddigits', new lang_string('minpassworddigits', 'admin'), new lang_string('configminpassworddigits', 'admin'), 1, PARAM_INT));
index 632cfe1..9a6a104 100644 (file)
@@ -285,7 +285,11 @@ if ($formdata = $mform2->is_cancelled()) {
             $userserrors++;
             continue;
         }
-
+        if ($user->username !== clean_param($user->username, PARAM_USERNAME)) {
+            $upt->track('status', get_string('invalidusername', 'error', 'username'), 'error');
+            $upt->track('username', $errorstr, 'error');
+            $userserrors++;
+        }
         if ($existinguser = $DB->get_record('user', array('username'=>$user->username, 'mnethostid'=>$CFG->mnet_localhost_id))) {
             $upt->track('id', $existinguser->id, 'normal', false);
         }
index 97f1abb..aac7112 100644 (file)
@@ -2,6 +2,7 @@
 
     require_once('../config.php');
     require_once($CFG->libdir.'/adminlib.php');
+    require_once($CFG->libdir.'/authlib.php');
     require_once($CFG->dirroot.'/user/filters/lib.php');
 
     $delete       = optional_param('delete', 0, PARAM_INT);
@@ -16,6 +17,7 @@
     $acl          = optional_param('acl', '0', PARAM_INT);           // id of user to tweak mnet ACL (requires $access)
     $suspend      = optional_param('suspend', 0, PARAM_INT);
     $unsuspend    = optional_param('unsuspend', 0, PARAM_INT);
+    $unlock       = optional_param('unlock', 0, PARAM_INT);
 
     admin_externalpage_setup('editusers');
 
@@ -32,6 +34,7 @@
     $strshowallusers = get_string('showallusers');
     $strsuspend = get_string('suspenduser', 'admin');
     $strunsuspend = get_string('unsuspenduser', 'admin');
+    $strunlock = get_string('unlockaccount', 'admin');
     $strconfirm = get_string('confirm');
 
     if (empty($CFG->loginhttps)) {
             }
         }
         redirect($returnurl);
+
+    } else if ($unlock and confirm_sesskey()) {
+        require_capability('moodle/user:update', $sitecontext);
+
+        if ($user = $DB->get_record('user', array('id'=>$unlock, 'mnethostid'=>$CFG->mnet_localhost_id, 'deleted'=>0))) {
+            login_unlock_account($user);
+        }
+        redirect($returnurl);
     }
 
     // create the user filter form
                         }
                     }
 
+                    if (login_is_lockedout($user)) {
+                        $buttons[] = html_writer::link(new moodle_url($returnurl, array('unlock'=>$user->id, 'sesskey'=>sesskey())), html_writer::empty_tag('img', array('src'=>$OUTPUT->pix_url('t/unlock'), 'alt'=>$strunlock, 'class'=>'iconsmall')), array('title'=>$strunlock));
+                    }
                 }
             }
 
index 4c95249..57c46e4 100644 (file)
@@ -1,11 +1,25 @@
 <?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/>.
+
 /**
  * Authentication Plugin: External Database Authentication
  *
  * Checks against an external database.
  *
- * @package    auth
- * @subpackage db
+ * @package    auth_db
  * @author     Martin Dougiamas
  * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License
  */
@@ -13,7 +27,6 @@
 defined('MOODLE_INTERNAL') || die();
 
 require_once($CFG->libdir.'/authlib.php');
-require_once($CFG->libdir.'/adodb/adodb.inc.php');
 
 /**
  * External database authentication plugin.
@@ -23,7 +36,10 @@ class auth_plugin_db extends auth_plugin_base {
     /**
      * Constructor.
      */
-    function auth_plugin_db() {
+    function __construct() {
+        global $CFG;
+        require_once($CFG->libdir.'/adodb/adodb.inc.php');
+
         $this->authtype = 'db';
         $this->config = get_config('auth/db');
         if (empty($this->config->extencoding)) {
@@ -37,7 +53,6 @@ class auth_plugin_db extends auth_plugin_base {
      *
      * @param string $username The username
      * @param string $password The password
-     *
      * @return bool Authentication success or failure.
      */
     function user_login($username, $password) {
@@ -47,9 +62,9 @@ class auth_plugin_db extends auth_plugin_base {
         $extpassword = textlib::convert($password, 'utf-8', $this->config->extencoding);
 
         if ($this->is_internal()) {
-            // lookup username externally, but resolve
+            // Lookup username externally, but resolve
             // password locally -- to support backend that
-            // don't track passwords
+            // don't track passwords.
 
             if (isset($this->config->removeuser) and $this->config->removeuser == AUTH_REMOVEUSER_KEEP) {
                 // No need to connect to external database in this case because users are never removed and we verify password locally.
@@ -62,8 +77,9 @@ class auth_plugin_db extends auth_plugin_base {
 
             $authdb = $this->db_init();
 
-            $rs = $authdb->Execute("SELECT * FROM {$this->config->table}
-                                     WHERE {$this->config->fielduser} = '".$this->ext_addslashes($extusername)."' ");
+            $rs = $authdb->Execute("SELECT *
+                                      FROM {$this->config->table}
+                                     WHERE {$this->config->fielduser} = '".$this->ext_addslashes($extusername)."'");
             if (!$rs) {
                 $authdb->Close();
                 debugging(get_string('auth_dbcantconnect','auth_db'));
@@ -73,32 +89,32 @@ class auth_plugin_db extends auth_plugin_base {
             if (!$rs->EOF) {
                 $rs->Close();
                 $authdb->Close();
-                // user exists externally
-                // check username/password internally
+                // User exists externally - check username/password internally.
                 if ($user = $DB->get_record('user', array('username'=>$username, 'mnethostid'=>$CFG->mnet_localhost_id, 'auth'=>$this->authtype))) {
                     return validate_internal_user_password($user, $password);
                 }
             } else {
                 $rs->Close();
                 $authdb->Close();
-                // user does not exist externally
+                // User does not exist externally.
                 return false;
             }
 
         } else {
-            // normal case: use external db for both usernames and passwords
+            // Normal case: use external db for both usernames and passwords.
 
             $authdb = $this->db_init();
 
-            if ($this->config->passtype === 'md5') {   // Re-format password accordingly
+            if ($this->config->passtype === 'md5') {   // Re-format password accordingly.
                 $extpassword = md5($extpassword);
             } else if ($this->config->passtype === 'sha1') {
                 $extpassword = sha1($extpassword);
             }
 
-            $rs = $authdb->Execute("SELECT * FROM {$this->config->table}
-                                WHERE {$this->config->fielduser} = '".$this->ext_addslashes($extusername)."'
-                                  AND {$this->config->fieldpass} = '".$this->ext_addslashes($extpassword)."' ");
+            $rs = $authdb->Execute("SELECT *
+                                      FROM {$this->config->table}
+                                     WHERE {$this->config->fielduser} = '".$this->ext_addslashes($extusername)."'
+                                           AND {$this->config->fieldpass} = '".$this->ext_addslashes($extpassword)."'");
             if (!$rs) {
                 $authdb->Close();
                 debugging(get_string('auth_dbcantconnect','auth_db'));
@@ -119,11 +135,11 @@ class auth_plugin_db extends auth_plugin_base {
     }
 
     function db_init() {
-        // Connect to the external database (forcing new connection)
+        // Connect to the external database (forcing new connection).
         $authdb = ADONewConnection($this->config->type);
         if (!empty($this->config->debugauthdb)) {
             $authdb->debug = true;
-            ob_start();//start output buffer to allow later use of the page headers
+            ob_start(); //Start output buffer to allow later use of the page headers.
         }
         $authdb->Connect($this->config->host, $this->config->user, $this->config->pass, $this->config->name, true);
         $authdb->SetFetchMode(ADODB_FETCH_ASSOC);
@@ -135,7 +151,7 @@ class auth_plugin_db extends auth_plugin_base {
     }
 
     /**
-     * Returns user attribute mappings between moodle and ldap
+     * Returns user attribute mappings between moodle and ldap.
      *
      * @return array
      */
@@ -152,11 +168,10 @@ class auth_plugin_db extends auth_plugin_base {
 
     /**
      * Reads any other information for a user from external database,
-     * then returns it in an array
+     * then returns it in an array.
      *
      * @param string $username
-     *
-     * @return array without magic quotes
+     * @return array
      */
     function get_userinfo($username) {
         global $CFG;
@@ -165,22 +180,22 @@ class auth_plugin_db extends auth_plugin_base {
 
         $authdb = $this->db_init();
 
-        //Array to map local fieldnames we want, to external fieldnames
+        // Array to map local fieldnames we want, to external fieldnames.
         $selectfields = $this->db_attributes();
 
         $result = array();
-        //If at least one field is mapped from external db, get that mapped data:
+        // If at least one field is mapped from external db, get that mapped data.
         if ($selectfields) {
-            $select = '';
+            $select = array();
             foreach ($selectfields as $localname=>$externalname) {
-                $select .= ", $externalname AS $localname";
+                $select[] = "$externalname AS $localname";
             }
-            $select = 'SELECT ' . substr($select,1);
-            $sql = $select .
-                " FROM {$this->config->table}" .
-                " WHERE {$this->config->fielduser} = '".$this->ext_addslashes($extusername)."'";
+            $select = implode(', ', $select);
+            $sql = "SELECT $select
+                      FROM {$this->config->table}
+                     WHERE {$this->config->fielduser} = '".$this->ext_addslashes($extusername)."'";
             if ($rs = $authdb->Execute($sql)) {
-                if ( !$rs->EOF ) {
+                if (!$rs->EOF) {
                     $fields_obj = $rs->FetchObj();
                     $fields_obj = (object)array_change_key_case((array)$fields_obj , CASE_LOWER);
                     foreach ($selectfields as $localname=>$externalname) {
@@ -195,12 +210,11 @@ class auth_plugin_db extends auth_plugin_base {
     }
 
     /**
-     * Change a user's password
+     * Change a user's password.
      *
-     * @param  object  $user        User table object
+     * @param  stdClass  $user      User table object
      * @param  string  $newpassword Plaintext password
-     *
-     * @return bool                  True on success
+     * @return bool                 True on success
      */
     function user_update_password($user, $newpassword) {
         global $DB;
@@ -214,13 +228,13 @@ class auth_plugin_db extends auth_plugin_base {
                 return false;
             }
         } else {
-            // we should have never been called!
+            // We should have never been called!
             return false;
         }
     }
 
     /**
-     * synchronizes user from external db to moodle user table
+     * Synchronizes user from external db to moodle user table.
      *
      * Sync should be done by using idnumber attribute, not username.
      * You need to pass firstsync parameter to function to fill in
@@ -231,17 +245,17 @@ class auth_plugin_db extends auth_plugin_base {
      *
      * This implementation is simpler but less scalable than the one found in the LDAP module.
      *
+     * @param progress_trace $trace
      * @param bool $do_updates  Optional: set to true to force an update of existing accounts
-     * @param bool $verbose
      * @return int 0 means success, 1 means failure
      */
-    function sync_users($do_updates=false, $verbose=false) {
+    function sync_users(progress_trace $trace, $do_updates=false) {
         global $CFG, $DB;
 
-        // list external users
+        // List external users.
         $userlist = $this->get_userlist();
 
-        // delete obsolete internal users
+        // Delete obsolete internal users.
         if (!empty($this->config->removeuser)) {
 
             $suspendselect = "";
@@ -249,7 +263,7 @@ class auth_plugin_db extends auth_plugin_base {
                 $suspendselect = "AND u.suspended = 0";
             }
 
-            // find obsolete users
+            // Find obsolete users.
             if (count($userlist)) {
                 list($notin_sql, $params) = $DB->get_in_or_equal($userlist, SQL_PARAMS_NAMED, 'u', false);
                 $params['authtype'] = $this->authtype;
@@ -267,56 +281,46 @@ class auth_plugin_db extends auth_plugin_base {
             $remove_users = $DB->get_records_sql($sql, $params);
 
             if (!empty($remove_users)) {
-                if ($verbose) {
-                    mtrace(get_string('auth_dbuserstoremove','auth_db', count($remove_users)));
-                }
+                $trace->output(get_string('auth_dbuserstoremove','auth_db', count($remove_users)));
 
                 foreach ($remove_users as $user) {
                     if ($this->config->removeuser == AUTH_REMOVEUSER_FULLDELETE) {
                         delete_user($user);
-                        if ($verbose) {
-                            mtrace("\t".get_string('auth_dbdeleteuser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)));
-                        }
+                        $trace->output(get_string('auth_dbdeleteuser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)), 1);
                     } else if ($this->config->removeuser == AUTH_REMOVEUSER_SUSPEND) {
                         $updateuser = new stdClass();
                         $updateuser->id   = $user->id;
                         $updateuser->suspended = 1;
                         $updateuser->timemodified = time();
                         $DB->update_record('user', $updateuser);
-                        if ($verbose) {
-                            mtrace("\t".get_string('auth_dbsuspenduser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)));
-                        }
+                        $trace->output(get_string('auth_dbsuspenduser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)), 1);
                     }
                 }
             }
-            unset($remove_users); // free mem!
+            unset($remove_users);
         }
 
         if (!count($userlist)) {
-            // exit right here
-            // nothing else to do
+            // Exit right here, nothing else to do.
+            $trace->finished();
             return 0;
         }
 
-        ///
-        /// update existing accounts
-        ///
+        // Update existing accounts.
         if ($do_updates) {
-            // narrow down what fields we need to update
+            // Narrow down what fields we need to update.
             $all_keys = array_keys(get_object_vars($this->config));
             $updatekeys = array();
             foreach ($all_keys as $key) {
                 if (preg_match('/^field_updatelocal_(.+)$/',$key, $match)) {
                     if ($this->config->{$key} === 'onlogin') {
-                        array_push($updatekeys, $match[1]); // the actual key name
+                        array_push($updatekeys, $match[1]); // The actual key name.
                     }
                 }
             }
-            // print_r($all_keys); print_r($updatekeys);
             unset($all_keys); unset($key);
 
-            // only go ahead if we actually
-            // have fields to update locally
+            // Only go ahead if we actually have fields to update locally.
             if (!empty($updatekeys)) {
                 list($in_sql, $params) = $DB->get_in_or_equal($userlist, SQL_PARAMS_NAMED, 'u', true);
                 $params['authtype'] = $this->authtype;
@@ -324,32 +328,23 @@ class auth_plugin_db extends auth_plugin_base {
                           FROM {user} u
                          WHERE u.auth=:authtype AND u.deleted=0 AND u.username {$in_sql}";
                 if ($update_users = $DB->get_records_sql($sql, $params)) {
-                    if ($verbose) {
-                        mtrace("User entries to update: ".count($update_users));
-                    }
+                    $trace->output("User entries to update: ".count($update_users));
 
                     foreach ($update_users as $user) {
                         if ($this->update_user_record($user->username, $updatekeys)) {
-                            if ($verbose) {
-                                mtrace("\t".get_string('auth_dbupdatinguser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)));
-                            }
+                            $trace->output(get_string('auth_dbupdatinguser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)), 1);
                         } else {
-                            if ($verbose) {
-                                mtrace("\t".get_string('auth_dbupdatinguser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id))." - ".get_string('skipped'));
-                            }
+                            $trace->output(get_string('auth_dbupdatinguser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id))." - ".get_string('skipped'), 1);
                         }
                     }
-                    unset($update_users); // free memory
+                    unset($update_users);
                 }
             }
         }
 
 
-        ///
-        /// create missing accounts
-        ///
-        // NOTE: this is very memory intensive
-        // and generally inefficient
+        // Create missing accounts.
+        // NOTE: this is very memory intensive and generally inefficient.
         $suspendselect = "";
         if ($this->config->removeuser == AUTH_REMOVEUSER_SUSPEND) {
             $suspendselect = "AND u.suspended = 0";
@@ -360,7 +355,7 @@ class auth_plugin_db extends auth_plugin_base {
 
         $users = $DB->get_records_sql($sql, array('authtype'=>$this->authtype, 'mnethostid'=>$CFG->mnet_localhost_id));
 
-        // simplify down to usernames
+        // Simplify down to usernames.
         $usernames = array();
         if (!empty($users)) {
             foreach ($users as $user) {
@@ -373,25 +368,21 @@ class auth_plugin_db extends auth_plugin_base {
         unset($usernames);
 
         if (!empty($add_users)) {
-            if ($verbose) {
-                mtrace(get_string('auth_dbuserstoadd','auth_db',count($add_users)));
-            }
+            $trace->output(get_string('auth_dbuserstoadd','auth_db',count($add_users)));
             // Do not use transactions around this foreach, we want to skip problematic users, not revert everything.
             foreach($add_users as $user) {
                 $username = $user;
                 if ($this->config->removeuser == AUTH_REMOVEUSER_SUSPEND) {
                     if ($old_user = $DB->get_record('user', array('username'=>$username, 'deleted'=>0, 'suspended'=>1, 'mnethostid'=>$CFG->mnet_localhost_id, 'auth'=>$this->authtype))) {
                         $DB->set_field('user', 'suspended', 0, array('id'=>$old_user->id));
-                        if ($verbose) {
-                            mtrace("\t".get_string('auth_dbreviveduser', 'auth_db', array('name'=>$username, 'id'=>$old_user->id)));
-                        }
+                        $trace->output(get_string('auth_dbreviveduser', 'auth_db', array('name'=>$username, 'id'=>$old_user->id)), 1);
                         continue;
                     }
                 }
 
                 // Do not try to undelete users here, instead select suspending if you ever expect users will reappear.
 
-                // prep a few params
+                // Prep a few params.
                 $user = $this->get_userinfo_asobj($user);
                 $user->username   = $username;
                 $user->confirmed  = 1;
@@ -403,23 +394,17 @@ class auth_plugin_db extends auth_plugin_base {
                 $user->timecreated = time();
                 $user->timemodified = $user->timecreated;
                 if ($collision = $DB->get_record_select('user', "username = :username AND mnethostid = :mnethostid AND auth <> :auth", array('username'=>$user->username, 'mnethostid'=>$CFG->mnet_localhost_id, 'auth'=>$this->authtype), 'id,username,auth')) {
-                    if ($verbose) {
-                        mtrace("\t".get_string('auth_dbinsertuserduplicate', 'auth_db', array('username'=>$user->username, 'auth'=>$collision->auth)));
-                    }
+                    $trace->output(get_string('auth_dbinsertuserduplicate', 'auth_db', array('username'=>$user->username, 'auth'=>$collision->auth)), 1);
                     continue;
                 }
                 try {
                     $id = $DB->insert_record ('user', $user); // it is truly a new user
-                    if ($verbose) {
-                        mtrace("\t".get_string('auth_dbinsertuser', 'auth_db', array('name'=>$user->username, 'id'=>$id)));
-                    }
+                    $trace->output(get_string('auth_dbinsertuser', 'auth_db', array('name'=>$user->username, 'id'=>$id)), 1);
                 } catch (moodle_exception $e) {
-                    if ($verbose) {
-                        mtrace("\t".get_string('auth_dbinsertusererror', 'auth_db', $user->username));
-                    }
+                    $trace->output(get_string('auth_dbinsertusererror', 'auth_db', $user->username), 1);
                     continue;
                 }
-                // if relevant, tag for password generation
+                // If relevant, tag for password generation.
                 if ($this->is_internal()) {
                     set_user_preference('auth_forcepasswordchange', 1, $id);
                     set_user_preference('create_password',          1, $id);
@@ -427,27 +412,29 @@ class auth_plugin_db extends auth_plugin_base {
                 // Make sure user context is present.
                 context_user::instance($id);
             }
-            unset($add_users); // free mem
+            unset($add_users);
         }
+        $trace->finished();
         return 0;
     }
 
     function user_exists($username) {
 
-    /// Init result value
+        // Init result value.
         $result = false;
 
         $extusername = textlib::convert($username, 'utf-8', $this->config->extencoding);
 
         $authdb = $this->db_init();
 
-        $rs = $authdb->Execute("SELECT * FROM {$this->config->table}
-                                     WHERE {$this->config->fielduser} = '".$this->ext_addslashes($extusername)."' ");
+        $rs = $authdb->Execute("SELECT *
+                                  FROM {$this->config->table}
+                                 WHERE {$this->config->fielduser} = '".$this->ext_addslashes($extusername)."' ");
 
         if (!$rs) {
             print_error('auth_dbcantconnect','auth_db');
         } else if (!$rs->EOF) {
-            // user exists externally
+            // User exists externally.
             $result = true;
         }
 
@@ -458,14 +445,14 @@ class auth_plugin_db extends auth_plugin_base {
 
     function get_userlist() {
 
-    /// Init result value
+        // Init result value.
         $result = array();
 
         $authdb = $this->db_init();
 
-        // fetch userlist
+        // Fetch userlist.
         $rs = $authdb->Execute("SELECT {$this->config->fielduser} AS username
-                                FROM   {$this->config->table} ");
+                                  FROM {$this->config->table} ");
 
         if (!$rs) {
             print_error('auth_dbcantconnect','auth_db');
@@ -481,9 +468,9 @@ class auth_plugin_db extends auth_plugin_base {
     }
 
     /**
-     * reads user information from DB and return it in an object
+     * Reads user information from DB and return it in an object.
      *
-     * @param string $username username (with system magic quotes)
+     * @param string $username username
      * @return array
      */
     function get_userinfo_asobj($username) {
@@ -498,7 +485,7 @@ class auth_plugin_db extends auth_plugin_base {
     /**
      * will update a local user record from an external source.
      * is a lighter version of the one in moodlelib -- won't do
-     * expensive ops such as enrolment
+     * expensive ops such as enrolment.
      *
      * If you don't pass $updatekeys, there is a performance hit and
      * values removed from DB won't be removed from moodle.
@@ -521,14 +508,14 @@ class auth_plugin_db extends auth_plugin_base {
             die;
         }
 
-        // Ensure userid is not overwritten
+        // Ensure userid is not overwritten.
         $userid = $user->id;
         $updated = false;
 
         if ($newinfo = $this->get_userinfo($username)) {
             $newinfo = truncate_userinfo($newinfo);
 
-            if (empty($updatekeys)) { // all keys? this does not support removing values
+            if (empty($updatekeys)) { // All keys? This does not support removing values.
                 $updatekeys = array_keys($newinfo);
             }
 
@@ -540,7 +527,7 @@ class auth_plugin_db extends auth_plugin_base {
                 }
 
                 if (!empty($this->config->{'field_updatelocal_' . $key})) {
-                    if (isset($user->{$key}) and $user->{$key} != $value) { // only update if it's changed
+                    if (isset($user->{$key}) and $user->{$key} != $value) { // Only update if it's changed.
                         $DB->set_field('user', $key, $value, array('id'=>$userid));
                         $updated = true;
                     }
@@ -558,8 +545,8 @@ class auth_plugin_db extends auth_plugin_base {
      * Modifies user in external database. It takes olduser (before changes) and newuser (after changes)
      * compares information saved modified information to external db.
      *
-     * @param mixed $olduser     Userobject before modifications
-     * @param mixed $newuser     Userobject new modified userobject
+     * @param stdClass $olduser     Userobject before modifications
+     * @param stdClass $newuser     Userobject new modified userobject
      * @return boolean result
      *
      */
@@ -570,7 +557,7 @@ class auth_plugin_db extends auth_plugin_base {
         }
 
         if (isset($olduser->auth) and $olduser->auth != $this->authtype) {
-            return true; // just change auth and skip update
+            return true; // Just change auth and skip update.
         }
 
         $curruser = $this->get_userinfo($olduser->username);
@@ -586,10 +573,10 @@ class auth_plugin_db extends auth_plugin_base {
         $update = array();
         foreach($curruser as $key=>$value) {
             if ($key == 'username') {
-                continue; // skip this
+                continue; // Skip this.
             }
             if (empty($this->config->{"field_updateremote_$key"})) {
-                continue; // remote update not requested
+                continue; // Remote update not requested.
             }
             if (!isset($newuser->$key)) {
                 continue;
@@ -612,8 +599,8 @@ class auth_plugin_db extends auth_plugin_base {
      * A chance to validate form data, and last chance to
      * do stuff before it is inserted in config_plugin
      *
-     * @param stfdClass config form
-     * @param array $error errors
+     * @param stfdClass $form
+     * @param array $err errors
      * @return void
      */
      function validate_form($form, &$err) {
@@ -670,10 +657,10 @@ class auth_plugin_db extends auth_plugin_base {
      */
     function change_password_url() {
         if ($this->is_internal()) {
-            // standard form
+            // Standard form.
             return null;
         } else {
-            // use admin defined custom url
+            // Use admin defined custom url.
             return new moodle_url($this->config->changepasswordurl);
         }
     }
@@ -704,6 +691,7 @@ class auth_plugin_db extends auth_plugin_base {
 
     /**
      * Processes and stores configuration data for this authentication plugin.
+     *
      * @param srdClass $config
      * @return bool always true or exception
      */
@@ -755,7 +743,7 @@ class auth_plugin_db extends auth_plugin_base {
             $config->changepasswordurl = '';
         }
 
-        // save settings
+        // Save settings.
         set_config('host',          $config->host,          'auth/db');
         set_config('type',          $config->type,          'auth/db');
         set_config('sybasequoting', $config->sybasequoting, 'auth/db');
@@ -775,8 +763,13 @@ class auth_plugin_db extends auth_plugin_base {
         return true;
     }
 
+    /**
+     * Add slashes, we can not use placeholders or system functions.
+     *
+     * @param string $text
+     * @return string
+     */
     function ext_addslashes($text) {
-        // using custom made function for now
         if (empty($this->config->sybasequoting)) {
             $text = str_replace('\\', '\\\\', $text);
             $text = str_replace(array('\'', '"', "\0"), array('\\\'', '\\"', '\\0'), $text);
index 20ef137..f84bf2f 100644 (file)
@@ -23,7 +23,7 @@
  *
  * Sample cron entry:
  * # 5 minutes past 4am
- * 5 4 * * * $sudo -u www-data /usr/bin/php /var/www/moodle/auth/db/cli/sync_users.php
+ * 5 4 * * * sudo -u www-data /usr/bin/php /var/www/moodle/auth/db/cli/sync_users.php
  *
  * Notes:
  *   - it is required to use the web server account when executing PHP CLI scripts
  * Performance notes:
  * + The code is simpler, but not as optimized as its LDAP counterpart.
  *
- * @package    auth
- * @subpackage db
+ * @package    auth_db
  * @copyright  2006 Martin Langhoff
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 define('CLI_SCRIPT', true);
 
-require(dirname(dirname(dirname(dirname(__FILE__)))).'/config.php');
-require_once($CFG->dirroot.'/course/lib.php');
-require_once($CFG->libdir.'/clilib.php');
+require(__DIR__.'/../../../config.php');
+require_once("$CFG->libdir/clilib.php");
 
-// now get cli options
+// Now get cli options.
 list($options, $unrecognized) = cli_get_params(array('noupdate'=>false, 'verbose'=>false, 'help'=>false), array('n'=>'noupdate', 'v'=>'verbose', 'h'=>'help'));
 
 if ($unrecognized) {
@@ -64,15 +62,15 @@ The auth_db plugin must be enabled and properly configured.
 
 Options:
 -n, --noupdate        Skip update of existing users
--v, --verbose         Print verbose progess information
+-v, --verbose         Print verbose progress information
 -h, --help            Print out this help
 
 Example:
-\$sudo -u www-data /usr/bin/php auth/db/cli/sync_users.php
+\$ sudo -u www-data /usr/bin/php auth/db/cli/sync_users.php
 
 Sample cron entry:
 # 5 minutes past 4am
-5 4 * * * \$sudo -u www-data /usr/bin/php /var/www/moodle/auth/db/cli/sync_users.php
+5 4 * * * sudo -u www-data /usr/bin/php /var/www/moodle/auth/db/cli/sync_users.php
 ";
 
     echo $help;
@@ -80,13 +78,19 @@ Sample cron entry:
 }
 
 if (!is_enabled_auth('db')) {
-    echo "Plugin not enabled!";
-    exit(1);
+    cli_error('auth_db plugin is disabled, synchronisation stopped', 2);
+}
+
+if (empty($options['verbose'])) {
+    $trace = new null_progress_trace();
+} else {
+    $trace = new text_progress_trace();
 }
 
-$verbose = !empty($options['verbose']);
 $update = empty($options['noupdate']);
 
+/** @var auth_plugin_db $dbauth */
 $dbauth = get_auth_plugin('db');
-return $dbauth->sync_users($update, $verbose);
+$result = $dbauth->sync_users($trace, $update);
 
+exit($result);
index e5fdb34..240dead 100644 (file)
@@ -1,4 +1,26 @@
 <?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/>.
+
+/**
+ * auth_db installer script.
+ *
+ * @package    auth_db
+ * @copyright  2009 Petr Skoda {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
 
 function xmldb_auth_db_install() {
     global $CFG, $DB;
index 76967ea..e2e295c 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
@@ -16,7 +15,7 @@
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * Strings for component 'auth_db', language 'en', branch 'MOODLE_20_STABLE'
+ * Strings for component 'auth_db', language 'en'.
  *
  * @package   auth_db
  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
diff --git a/auth/db/tests/db_test.php b/auth/db/tests/db_test.php
new file mode 100644 (file)
index 0000000..f91b44a
--- /dev/null
@@ -0,0 +1,361 @@
+<?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/>.
+
+/**
+ * External database auth sync tests, this also tests adodb drivers
+ * that are matching our four supported Moodle database drivers.
+ *
+ * @package    auth_db
+ * @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();
+
+
+class auth_db_testcase extends advanced_testcase {
+
+    protected function init_auth_database() {
+        global $DB, $CFG;
+        require_once("$CFG->dirroot/auth/db/auth.php");
+
+        $dbman = $DB->get_manager();
+
+        set_config('extencoding', 'utf-8', 'auth/db');
+
+        set_config('host', $CFG->dbhost, 'auth/db');
+        set_config('user', $CFG->dbuser, 'auth/db');
+        set_config('pass', $CFG->dbpass, 'auth/db');
+        set_config('name', $CFG->dbname, 'auth/db');
+
+        if (!empty($CFG->dboptions['dbport'])) {
+            set_config('host', $CFG->dbhost.':'.$CFG->dboptions['dbport'], 'auth/db');
+        }
+
+        switch (get_class($DB)) {
+            case 'mssql_native_moodle_database':
+                set_config('type', 'mssql_n', 'auth/db');
+                set_config('sybasequoting', '1', 'auth/db');
+                break;
+
+            case 'mysqli_native_moodle_database':
+                set_config('type', 'mysqli', 'auth/db');
+                set_config('setupsql', "SET NAMES 'UTF-8'", 'auth/db');
+                set_config('sybasequoting', '0', 'auth/db');
+                if (!empty($CFG->dboptions['dbsocket'])) {
+                    $dbsocket = $CFG->dboptions['dbsocket'];
+                    if ((strpos($dbsocket, '/') === false and strpos($dbsocket, '\\') === false)) {
+                        $dbsocket = ini_get('mysqli.default_socket');
+                    }
+                    set_config('type', 'mysqli://'.rawurlencode($CFG->dbuser).':'.rawurlencode($CFG->dbpass).'@'.rawurlencode($CFG->dbhost).'/'.rawurlencode($CFG->dbname).'?socket='.rawurlencode($dbsocket), 'auth/db');
+                }
+                break;
+
+            case 'oci_native_moodle_database':
+                set_config('type', 'oci8po', 'auth/db');
+                set_config('sybasequoting', '1', 'auth/db');
+                break;
+
+            case 'pgsql_native_moodle_database':
+                set_config('type', 'postgres7', 'auth/db');
+                set_config('setupsql', "SET NAMES 'UTF-8'", 'auth/db');
+                set_config('sybasequoting', '0', 'auth/db');
+                if (!empty($CFG->dboptions['dbsocket']) and ($CFG->dbhost === 'localhost' or $CFG->dbhost === '127.0.0.1')) {
+                    if (strpos($CFG->dboptions['dbsocket'], '/') !== false) {
+                        set_config('host', $CFG->dboptions['dbsocket'], 'auth/db');
+                    } else {
+                        set_config('host', '', 'auth/db');
+                    }
+                }
+                break;
+
+            case 'sqlsrv_native_moodle_database':
+                set_config('type', 'mssqlnative', 'auth/db');
+                set_config('sybasequoting', '1', 'auth/db');
+                break;
+
+            default:
+                throw new exception('Unknown database driver '.get_class($DB));
+        }
+
+        $table = new xmldb_table('auth_db_users');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
+        $table->add_field('name', XMLDB_TYPE_CHAR, '255', null, null, null);
+        $table->add_field('pass', XMLDB_TYPE_CHAR, '255', null, null, null);
+        $table->add_field('email', XMLDB_TYPE_CHAR, '255', null, null, null);
+        $table->add_field('firstname', XMLDB_TYPE_CHAR, '255', null, null, null);
+        $table->add_field('lastname', XMLDB_TYPE_CHAR, '255', null, null, null);
+        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
+        if ($dbman->table_exists($table)) {
+            $dbman->drop_table($table);
+        }
+        $dbman->create_table($table);
+        set_config('table', $CFG->prefix.'auth_db_users', 'auth/db');
+        set_config('fielduser', 'name', 'auth/db');
+        set_config('fieldpass', 'pass', 'auth/db');
+
+        // Setu up field mappings.
+
+        set_config('field_map_email', 'email', 'auth/db');
+        set_config('field_updatelocal_email', 'oncreate', 'auth/db');
+        set_config('field_updateremote_email', '0', 'auth/db');
+        set_config('field_lock_email', 'unlocked', 'auth/db');
+
+        // Init the rest of settings.
+        set_config('passtype', 'plaintext', 'auth/db');
+        set_config('changepasswordurl', '', 'auth/db');
+        set_config('debugauthdb', 0, 'auth/db');
+        set_config('removeuser', AUTH_REMOVEUSER_KEEP, 'auth/db');
+    }
+
+    protected function cleanup_auth_database() {
+        global $DB;
+
+        $dbman = $DB->get_manager();
+        $table = new xmldb_table('auth_db_users');
+        $dbman->drop_table($table);
+    }
+
+    public function test_plugin() {
+        global $DB, $CFG;
+
+        $this->resetAfterTest(false);
+
+        // NOTE: It is strongly discouraged to create new tables in advanced_testcase classes,
+        //       but there is no other simple way to test ext database enrol sync, so let's
+        //       disable transactions are try to cleanup after the tests.
+
+        $this->preventResetByRollback();
+
+        $this->init_auth_database();
+
+        /** @var auth_plugin_db $auth */
+        $auth = get_auth_plugin('db');
+
+        $authdb = $auth->db_init();
+
+
+        // Test adodb may access the table.
+
+        $user1 = (object)array('name'=>'u1', 'pass'=>'heslo', 'email'=>'u1@example.com');
+        $user1->id = $DB->insert_record('auth_db_users', $user1);
+
+
+        $sql = "SELECT * FROM {$auth->config->table}";
+        $rs = $authdb->Execute($sql);
+        $this->assertInstanceOf('ADORecordSet', $rs);
+        $this->assertFalse($rs->EOF);
+        $fields = $rs->FetchRow();
+        $this->assertTrue(is_array($fields));
+        $this->assertTrue($rs->EOF);
+        $rs->Close();
+
+        $authdb->Close();
+
+
+        // Test bulk user account creation.
+
+        $user2 = (object)array('name'=>'u2', 'pass'=>'heslo', 'email'=>'u2@example.com');
+        $user2->id = $DB->insert_record('auth_db_users', $user2);
+
+        $user3 = (object)array('name'=>'admin', 'pass'=>'heslo', 'email'=>'admin@example.com'); // Should be skipped.
+        $user3->id = $DB->insert_record('auth_db_users', $user3);
+
+        $this->assertCount(2, $DB->get_records('user'));
+
+        $trace = new null_progress_trace();
+        $auth->sync_users($trace, false);
+
+        $this->assertEquals(4, $DB->count_records('user'));
+        $u1 = $DB->get_record('user', array('username'=>$user1->name, 'auth'=>'db'));
+        $this->assertSame($user1->email, $u1->email);
+        $u2 = $DB->get_record('user', array('username'=>$user2->name, 'auth'=>'db'));
+        $this->assertSame($user2->email, $u2->email);
+        $admin = $DB->get_record('user', array('username'=>'admin', 'auth'=>'manual'));
+        $this->assertNotEmpty($admin);
+
+
+        // Test sync updates.
+
+        $user2b = clone($user2);
+        $user2b->email = 'u2b@example.com';
+        $DB->update_record('auth_db_users', $user2b);
+
+        $auth->sync_users($trace, false);
+        $this->assertEquals(4, $DB->count_records('user'));
+        $u2 = $DB->get_record('user', array('username'=>$user2->name));
+        $this->assertSame($user2->email, $u2->email);
+
+        $auth->sync_users($trace, true);
+        $this->assertEquals(4, $DB->count_records('user'));
+        $u2 = $DB->get_record('user', array('username'=>$user2->name));
+        $this->assertSame($user2->email, $u2->email);
+
+        set_config('field_updatelocal_email', 'onlogin', 'auth/db');
+        $auth->config->field_updatelocal_email = 'onlogin';
+
+        $auth->sync_users($trace, false);
+        $this->assertEquals(4, $DB->count_records('user'));
+        $u2 = $DB->get_record('user', array('username'=>$user2->name));
+        $this->assertSame($user2->email, $u2->email);
+
+        $auth->sync_users($trace, true);
+        $this->assertEquals(4, $DB->count_records('user'));
+        $u2 = $DB->get_record('user', array('username'=>$user2->name));
+        $this->assertSame($user2b->email, $u2->email);
+
+
+        // Test sync deletes and suspends.
+
+        $DB->delete_records('auth_db_users', array('id'=>$user2->id));
+        $this->assertCount(2, $DB->get_records('auth_db_users'));
+        unset($user2);
+        unset($user2b);
+
+        $auth->sync_users($trace, false);
+        $this->assertEquals(4, $DB->count_records('user'));
+        $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
+        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
+
+        set_config('removeuser', AUTH_REMOVEUSER_SUSPEND, 'auth/db');
+        $auth->config->removeuser = AUTH_REMOVEUSER_SUSPEND;
+
+        $auth->sync_users($trace, false);
+        $this->assertEquals(4, $DB->count_records('user'));
+        $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
+        $this->assertEquals(1, $DB->count_records('user', array('suspended'=>1)));
+
+        $user2 = (object)array('name'=>'u2', 'pass'=>'heslo', 'email'=>'u2@example.com');
+        $user2->id = $DB->insert_record('auth_db_users', $user2);
+
+        $auth->sync_users($trace, false);
+        $this->assertEquals(4, $DB->count_records('user'));
+        $this->assertEquals(0, $DB->count_records('user', array('deleted'=>1)));
+        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
+
+        $DB->delete_records('auth_db_users', array('id'=>$user2->id));
+
+        set_config('removeuser', AUTH_REMOVEUSER_FULLDELETE, 'auth/db');
+        $auth->config->removeuser = AUTH_REMOVEUSER_FULLDELETE;
+
+        $auth->sync_users($trace, false);
+        $this->assertEquals(4, $DB->count_records('user'));
+        $this->assertEquals(1, $DB->count_records('user', array('deleted'=>1)));
+        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
+
+        $user2 = (object)array('name'=>'u2', 'pass'=>'heslo', 'email'=>'u2@example.com');
+        $user2->id = $DB->insert_record('auth_db_users', $user2);
+
+        $auth->sync_users($trace, false);
+        $this->assertEquals(5, $DB->count_records('user'));
+        $this->assertEquals(1, $DB->count_records('user', array('deleted'=>1)));
+        $this->assertEquals(0, $DB->count_records('user', array('suspended'=>1)));
+
+
+        // Test user_login().
+
+        $user3 = (object)array('name'=>'u3', 'pass'=>'heslo', 'email'=>'u3@example.com');
+        $user3->id = $DB->insert_record('auth_db_users', $user3);
+
+        $this->assertFalse($auth->user_login('u4', 'heslo'));
+        $this->assertTrue($auth->user_login('u1', 'heslo'));
+
+        $this->assertFalse($DB->record_exists('user', array('username'=>'u3', 'auth'=>'db')));
+        $this->assertTrue($auth->user_login('u3', 'heslo'));
+        $this->assertFalse($DB->record_exists('user', array('username'=>'u3', 'auth'=>'db')));
+
+        set_config('passtype', 'md5', 'auth/db');
+        $auth->config->passtype = 'md5';
+        $user3->pass = md5('heslo');
+        $DB->update_record('auth_db_users', $user3);
+        $this->assertTrue($auth->user_login('u3', 'heslo'));
+
+        set_config('passtype', 'sh1', 'auth/db');
+        $auth->config->passtype = 'sha1';
+        $user3->pass = sha1('heslo');
+        $DB->update_record('auth_db_users', $user3);
+        $this->assertTrue($auth->user_login('u3', 'heslo'));
+
+        set_config('passtype', 'internal', 'auth/db');
+        $auth->config->passtype = 'internal';
+        create_user_record('u3', 'heslo', 'db');
+        $this->assertTrue($auth->user_login('u3', 'heslo'));
+
+
+        $DB->delete_records('auth_db_users', array('id'=>$user3->id));
+
+        set_config('removeuser', AUTH_REMOVEUSER_KEEP, 'auth/db');
+        $auth->config->removeuser = AUTH_REMOVEUSER_KEEP;
+        $this->assertTrue($auth->user_login('u3', 'heslo'));
+
+        set_config('removeuser', AUTH_REMOVEUSER_SUSPEND, 'auth/db');
+        $auth->config->removeuser = AUTH_REMOVEUSER_SUSPEND;
+        $this->assertFalse($auth->user_login('u3', 'heslo'));
+
+        set_config('removeuser', AUTH_REMOVEUSER_FULLDELETE, 'auth/db');
+        $auth->config->removeuser = AUTH_REMOVEUSER_FULLDELETE;
+        $this->assertFalse($auth->user_login('u3', 'heslo'));
+
+        set_config('passtype', 'sh1', 'auth/db');
+        $auth->config->passtype = 'sha1';
+        $this->assertFalse($auth->user_login('u3', 'heslo'));
+
+
+        // Test login create and update.
+
+        $user4 = (object)array('name'=>'u4', 'pass'=>'heslo', 'email'=>'u4@example.com');
+        $user4->id = $DB->insert_record('auth_db_users', $user4);
+
+        set_config('passtype', 'plaintext', 'auth/db');
+        $auth->config->passtype = 'plaintext';
+
+        $iuser4 = create_user_record('u4', 'heslo', 'db');
+        $this->assertNotEmpty($iuser4);
+        $this->assertSame($user4->name, $iuser4->username);
+        $this->assertSame($user4->email, $iuser4->email);
+        $this->assertSame('db', $iuser4->auth);
+        $this->assertSame($CFG->mnet_localhost_id, $iuser4->mnethostid);
+
+        $user4b = clone($user4);
+        $user4b->email = 'u4b@example.com';
+        $DB->update_record('auth_db_users', $user4b);
+
+        set_config('field_updatelocal_email', 'oncreate', 'auth/db');
+        $auth->config->field_updatelocal_email = 'oncreate';
+
+        update_user_record('u4');
+        $iuser4 = $DB->get_record('user', array('id'=>$iuser4->id));
+        $this->assertSame($user4->email, $iuser4->email);
+
+        set_config('field_updatelocal_email', 'onlogin', 'auth/db');
+        $auth->config->field_updatelocal_email = 'onlogin';
+
+        update_user_record('u4');
+        $iuser4 = $DB->get_record('user', array('id'=>$iuser4->id));
+        $this->assertSame($user4b->email, $iuser4->email);
+
+
+        // Test user_exists()
+
+        $this->assertTrue($auth->user_exists('u1'));
+        $this->assertTrue($auth->user_exists('admin'));
+        $this->assertFalse($auth->user_exists('u3'));
+        $this->assertTrue($auth->user_exists('u4'));
+
+        $this->cleanup_auth_database();
+    }
+}
index 4cecc7e..914a9fa 100644 (file)
@@ -17,8 +17,7 @@
 /**
  * Version details
  *
- * @package    auth
- * @subpackage db
+ * @package    auth_db
  * @copyright  1999 onwards Martin Dougiamas (http://dougiamas.com)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
index 1e93cf2..29943d6 100644 (file)
@@ -40,8 +40,7 @@ if ($show_instructions) {
             </form>
             <p>
             <?php
-                print_string("auth_shibboleth_contact_administrator", "auth_shibboleth");
-                echo '<a href="mailto:'.get_admin()->email.'"> Moodle Administrator</a>.';
+                print_string("auth_shib_contact_administrator", "auth_shibboleth", get_admin()->email);
             ?>
             </p>
           </div>
index aace9a1..ea8980d 100644 (file)
@@ -25,7 +25,7 @@
 
 $string['auth_shib_auth_method'] = 'Authentication method name';
 $string['auth_shib_auth_method_description'] = 'Provide a name for the Shibboleth authentication method that is familiar to your users. This could be the name of your Shibboleth federation, e.g. <tt>SWITCHaai Login</tt> or <tt>InCommon Login</tt> or similar.';
-$string['auth_shibboleth_contact_administrator'] = 'In case you are not associated with the given organizations and you need access to a course on this server, please contact the';
+$string['auth_shib_contact_administrator'] = 'In case you are not associated with the given organizations and you need access to a course on this server, please contact the <a href="mailto:{$a}">Moodle Administrator</a>.';
 $string['auth_shibbolethdescription'] = 'Using this method users are created and authenticated using <a href="http://shibboleth.internet2.edu/">Shibboleth</a>.<br />Be sure to read the <a href="../auth/shibboleth/README.txt">README</a> for Shibboleth on how to set up your Moodle with Shibboleth';
 $string['auth_shibboleth_errormsg'] = 'Please select the organization you are member of!';
 $string['auth_shibboleth_login'] = 'Shibboleth login';
index 6b81b7d..ac5584c 100644 (file)
@@ -33,7 +33,7 @@ $currentcontext = required_param('currentcontext', PARAM_INT);
 // file parameters
 $component  = optional_param('component', null, PARAM_COMPONENT);
 $filearea   = optional_param('filearea', null, PARAM_AREA);
-$returnurl  = optional_param('returnurl', null, PARAM_URL);
+$returnurl  = optional_param('returnurl', null, PARAM_LOCALURL);
 
 list($context, $course, $cm) = get_context_info_array($currentcontext);
 $filecontext = context::instance_by_id($contextid, IGNORE_MISSING);
index 4fd0e1b..4df141f 100644 (file)
@@ -642,7 +642,9 @@ class moodle1_converter extends base_converter {
         }
         foreach ($matches[2] as $match) {
             $file = str_replace(array('$@FILEPHP@$', '$@SLASH@$', '$@FORCEDOWNLOAD@$'), array('', '/', ''), $match);
-            $files[] = rawurldecode($file);
+            if ($file === clean_param($file, PARAM_PATH)) {
+                $files[] = rawurldecode($file);
+            }
         }
 
         return array_unique($files);
@@ -1210,6 +1212,10 @@ class moodle1_file_manager implements loggable {
 
         $sourcefullpath = $this->basepath.'/'.$sourcepath;
 
+        if ($sourcefullpath !== clean_param($sourcefullpath, PARAM_PATH)) {
+            throw new moodle1_convert_exception('file_invalid_path', $sourcefullpath);
+        }
+
         if (!is_readable($sourcefullpath)) {
             throw new moodle1_convert_exception('file_not_readable', $sourcefullpath);
         }
index bf4935c..154b6c8 100644 (file)
@@ -273,6 +273,15 @@ class moodle1_converter_testcase extends advanced_testcase {
         $fileids = $fileman->get_fileids();
         $this->assertEquals(gettype($fileids), 'array');
         $this->assertEquals(0, count($fileids));
+        // try to migrate an invalid file
+        $fileman->itemid = 1;
+        $thrown = false;
+        try {
+            $fileman->migrate_file('/../../../../../../../../../../../../../../etc/passwd');
+        } catch (moodle1_convert_exception $e) {
+            $thrown = true;
+        }
+        $this->assertTrue($thrown);
         // migrate a single file
         $fileman->itemid = 4;
         $fileman->migrate_file('moddata/unittest/4/icon.gif');
@@ -435,6 +444,8 @@ class moodle1_converter_testcase extends advanced_testcase {
 
         $text = 'This is a text containing links to file.php
 as it is parsed from the backup file. <br /><br /><img border="0" width="110" vspace="0" hspace="0" height="92" title="News" alt="News" src="$@FILEPHP@$$@SLASH@$pics$@SLASH@$news.gif" /><a href="$@FILEPHP@$$@SLASH@$pics$@SLASH@$news.gif$@FORCEDOWNLOAD@$">download image</a><br />
+    <div><a href=\'$@FILEPHP@$/../../../../../../../../../../../../../../../etc/passwd\'>download passwords</a></div>
+    <div><a href=\'$@FILEPHP@$$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$etc$@SLASH@$shadow\'>download shadows</a></div>
     <br /><a href=\'$@FILEPHP@$$@SLASH@$MANUAL.DOC$@FORCEDOWNLOAD@$\'>download manual</a><br />';
 
         $files = moodle1_converter::find_referenced_files($text);
@@ -446,6 +457,8 @@ as it is parsed from the backup file. <br /><br /><img border="0" width="110" vs
         $text = moodle1_converter::rewrite_filephp_usage($text, array('/pics/news.gif', '/another/file/notused.txt'));
         $this->assertEquals($text, 'This is a text containing links to file.php
 as it is parsed from the backup file. <br /><br /><img border="0" width="110" vspace="0" hspace="0" height="92" title="News" alt="News" src="@@PLUGINFILE@@/pics/news.gif" /><a href="@@PLUGINFILE@@/pics/news.gif?forcedownload=1">download image</a><br />
+    <div><a href=\'$@FILEPHP@$/../../../../../../../../../../../../../../../etc/passwd\'>download passwords</a></div>
+    <div><a href=\'$@FILEPHP@$$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$..$@SLASH@$etc$@SLASH@$shadow\'>download shadows</a></div>
     <br /><a href=\'$@FILEPHP@$$@SLASH@$MANUAL.DOC$@FORCEDOWNLOAD@$\'>download manual</a><br />');
     }
 
index babbcd0..b7da2d3 100644 (file)
@@ -297,8 +297,13 @@ class restore_gradebook_structure_step extends restore_structure_step {
 
         $data->courseid = $this->get_courseid();
 
-        $newitemid = $DB->insert_record('grade_settings', $data);
-        //$this->set_mapping('grade_setting', $oldid, $newitemid);
+        if (!$DB->record_exists('grade_settings', array('courseid' => $data->courseid, 'name' => $data->name))) {
+            $newitemid = $DB->insert_record('grade_settings', $data);
+        } else {
+            $newitemid = $data->id;
+        }
+
+        $this->set_mapping('grade_setting', $oldid, $newitemid);
     }
 
     /**
@@ -1817,6 +1822,14 @@ class restore_filters_structure_step extends restore_structure_step {
 
         $data = (object)$data;
 
+        if (strpos($data->filter, 'filter/') === 0) {
+            $data->filter = substr($data->filter, 7);
+
+        } else if (strpos($data->filter, '/') !== false) {
+            // Unsupported old filter.
+            return;
+        }
+
         if (!filter_is_enabled($data->filter)) { // Not installed or not enabled, nothing to do
             return;
         }
@@ -1827,6 +1840,14 @@ class restore_filters_structure_step extends restore_structure_step {
 
         $data = (object)$data;
 
+        if (strpos($data->filter, 'filter/') === 0) {
+            $data->filter = substr($data->filter, 7);
+
+        } else if (strpos($data->filter, '/') !== false) {
+            // Unsupported old filter.
+            return;
+        }
+
         if (!filter_is_enabled($data->filter)) { // Not installed or not enabled, nothing to do
             return;
         }
index d098938..12f0ea1 100644 (file)
@@ -38,6 +38,10 @@ class block_completionstatus extends block_base {
         $this->title = get_string('pluginname', 'block_completionstatus');
     }
 
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
+    }
+
     public function get_content() {
         global $USER;
 
index 8220ecc..8d38ec8 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/completionstatus:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/completionstatus:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/completionstatus/db/upgrade.php b/blocks/completionstatus/db/upgrade.php
new file mode 100644 (file)
index 0000000..b5bbe8c
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file keeps track of upgrades to the completion status block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_completionstatus_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'completionstatus', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'completionstatus');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index 3c90759..e389743 100644 (file)
@@ -25,7 +25,6 @@
 
 $string['completionprogressdetails'] = 'Completion progress details';
 $string['completionstatus:addinstance'] = 'Add a new course completion status block';
-$string['completionstatus:myaddinstance'] = 'Add a new course completion status block to the My Moodle page';
 $string['criteriagroup'] = 'Criteria group';
 $string['firstofsecond'] = '{$a->first} of {$a->second}';
 $string['pluginname'] = 'Course completion status';
index b97ad8e..218f326 100644 (file)
@@ -26,7 +26,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version      = 2012112900; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version      = 2012112901; // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires     = 2012112900; // Requires this Moodle version
 $plugin->component    = 'block_completionstatus';
-$plugin->dependencies = array('report_completion' => 2012112900);
\ No newline at end of file
+$plugin->dependencies = array('report_completion' => 2012112900);
index cac6591..504c626 100644 (file)
@@ -5,6 +5,10 @@ class block_course_summary extends block_base {
         $this->title = get_string('pluginname', 'block_course_summary');
     }
 
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
+    }
+
     function specialization() {
         if($this->page->pagetype == PAGE_COURSE_VIEW && $this->page->course->id != SITEID) {
             $this->title = get_string('coursesummary', 'block_course_summary');
index 5613ae7..a1e4265 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/course_summary:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/course_summary:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/course_summary/db/upgrade.php b/blocks/course_summary/db/upgrade.php
new file mode 100644 (file)
index 0000000..7a16a1f
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file keeps track of upgrades to the course summary block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_course_summary_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'course_summary', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'course_summary');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index 836cbfc..92adcf9 100644 (file)
@@ -25,5 +25,4 @@
 
 $string['coursesummary'] = 'Course summary';
 $string['course_summary:addinstance'] = 'Add a new course/site description block';
-$string['course_summary:myaddinstance'] = 'Add a new course/site description block to the My Moodle page';
 $string['pluginname'] = 'Course/Site description';
index 38cb1cf..d036ba1 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_course_summary'; // Full name of the plugin (used for diagnostics)
index 73249e9..46c0479 100644 (file)
@@ -936,7 +936,7 @@ M.core_dock.genericblock.prototype = {
             }, this);
             // Add a close icon
             // Must set the image src seperatly of we get an error with XML strict headers
-            var closeicon = Y.Node.create('<span class="hidepanelicon" tabindex="0"><img alt="" /></span>');
+            var closeicon = Y.Node.create('<span class="hidepanelicon" tabindex="0"><img alt="'+M.str.block.hidepanel+'" title="'+M.str.block.hidedockpanel+'" /></span>');
             closeicon.one('img').setAttribute('src', M.util.image_url('t/dockclose', 'moodle'));
             closeicon.on('forceclose|click', this.hide, this);
             closeicon.on('dock:actionkey',this.hide, this, {actions:{enter:true,toggle:true}});
index 1eccd11..af9c550 100644 (file)
@@ -5,10 +5,15 @@ define('BGR_LASTMODIFIED', '1');
 define('BGR_NEXTONE',      '2');
 
 class block_glossary_random extends block_base {
+
     function init() {
         $this->title = get_string('pluginname','block_glossary_random');
     }
 
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
+    }
+
     function specialization() {
         global $CFG, $DB;
 
index 0c1acd6..e7bb687 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/glossary_random:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/glossary_random:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/glossary_random/db/upgrade.php b/blocks/glossary_random/db/upgrade.php
new file mode 100644 (file)
index 0000000..81aeabe
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file keeps track of upgrades to the glossary random block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_glossary_random_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'glossary_random', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'glossary_random');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index ddb483d..3c51dfa 100644 (file)
@@ -28,7 +28,6 @@ $string['askaddentry'] = 'When users can add entries to the glossary, show a lin
 $string['askinvisible'] = 'When users cannot edit or view the glossary, show this text (without link)';
 $string['askviewglossary'] = 'When users can view the glossary but not add entries, show a link with this text';
 $string['glossary_random:addinstance'] = 'Add a new random glossary entry block';
-$string['glossary_random:myaddinstance'] = 'Add a new random glossary entry block to the My Moodle page';
 $string['intro'] = 'Make sure you have at least one glossary with at least one entry added to this course. Then you can adjust the following settings';
 $string['invisible'] = '(to be continued)';
 $string['lastmodified'] = 'Last modified entry';
index bcca83b..061ec44 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_glossary_random'; // Full name of the plugin (used for diagnostics)
index aa340af..85f48f3 100644 (file)
@@ -7,7 +7,7 @@ class block_mentees extends block_base {
     }
 
     function applicable_formats() {
-        return array('all' => true, 'tag' => false);
+        return array('all' => true, 'tag' => false, 'my' => false);
     }
 
     function specialization() {
index ba14b07..489ceb3 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/mentees:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/mentees:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/mentees/db/upgrade.php b/blocks/mentees/db/upgrade.php
new file mode 100644 (file)
index 0000000..e8aba71
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file keeps track of upgrades to the mentees block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_mentees_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'mentees', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'mentees');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index 3a22057..1c0cdab 100644 (file)
@@ -27,6 +27,5 @@ $string['configtitle'] = 'Block title';
 $string['configtitleblankhides'] = 'Block title (no title if blank)';
 $string['leaveblanktohide'] = 'leave blank to hide the title';
 $string['mentees:addinstance'] = 'Add a new mentees block';
-$string['mentees:myaddinstance'] = 'Add a new mentees block to the My Moodle page';
 $string['newmenteesblock'] = '(new Mentees block)';
 $string['pluginname'] = 'Mentees';
index 8ead4fc..c3a8db3 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_mentees';   // Full name of the plugin (used for diagnostics)
index 5ecbec2..e803c6e 100644 (file)
@@ -5,6 +5,10 @@ class block_news_items extends block_base {
         $this->title = get_string('pluginname', 'block_news_items');
     }
 
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
+    }
+
     function get_content() {
         global $CFG, $USER;
 
index 86bb1b7..452158e 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/news_items:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/news_items:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/news_items/db/upgrade.php b/blocks/news_items/db/upgrade.php
new file mode 100644 (file)
index 0000000..e634e57
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file keeps track of upgrades to the latest news block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_news_items_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'news_items', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'news_items');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index d1ab3d8..1de6507 100644 (file)
@@ -24,5 +24,4 @@
  */
 
 $string['news_items:addinstance'] = 'Add a new latest news block';
-$string['news_items:myaddinstance'] = 'Add a new navigation block to the My Moodle page';
 $string['pluginname'] = 'Latest news';
index 4cdea31..11d74ca 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_news_items'; // Full name of the plugin (used for diagnostics)
index 77f8a69..6d14ebb 100644 (file)
@@ -10,7 +10,13 @@ class block_online_users extends block_base {
         $this->title = get_string('pluginname','block_online_users');
     }
 
-    function has_config() {return true;}
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
+    }
+
+    function has_config() {
+        return true;
+    }
 
     function get_content() {
         global $USER, $CFG, $DB, $OUTPUT;
index f238b73..41959c4 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/online_users:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/online_users:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/online_users/db/upgrade.php b/blocks/online_users/db/upgrade.php
new file mode 100644 (file)
index 0000000..f45a788
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file keeps track of upgrades to the online users block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_online_users_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'online_users', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'online_users');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index 034fce5..b7a008e 100644 (file)
@@ -25,7 +25,6 @@
 
 $string['configtimetosee'] = 'Number of minutes determining the period of inactivity after which a user is no longer considered to be online.';
 $string['online_users:addinstance'] = 'Add a new online users block';
-$string['online_users:myaddinstance'] = 'Add a new online users block to the My Moodle page';
 $string['online_users:viewlist'] = 'View list of online users';
 $string['periodnminutes'] = 'last {$a} minutes';
 $string['pluginname'] = 'Online users';
index 18e1354..4463c45 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_online_users'; // Full name of the plugin (used for diagnostics)
index 8e28ac2..c23d7b9 100644 (file)
@@ -78,6 +78,9 @@ class restore_rss_client_block_structure_step extends restore_structure_step {
         $configdata = $DB->get_field('block_instances', 'configdata', array('id' => $this->task->get_blockid()));
         // Extract configdata
         $config = unserialize(base64_decode($configdata));
+        if (empty($config)) {
+            $config = new stdClass();
+        }
         // Set array of used rss feeds
         $config->rssid = $feedsarr;
         // Serialize back the configdata
index 7a44dfe..9ea6db4 100644 (file)
@@ -36,7 +36,11 @@ require_once($CFG->libdir.'/completionlib.php');
 class block_selfcompletion extends block_base {
 
     public function init() {
-        $this->title   = get_string('pluginname', 'block_selfcompletion');
+        $this->title = get_string('pluginname', 'block_selfcompletion');
+    }
+
+    function applicable_formats() {
+        return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
     }
 
     public function get_content() {
index 489eebd..d91d4d4 100644 (file)
@@ -26,16 +26,6 @@ defined('MOODLE_INTERNAL') || die();
 
 $capabilities = array(
 
-    'block/selfcompletion:myaddinstance' => array(
-        'captype' => 'write',
-        'contextlevel' => CONTEXT_SYSTEM,
-        'archetypes' => array(
-            'user' => CAP_ALLOW
-        ),
-
-        'clonepermissionsfrom' => 'moodle/my:manageblocks'
-    ),
-
     'block/selfcompletion:addinstance' => array(
         'riskbitmask' => RISK_SPAM | RISK_XSS,
 
diff --git a/blocks/selfcompletion/db/upgrade.php b/blocks/selfcompletion/db/upgrade.php
new file mode 100644 (file)
index 0000000..fd03025
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This file keeps track of upgrades to the self completion block
+ *
+ * Sometimes, changes between versions involve alterations to database structures
+ * and other major things that may break installations.
+ *
+ * The upgrade function in this file will attempt to perform all the necessary
+ * actions to upgrade your older installation to the current version.
+ *
+ * If there's something it cannot do itself, it will tell you what you need to do.
+ *
+ * The commands in here will all be database-neutral, using the methods of
+ * database_manager class
+ *
+ * Please do not forget to use upgrade_set_timeout()
+ * before any action that may take longer time to finish.
+ *
+ * @since 2.0
+ * @package blocks
+ * @copyright 2012 Mark Nelson <markn@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Handles upgrading instances of this block.
+ *
+ * @param int $oldversion
+ * @param object $block
+ */
+function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
+    global $DB;
+
+    // Moodle v2.4.0 release upgrade line
+    // Put any upgrade step following this.
+
+    if ($oldversion < 2012112901) {
+        // Get the instances of this block.
+        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'selfcompletion', 'pagetypepattern' => 'my-index'))) {
+            // Loop through and remove them from the My Moodle page.
+            foreach ($blocks as $block) {
+                blocks_delete_instance($block);
+            }
+
+        }
+
+        // Savepoint reached.
+        upgrade_block_savepoint(true, 2012112901, 'selfcompletion');
+    }
+
+
+    return true;
+}
\ No newline at end of file
index e7c89d3..457c77c 100644 (file)
@@ -28,4 +28,3 @@ $string['completecourse'] = 'Complete course';
 $string['pluginname'] = 'Self completion';
 $string['selfcompletionnotenabled'] = 'The self completion criteria has not been enabled for this course';
 $string['selfcompletion:addinstance'] = 'Add a new self completion block';
-$string['selfcompletion:myaddinstance'] = 'Add a new self completion block to the My Moodle page';
index 517c84b..2a0d036 100644 (file)
@@ -25,6 +25,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2012112900;        // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version   = 2012112901;        // The current plugin version (Date: YYYYMMDDXX)
 $plugin->requires  = 2012112900;        // Requires this Moodle version
 $plugin->component = 'block_selfcompletion'; // Full name of the plugin (used for diagnostics)
index bc5c265..e6bde82 100644 (file)
@@ -33,7 +33,7 @@ class block_tags_edit_form extends block_edit_form {
         // Fields for editing HTML block title and contents.
         $mform->addElement('header', 'configheader', get_string('blocksettings', 'block'));
 
-        $mform->addElement('text', 'config_title', get_string('pluginname', 'block_tags'));
+        $mform->addElement('text', 'config_title', get_string('configtitle', 'block_tags'));
         $mform->setType('config_title', PARAM_TEXT);
         $mform->setDefault('config_title', get_string('pluginname', 'block_tags'));
 
index 7f2d59f..6dcb0b9 100644 (file)
@@ -25,6 +25,7 @@
 $string['add'] = 'Add';
 $string['alltags'] = 'All tags:';
 $string['arrowtitle'] = 'Click here to enter the suggested text (grey letters).';
+$string['configtitle'] = 'Block title';
 $string['coursetags'] = 'Course tags:';
 $string['disabledtags'] = 'Tags are disabled';
 $string['defaultdisplay'] = 'Tag type to display';
index b6195bd..73cd5ee 100644 (file)
@@ -163,6 +163,13 @@ function blog_rss_get_feed($context, $args) {
         return '';
     }
 
+    if ($CFG->bloglevel == BLOG_SITE_LEVEL) {
+        if (isguestuser()) {
+            debugging(get_string('nopermissiontoshow','error'));
+            return '';
+        }
+    }
+
     $sitecontext = context_system::instance();
     if (!has_capability('moodle/blog:view', $sitecontext)) {
         return null;
index 74014c4..028a31e 100644 (file)
@@ -1093,6 +1093,10 @@ class cache_application extends cache implements cache_loader_with_locking {
             $todelete = array();
             // Iterate the returned data for the events.
             foreach ($events as $event => $keys) {
+                if ($keys === false) {
+                    // There are no keys.
+                    continue;
+                }
                 // Look at each key and check the timestamp.
                 foreach ($keys as $key => $timestamp) {
                     // If the timestamp of the event is more than or equal to the last invalidation (happened between the last
index dcbdbd7..7281fad 100644 (file)
@@ -357,6 +357,7 @@ class cachestore_static extends static_data_store implements cache_is_key_aware
      */
     public function purge() {
         $this->flush_store_by_id($this->storeid);
+        $this->store = &self::register_store_id($this->storeid);
     }
 
     /**
index 86ca22f..dc56f91 100644 (file)
@@ -2977,6 +2977,48 @@ function calendar_update_subscription_events($subscriptionid) {
     return $return;
 }
 
+/**
+ * Checks to see if the user can edit a given subscription feed.
+ *
+ * @param mixed $subscriptionorid Subscription object or id
+ * @return bool true if current user can edit the subscription else false
+ */
+function calendar_can_edit_subscription($subscriptionorid) {
+    global $DB;
+
+    if (is_array($subscriptionorid)) {
+        $subscription = (object)$subscriptionorid;
+    } else if (is_object($subscriptionorid)) {
+        $subscription = $subscriptionorid;
+    } else {
+        $subscription = $DB->get_record('event_subscriptions', array('id' => $subscriptionorid), '*', MUST_EXIST);
+    }
+    $allowed = new stdClass;
+    $courseid = $subscription->courseid;
+    $groupid = $subscription->groupid;
+    calendar_get_allowed_types($allowed, $courseid);
+    switch ($subscription->eventtype) {
+        case 'user':
+            return $allowed->user;
+        case 'course':
+            if (isset($allowed->courses[$courseid])) {
+                return $allowed->courses[$courseid];
+            } else {
+                return false;
+            }
+        case 'site':
+            return $allowed->site;
+        case 'group':
+            if (isset($allowed->groups[$groupid])) {
+                return $allowed->groups[$groupid];
+            } else {
+                return false;
+            }
+        default:
+            return false;
+    }
+}
+
 /**
  * Update calendar subscriptions.
  *
index 95479ef..cc726f1 100644 (file)
@@ -78,11 +78,15 @@ if (!empty($formdata)) {
         $importresults = calendar_update_subscription_events($subscriptionid);
     }
     // Redirect to prevent refresh issues.
-    redirect($PAGE->url);
+    redirect($PAGE->url, $importresults);
 } else if (!empty($subscriptionid)) {
     // The user is wanting to perform an action upon an existing subscription.
     require_sesskey(); // Must have sesskey for all actions.
-    $importresults = calendar_process_subscription_row($subscriptionid, $pollinterval, $action);
+    if (calendar_can_edit_subscription($subscriptionid)) {
+        $importresults = calendar_process_subscription_row($subscriptionid, $pollinterval, $action);
+    } else {
+        print_error('nopermissions', 'error', $PAGE->url, get_string('managesubscriptions', 'calendar'));
+    }
 }
 
 $sql = 'SELECT *
index 5a18073..b7cbd79 100644 (file)
@@ -736,6 +736,7 @@ class core_calendar_renderer extends plugin_renderer_base {
         $table->head  = array(
             get_string('colcalendar', 'calendar'),
             get_string('collastupdated', 'calendar'),
+            get_string('eventkind', 'calendar'),
             get_string('colpoll', 'calendar'),
             get_string('colactions', 'calendar')
         );
@@ -762,10 +763,12 @@ class core_calendar_renderer extends plugin_renderer_base {
 
             $cell = new html_table_cell($this->subscription_action_form($sub, $courseid));
             $cell->colspan = 2;
+            $type = $sub->eventtype . 'events';
 
             $table->data[] = new html_table_row(array(
                 new html_table_cell($label),
                 new html_table_cell($lastupdated),
+                new html_table_cell(get_string($type, 'calendar')),
                 $cell
             ));
         }
index b7a39a8..a960293 100644 (file)
@@ -38,7 +38,7 @@ $action    = optional_param('action',    '',  PARAM_ALPHA);
 $area      = optional_param('area',      '',  PARAM_AREA);
 $content   = optional_param('content',   '',  PARAM_RAW);
 $itemid    = optional_param('itemid',    '',  PARAM_INT);
-$returnurl = optional_param('returnurl', '/', PARAM_URL);
+$returnurl = optional_param('returnurl', '/', PARAM_LOCALURL);
 $component = optional_param('component', '',  PARAM_COMPONENT);
 
 // Currently this script can only add comments
index 33bc709..37138b5 100644 (file)
@@ -191,6 +191,7 @@ if ($editingon && can_edit_in_category()) {
     // Integrate into the admin tree only if the user can edit categories at the top level,
     // otherwise the admin block does not appear to this user, and you get an error.
     require_once($CFG->libdir . '/adminlib.php');
+    navigation_node::override_active_url(new moodle_url('/course/category.php', array('id' => $id)));
     admin_externalpage_setup('coursemgmt', '', $urlparams, $CFG->wwwroot . '/course/category.php');
     $PAGE->set_context($context);   // Ensure that we are actually showing blocks etc for the cat context
 
index 6fb00b0..21dc7a7 100644 (file)
@@ -555,6 +555,15 @@ class dndupload_ajax_processor {
         $this->cm->groupmode = $this->course->groupmode;
         $this->cm->groupingid = $this->course->defaultgroupingid;
 
+        // Set the correct default for completion tracking.
+        $this->cm->completion = COMPLETION_TRACKING_NONE;
+        $completion = new completion_info($this->course);
+        if ($completion->is_enabled()) {
+            if (plugin_supports('mod', $this->cm->modulename, FEATURE_MODEDIT_DEFAULT_COMPLETION, true)) {
+                $this->cm->completion = COMPLETION_TRACKING_MANUAL;
+            }
+        }
+
         if (!$this->cm->id = add_course_module($this->cm)) {
             throw new coding_exception("Unable to create the course module");
         }
index f2d90db..a58b86a 100644 (file)
@@ -1516,8 +1516,9 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
                     $textcss = '';
                 }
 
-                // Get on-click attribute value if specified
-                $onclick = $mod->get_on_click();
+                // Get on-click attribute value if specified and decode the onclick - it
+                // has already been encoded for display (puke).
+                $onclick = htmlspecialchars_decode($mod->get_on_click(), ENT_QUOTES);
 
                 $groupinglabel = '';
                 if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', context_course::instance($course->id))) {
index 719762e..2b756b6 100644 (file)
@@ -35,7 +35,7 @@ require_once($CFG->dirroot.'/course/lib.php');
 
 $id         = required_param('id', PARAM_INT);
 $switchrole = optional_param('switchrole',-1, PARAM_INT);
-$returnurl  = optional_param('returnurl', false, PARAM_URL);
+$returnurl  = optional_param('returnurl', false, PARAM_LOCALURL);
 
 $PAGE->set_url('/course/switchrole.php', array('id'=>$id));
 
@@ -84,4 +84,4 @@ if ($returnurl === false) {
     $returnurl = new moodle_url('/course/view.php', array('id' => $course->id));
 }
 
-redirect($returnurl);
\ No newline at end of file
+redirect($returnurl);
index 7db80b8..0702c9e 100644 (file)
@@ -32,7 +32,7 @@
 
 define('CLI_SCRIPT', true);
 
-require(dirname(dirname(dirname(dirname(__FILE__)))).'/config.php');
+require(__DIR__.'/../../../config.php');
 require_once("$CFG->dirroot/enrol/category/locallib.php");
 require_once("$CFG->libdir/clilib.php");
 
@@ -49,7 +49,7 @@ if ($options['help']) {
         "Execute course category enrolment sync.
 
 Options:
--v, --verbose         Print verbose progess information
+-v, --verbose         Print verbose progress information
 -h, --help            Print out this help
 
 Example:
@@ -64,5 +64,12 @@ if (!enrol_is_enabled('category')) {
     cli_error('enrol_category plugin is disabled, synchronisation stopped', 2);
 }
 
-$verbose = !empty($options['verbose']);
-return enrol_category_sync_full($verbose);
+if (empty($options['verbose'])) {
+    $trace = new null_progress_trace();
+} else {
+    $trace = new text_progress_trace();
+}
+
+$result = enrol_category_sync_full($trace);
+
+exit($result);
index 4fed790..b806eae 100644 (file)
@@ -70,7 +70,8 @@ class enrol_category_plugin extends enrol_plugin {
         }
 
         require_once("$CFG->dirroot/enrol/category/locallib.php");
-        enrol_category_sync_full();
+        $trace = new null_progress_trace();
+        enrol_category_sync_full($trace);
     }
 
     /**
index 9e4ab0c..69ec05e 100644 (file)
@@ -252,14 +252,15 @@ function enrol_category_sync_course($course) {
  * - reorder categories
  * - disable enrol_category and enable it again
  *
- * @param bool $verbose
+ * @param progress_trace $trace
  * @return int exit code - 0 is ok, 1 means error, 2 if plugin disabled
  */
-function enrol_category_sync_full($verbose = false) {
+function enrol_category_sync_full(progress_trace $trace) {
     global $DB;
 
 
     if (!enrol_is_enabled('category')) {
+        $trace->finished();
         return 2;
     }
 
@@ -273,23 +274,20 @@ function enrol_category_sync_full($verbose = false) {
     // Any interesting roles worth synchronising?
     if (!$roles = get_roles_with_capability('enrol/category:synchronised', CAP_ALLOW, $syscontext)) {
         // yay, nothing to do, so let's remove all leftovers
-        if ($verbose) {
-            mtrace("No roles with 'enrol/category:synchronised' capability found.");
-        }
+        $trace->output("No roles with 'enrol/category:synchronised' capability found.");
         if ($instances = $DB->get_records('enrol', array('enrol'=>'category'))) {
+            $trace->output("Deleting all category enrol instances...");
             foreach ($instances as $instance) {
-                if ($verbose) {
-                    mtrace("  deleting category enrol instance from course {$instance->courseid}");
-                }
+                $trace->output("deleting category enrol instance from course {$instance->courseid}", 1);
                 $plugin->delete_instance($instance);
             }
+            $trace->output("...all instances deleted.");
         }
+        $trace->finished();
         return 0;
     }
     $rolenames = role_fix_names($roles, null, ROLENAME_SHORT, true);
-    if ($verbose) {
-        mtrace('Synchronising category enrolments for roles: '.implode(', ', $rolenames).'...');
-    }
+    $trace->output('Synchronising category enrolments for roles: '.implode(', ', $rolenames).'...');
 
     list($roleids, $params) = $DB->get_in_or_equal(array_keys($roles), SQL_PARAMS_NAMED, 'r');
     $params['courselevel'] = CONTEXT_COURSE;
@@ -357,9 +355,7 @@ function enrol_category_sync_full($verbose = false) {
         unset($instance->userid);
         unset($instance->estart);
         $plugin->enrol_user($instance, $userid, null, $estart);
-        if ($verbose) {
-            mtrace("  enrolling: user $userid ==> course $instance->courseid");
-        }
+        $trace->output("enrolling: user $userid ==> course $instance->courseid", 1);
     }
     $rs->close();
 
@@ -378,15 +374,12 @@ function enrol_category_sync_full($verbose = false) {
         $userid = $instance->userid;
         unset($instance->userid);
         $plugin->unenrol_user($instance, $userid);
-        if ($verbose) {
-            mtrace("  unenrolling: user $userid ==> course $instance->courseid");
-        }
+        $trace->output("unenrolling: user $userid ==> course $instance->courseid", 1);
     }
     $rs->close();
 
-    if ($verbose) {
-        mtrace('...user enrolment synchronisation finished.');
-    }
+    $trace->output('...user enrolment synchronisation finished.');
+    $trace->finished();
 
     return 0;
 }
index 3649764..ca8d4cd 100644 (file)
@@ -276,6 +276,8 @@ class enrol_category_testcase extends advanced_testcase {
 
         $this->resetAfterTest();
 
+        $trace = new null_progress_trace();
+
         // Setup a few courses and categories.
 
         $studentrole = $DB->get_record('role', array('shortname'=>'student'));
@@ -309,13 +311,13 @@ class enrol_category_testcase extends advanced_testcase {
         role_assign($managerrole->id, $user3->id, context_course::instance($course2->id));
         $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
 
-        $result = enrol_category_sync_full();
+        $result = enrol_category_sync_full($trace);
         $this->assertSame(0, $result);
 
         $this->disable_plugin();
         role_assign($studentrole->id, $user1->id, context_coursecat::instance($cat2->id));
         $this->enable_plugin();
-        $result = enrol_category_sync_full();
+        $result = enrol_category_sync_full($trace);
         $this->assertSame(0, $result);
         $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
         $this->assertTrue(is_enrolled(context_course::instance($course2->id), $user1->id));
@@ -329,7 +331,7 @@ class enrol_category_testcase extends advanced_testcase {
         role_assign($teacherrole->id, $user3->id, context_coursecat::instance($cat2->id));
         role_assign($managerrole->id, $user3->id, context_course::instance($course3->id));
         $this->enable_plugin();
-        $result = enrol_category_sync_full();
+        $result = enrol_category_sync_full($trace);
         $this->assertSame(0, $result);
         $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
         $this->assertTrue(is_enrolled(context_course::instance($course1->id), $user2->id));
@@ -348,7 +350,7 @@ class enrol_category_testcase extends advanced_testcase {
         role_unassign_all(array('roleid'=>$managerrole->id));
         role_unassign_all(array('roleid'=>$teacherrole->id));
 
-        $result = enrol_category_sync_full();
+        $result = enrol_category_sync_full($trace);
         $this->assertSame(2, $result);
         $this->assertEquals(0, $DB->count_records('role_assignments', array()));
         $this->assertNotEmpty($DB->count_records('user_enrolments', array()));
@@ -356,7 +358,7 @@ class enrol_category_testcase extends advanced_testcase {
         $this->disable_role_sync($teacherrole->id);
 
         $this->enable_plugin();
-        $result = enrol_category_sync_full();
+        $result = enrol_category_sync_full($trace);
         $this->assertSame(0, $result);
         $this->assertEquals(0, $DB->count_records('role_assignments', array()));
         $this->assertEquals(0, $DB->count_records('user_enrolments', array()));
index 6eec6ce..42cc37e 100644 (file)
@@ -90,7 +90,9 @@ switch ($action) {
         }
         $enrol = enrol_get_plugin('cohort');
         $enrol->add_instance($manager->get_course(), array('customint1' => $cohortid, 'roleid' => $roleid));
-        enrol_cohort_sync($manager->get_course()->id);
+        $trace = new null_progress_trace();
+        enrol_cohort_sync($trace, $manager->get_course()->id);
+        $trace->finished();
         break;
     case 'enrolcohortusers':
         //TODO: this should be moved to enrol_manual, see MDL-35618.
index 4f1cd3b..032c34a 100644 (file)
@@ -30,8 +30,8 @@
 
 define('CLI_SCRIPT', true);
 
-require(dirname(dirname(dirname(dirname(__FILE__)))).'/config.php');
-require_once($CFG->libdir.'/clilib.php');
+require(__DIR__.'/../../../config.php');
+require_once("$CFG->libdir/clilib.php");
 require_once("$CFG->dirroot/enrol/cohort/locallib.php");
 
 // Now get cli options.
@@ -51,15 +51,20 @@ Options:
 -h, --help            Print out this help
 
 Example:
-\$sudo -u www-data /usr/bin/php enrol/cohort/cli/sync.php
+\$ sudo -u www-data /usr/bin/php enrol/cohort/cli/sync.php
 ";
 
     echo $help;
     die;
 }
 
-$verbose = !empty($options['verbose']);
+if (empty($options['verbose'])) {
+    $trace = new null_progress_trace();
+} else {
+    $trace = new text_progress_trace();
+}
 
-$result = enrol_cohort_sync(null, $verbose);
+$result = enrol_cohort_sync($trace, null);
+$trace->finished();
 
-exit($result);
\ No newline at end of file
+exit($result);
index ee97210..050bdff 100644 (file)
@@ -92,7 +92,9 @@ if ($mform->is_cancelled()) {
     }  else {
         $enrol->add_instance($course, array('name'=>$data->name, 'status'=>$data->status, 'customint1'=>$data->customint1, 'roleid'=>$data->roleid, 'customint2'=>$data->customint2));
     }
-    enrol_cohort_sync($course->id);
+    $trace = new null_progress_trace();
+    enrol_cohort_sync($trace, $course->id);
+    $trace->finished();
     redirect($returnurl);
 }
 
index 56dc5c9..a2370d4 100644 (file)
@@ -132,7 +132,9 @@ class enrol_cohort_plugin extends enrol_plugin {
         global $CFG;
 
         require_once("$CFG->dirroot/enrol/cohort/locallib.php");
-        enrol_cohort_sync();
+        $trace = new null_progress_trace();
+        enrol_cohort_sync($trace);
+        $trace->finished();
     }
 
     /**
@@ -160,7 +162,9 @@ class enrol_cohort_plugin extends enrol_plugin {
         parent::update_status($instance, $newstatus);
 
         require_once("$CFG->dirroot/enrol/cohort/locallib.php");
-        enrol_cohort_sync($instance->courseid);
+        $trace = new null_progress_trace();
+        enrol_cohort_sync($trace, $instance->courseid);
+        $trace->finished();
     }
 
     /**
@@ -279,7 +283,9 @@ class enrol_cohort_plugin extends enrol_plugin {
             $step->set_mapping('enrol', $oldid, $instanceid);
 
             require_once("$CFG->dirroot/enrol/cohort/locallib.php");
-            enrol_cohort_sync($course->id, false);
+            $trace = new null_progress_trace();
+            enrol_cohort_sync($trace, $course->id);
+            $trace->finished();
 
         } else if ($this->get_config('unenrolaction') == ENROL_EXT_REMOVED_SUSPENDNOROLES) {
             $data->customint1 = 0;
@@ -294,7 +300,9 @@ class enrol_cohort_plugin extends enrol_plugin {
             $step->set_mapping('enrol', $oldid, $instanceid);
 
             require_once("$CFG->dirroot/enrol/cohort/locallib.php");
-            enrol_cohort_sync($course->id, false);
+            $trace = new null_progress_trace();
+            enrol_cohort_sync($trace, $course->id);
+            $trace->finished();
 
         } else {
             $step->set_mapping('enrol', $oldid, 0);
index 83dd982..4027af3 100644 (file)
@@ -151,19 +151,17 @@ class enrol_cohort_handler {
 
 /**
  * Sync all cohort course links.
+ * @param progress_trace $trace
  * @param int $courseid one course, empty mean all
- * @param bool $verbose verbose CLI output
  * @return int 0 means ok, 1 means error, 2 means plugin disabled
  */
-function enrol_cohort_sync($courseid = NULL, $verbose = false) {
+function enrol_cohort_sync(progress_trace $trace, $courseid = NULL) {
     global $CFG, $DB;
     require_once("$CFG->dirroot/group/lib.php");
 
     // Purge all roles if cohort sync disabled, those can be recreated later here by cron or CLI.
     if (!enrol_is_enabled('cohort')) {
-        if ($verbose) {
-            mtrace('Cohort sync plugin is disabled, unassigning all plugin roles and stopping.');
-        }
+        $trace->output('Cohort sync plugin is disabled, unassigning all plugin roles and stopping.');
         role_unassign_all(array('component'=>'enrol_cohort'));
         return 2;
     }
@@ -172,9 +170,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
     @set_time_limit(0);
     raise_memory_limit(MEMORY_HUGE);
 
-    if ($verbose) {
-        mtrace('Starting user enrolment synchronisation...');
-    }
+    $trace->output('Starting user enrolment synchronisation...');
 
     $allroles = get_all_roles();
     $instances = array(); //cache
@@ -201,14 +197,10 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
         $instance = $instances[$ue->enrolid];
         if ($ue->status == ENROL_USER_SUSPENDED) {
             $plugin->update_user_enrol($instance, $ue->userid, ENROL_USER_ACTIVE);
-            if ($verbose) {
-                mtrace("  unsuspending: $ue->userid ==> $instance->courseid via cohort $instance->customint1");
-            }
+            $trace->output("unsuspending: $ue->userid ==> $instance->courseid via cohort $instance->customint1", 1);
         } else {
             $plugin->enrol_user($instance, $ue->userid);
-            if ($verbose) {
-                mtrace("  enrolling: $ue->userid ==> $instance->courseid via cohort $instance->customint1");
-            }
+            $trace->output("enrolling: $ue->userid ==> $instance->courseid via cohort $instance->customint1", 1);
         }
     }
     $rs->close();
@@ -229,9 +221,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
         if ($unenrolaction == ENROL_EXT_REMOVED_UNENROL) {
             // Remove enrolment together with group membership, grades, preferences, etc.
             $plugin->unenrol_user($instance, $ue->userid);
-            if ($verbose) {
-                mtrace("  unenrolling: $ue->userid ==> $instance->courseid via cohort $instance->customint1");
-            }
+            $trace->output("unenrolling: $ue->userid ==> $instance->courseid via cohort $instance->customint1", 1);
 
         } else { // ENROL_EXT_REMOVED_SUSPENDNOROLES
             // Just disable and ignore any changes.
@@ -239,9 +229,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
                 $plugin->update_user_enrol($instance, $ue->userid, ENROL_USER_SUSPENDED);
                 $context = context_course::instance($instance->courseid);
                 role_unassign_all(array('userid'=>$ue->userid, 'contextid'=>$context->id, 'component'=>'enrol_cohort', 'itemid'=>$instance->id));
-                if ($verbose) {
-                    mtrace("  suspending and unsassigning all roles: $ue->userid ==> $instance->courseid");
-                }
+                $trace->output("suspending and unsassigning all roles: $ue->userid ==> $instance->courseid", 1);
             }
         }
     }
@@ -267,9 +255,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
     $rs = $DB->get_recordset_sql($sql, $params);
     foreach($rs as $ra) {
         role_assign($ra->roleid, $ra->userid, $ra->contextid, 'enrol_cohort', $ra->itemid);
-        if ($verbose) {
-            mtrace("  assigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname);
-        }
+        $trace->output("assigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname, 1);
     }
     $rs->close();
 
@@ -291,9 +277,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
     $rs = $DB->get_recordset_sql($sql, $params);
     foreach($rs as $ra) {
         role_unassign($ra->roleid, $ra->userid, $ra->contextid, 'enrol_cohort', $ra->itemid);
-        if ($verbose) {
-            mtrace("  unassigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname);
-        }
+        $trace->output("unassigning role: $ra->userid ==> $ra->courseid as ".$allroles[$ra->roleid]->shortname, 1);
     }
     $rs->close();
 
@@ -314,9 +298,7 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
     $rs = $DB->get_recordset_sql($sql, $params);
     foreach($rs as $gm) {
         groups_remove_member($gm->groupid, $gm->userid);
-        if ($verbose) {
-            mtrace("  removing user from group: $gm->userid ==> $gm->courseid - $gm->groupname");
-        }
+        $trace->output("removing user from group: $gm->userid ==> $gm->courseid - $gm->groupname", 1);
     }
     $rs->close();
 
@@ -333,16 +315,12 @@ function enrol_cohort_sync($courseid = NULL, $verbose = false) {
     $rs = $DB->get_recordset_sql($sql, $params);
     foreach($rs as $ue) {
         groups_add_member($ue->groupid, $ue->userid, 'enrol_cohort', $ue->enrolid);
-        if ($verbose) {
-            mtrace("  adding user to group: $ue->userid ==> $ue->courseid - $ue->groupname");
-        }
+        $trace->output("adding user to group: $ue->userid ==> $ue->courseid - $ue->groupname", 1);
     }
     $rs->close();
 
 
-    if ($verbose) {
-        mtrace('...user enrolment synchronisation finished.');
-    }
+    $trace->output('...user enrolment synchronisation finished.');
 
     return 0;
 }
index 75fc773..b21afc3 100644 (file)
@@ -260,6 +260,8 @@ class enrol_cohort_testcase extends advanced_testcase {
         global $DB;
         $this->resetAfterTest();
 
+        $trace = new null_progress_trace();
+
         // Setup a few courses and categories.
 
         $cohortplugin = enrol_get_plugin('cohort');
@@ -319,19 +321,19 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         // Test sync of one course only.
 
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(2, $DB->count_records('role_assignments', array()));
         $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
 
 
         $this->enable_plugin();
-        enrol_cohort_sync($course2->id, false);
+        enrol_cohort_sync($trace, $course2->id);
         $this->assertEquals(3, $DB->count_records('role_assignments', array()));
         $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort3->id)); // Use low level DB api to prevent events!
         $DB->delete_records('cohort', array('id'=>$cohort3->id)); // Use low level DB api to prevent events!
 
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
         $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
         $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user2->id)));
@@ -345,14 +347,14 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort2->id, 'userid'=>$user3->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(6, $DB->count_records('role_assignments', array()));
         $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id, 'userid'=>$user1->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
         $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance2->id, 'userid'=>$user3->id)));
         $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
@@ -363,12 +365,12 @@ class enrol_cohort_testcase extends advanced_testcase {
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id)); // Use low level DB api to prevent events!
         $DB->delete_records('cohort', array('id'=>$cohort1->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(3, $DB->count_records('role_assignments', array()));
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(3, $DB->count_records('role_assignments', array()));
 
@@ -400,7 +402,7 @@ class enrol_cohort_testcase extends advanced_testcase {
         cohort_add_member($cohort1->id, $user4->id);
         cohort_add_member($cohort2->id, $user4->id);
 
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
 
         $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(7, $DB->count_records('role_assignments', array()));
@@ -414,7 +416,7 @@ class enrol_cohort_testcase extends advanced_testcase {
         $cohortinstance1->customint2 = $group2->id;
         $DB->update_record('enrol', $cohortinstance1);
 
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertFalse(groups_is_member($group1->id, $user1->id));
         $this->assertTrue(groups_is_member($group2->id, $user1->id));
         $this->assertTrue($DB->record_exists('groups_members', array('groupid'=>$group2->id, 'userid'=>$user1->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));
@@ -437,6 +439,8 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         $this->resetAfterTest();
 
+        $trace = new null_progress_trace();
+
         // Setup a few courses and categories.
 
         $cohortplugin = enrol_get_plugin('cohort');
@@ -496,13 +500,13 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         // Test sync of one course only.
 
-        enrol_cohort_sync(null, false);
+        enrol_cohort_sync($trace, null);
         $this->assertEquals(2, $DB->count_records('role_assignments', array()));
         $this->assertEquals(2, $DB->count_records('user_enrolments', array()));
 
 
         $this->enable_plugin();
-        enrol_cohort_sync(null, false);
+        enrol_cohort_sync($trace, null);
         $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
         $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
         $this->assertTrue($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user2->id)));
@@ -516,14 +520,14 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort2->id, 'userid'=>$user3->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(7, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(6, $DB->count_records('role_assignments', array()));
         $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>context_course::instance($course1->id)->id, 'userid'=>$user3->id, 'roleid'=>$teacherrole->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance2->id)));
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id, 'userid'=>$user1->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
         $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance2->id, 'userid'=>$user3->id)));
         $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$cohortinstance1->id, 'userid'=>$user1->id)));
@@ -534,12 +538,12 @@ class enrol_cohort_testcase extends advanced_testcase {
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
         $DB->delete_records('cohort_members', array('cohortid'=>$cohort1->id)); // Use low level DB api to prevent events!
         $DB->delete_records('cohort', array('id'=>$cohort1->id)); // Use low level DB api to prevent events!
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(5, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(3, $DB->count_records('role_assignments', array()));
 
         $cohortplugin->set_config('unenrolaction', ENROL_EXT_REMOVED_UNENROL);
-        enrol_cohort_sync($course1->id, false);
+        enrol_cohort_sync($trace, $course1->id);
         $this->assertEquals(3, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(3, $DB->count_records('role_assignments', array()));
 
@@ -573,7 +577,7 @@ class enrol_cohort_testcase extends advanced_testcase {
 
         $this->enable_plugin();
 
-        enrol_cohort_sync(null, false);
+        enrol_cohort_sync($trace, null);
 
         $this->assertEquals(8, $DB->count_records('user_enrolments', array()));
         $this->assertEquals(8, $DB->count_records('role_assignments', array()));
@@ -593,7 +597,7 @@ class enrol_cohort_testcase extends advanced_testcase {
         $cohortinstance3->customint2 = $group3->id;
         $DB->update_record('enrol', $cohortinstance3);
 
-        enrol_cohort_sync(null, false);
+        enrol_cohort_sync($trace, null);
         $this->assertFalse(groups_is_member($group1->id, $user1->id));
         $this->assertTrue(groups_is_member($group2->id, $user1->id));
         $this->assertTrue($DB->record_exists('groups_members', array('groupid'=>$group2->id, 'userid'=>$user1->id, 'component'=>'enrol_cohort', 'itemid'=>$cohortinstance1->id)));