Merge branch 'MDL-43930-master' of git://github.com/damyon/moodle
authorDan Poltawski <dan@moodle.com>
Wed, 5 Mar 2014 03:22:35 +0000 (11:22 +0800)
committerDan Poltawski <dan@moodle.com>
Wed, 5 Mar 2014 03:22:35 +0000 (11:22 +0800)
926 files changed:
admin/environment.xml
admin/handlevirus.php [deleted file]
admin/renderer.php
admin/settings/server.php
admin/settings/users.php
admin/tests/behat/display_short_names.feature
admin/tests/behat/filter_users.feature
admin/tests/behat/upload_users.feature
admin/tool/behat/lang/en/tool_behat.php
admin/tool/behat/renderer.php
admin/tool/behat/tests/behat/basic_actions.feature
admin/tool/behat/tests/behat/data_generators.feature
admin/tool/behat/tests/behat/edit_permissions.feature
admin/tool/behat/tests/behat/get_and_set_fields.feature [new file with mode: 0644]
admin/tool/behat/tests/behat/list_steps.feature
admin/tool/behat/tests/behat/manipulate_forms.feature
admin/tool/behat/tests/behat/nasty_strings.feature
admin/tool/behat/upgrade.txt
admin/tool/log/classes/helper/buffered_writer.php [new file with mode: 0644]
admin/tool/log/classes/helper/reader.php [new file with mode: 0644]
admin/tool/log/classes/helper/store.php [new file with mode: 0644]
admin/tool/log/classes/log/manager.php [new file with mode: 0644]
admin/tool/log/classes/log/observer.php [new file with mode: 0644]
admin/tool/log/classes/log/store.php [new file with mode: 0644]
admin/tool/log/classes/log/writer.php [moved from admin/tool/qeupgradehelper/settings.php with 63% similarity]
admin/tool/log/classes/plugininfo/logstore.php [new file with mode: 0644]
admin/tool/log/classes/setting_managestores.php [new file with mode: 0644]
admin/tool/log/db/events.php [new file with mode: 0644]
admin/tool/log/db/install.php [new file with mode: 0644]
admin/tool/log/db/subplugins.php [new file with mode: 0644]
admin/tool/log/lang/en/tool_log.php [new file with mode: 0644]
admin/tool/log/lib.php [new file with mode: 0644]
admin/tool/log/settings.php [new file with mode: 0644]
admin/tool/log/store/database/classes/helper.php [new file with mode: 0644]
admin/tool/log/store/database/classes/log/store.php [new file with mode: 0644]
admin/tool/log/store/database/lang/en/logstore_database.php [new file with mode: 0644]
admin/tool/log/store/database/settings.php [new file with mode: 0644]
admin/tool/log/store/database/test_settings.php [new file with mode: 0644]
admin/tool/log/store/database/tests/fixtures/event.php [new file with mode: 0644]
admin/tool/log/store/database/tests/store_test.php [new file with mode: 0644]
admin/tool/log/store/database/version.php [new file with mode: 0644]
admin/tool/log/store/legacy/classes/event/legacy_logged.php [new file with mode: 0644]
admin/tool/log/store/legacy/classes/log/store.php [new file with mode: 0644]
admin/tool/log/store/legacy/db/access.php [new file with mode: 0644]
admin/tool/log/store/legacy/lang/en/logstore_legacy.php [new file with mode: 0644]
admin/tool/log/store/legacy/settings.php [new file with mode: 0644]
admin/tool/log/store/legacy/tests/fixtures/event.php [new file with mode: 0644]
admin/tool/log/store/legacy/tests/store_test.php [new file with mode: 0644]
admin/tool/log/store/legacy/version.php [new file with mode: 0644]
admin/tool/log/store/standard/classes/log/store.php [new file with mode: 0644]
admin/tool/log/store/standard/db/access.php [new file with mode: 0644]
admin/tool/log/store/standard/db/install.xml [new file with mode: 0644]
admin/tool/log/store/standard/lang/en/logstore_standard.php [new file with mode: 0644]
admin/tool/log/store/standard/settings.php [new file with mode: 0644]
admin/tool/log/store/standard/tests/fixtures/event.php [new file with mode: 0644]
admin/tool/log/store/standard/tests/store_test.php [new file with mode: 0644]
admin/tool/log/store/standard/version.php [new file with mode: 0644]
admin/tool/log/stores.php [new file with mode: 0644]
admin/tool/log/tests/manager_test.php [new file with mode: 0644]
admin/tool/log/version.php [new file with mode: 0644]
admin/tool/qeupgradehelper/README.txt [deleted file]
admin/tool/qeupgradehelper/afterupgradelib.php [deleted file]
admin/tool/qeupgradehelper/cli/convert.php [deleted file]
admin/tool/qeupgradehelper/convertquiz.php [deleted file]
admin/tool/qeupgradehelper/cronsetup.php [deleted file]
admin/tool/qeupgradehelper/cronsetup_form.php [deleted file]
admin/tool/qeupgradehelper/extracttestcase.php [deleted file]
admin/tool/qeupgradehelper/extracttestcase_form.php [deleted file]
admin/tool/qeupgradehelper/index.php [deleted file]
admin/tool/qeupgradehelper/lang/en/tool_qeupgradehelper.php [deleted file]
admin/tool/qeupgradehelper/lib.php [deleted file]
admin/tool/qeupgradehelper/listpreupgrade.php [deleted file]
admin/tool/qeupgradehelper/listtodo.php [deleted file]
admin/tool/qeupgradehelper/listupgraded.php [deleted file]
admin/tool/qeupgradehelper/locallib.php [deleted file]
admin/tool/qeupgradehelper/partialupgrade-example.php [deleted file]
admin/tool/qeupgradehelper/renderer.php [deleted file]
admin/tool/qeupgradehelper/resetquiz.php [deleted file]
admin/tool/qeupgradehelper/styles.css [deleted file]
admin/tool/spamcleaner/index.php
admin/tool/task/classes/edit_scheduled_task_form.php [new file with mode: 0644]
admin/tool/task/lang/en/tool_task.php [new file with mode: 0644]
admin/tool/task/renderer.php [new file with mode: 0644]
admin/tool/task/scheduledtasks.php [new file with mode: 0644]
admin/tool/task/settings.php [moved from admin/tool/qeupgradehelper/db/install.php with 74% similarity]
admin/tool/task/version.php [moved from admin/tool/qeupgradehelper/version.php with 72% similarity]
admin/tool/uploadcourse/tests/behat/create.feature
admin/tool/uploadcourse/tests/behat/update.feature
auth/cas/auth.php
auth/ldap/auth.php
auth/tests/behat/behat_auth.php
auth/tests/behat/login.feature
backup/moodle2/restore_stepslib.php
backup/util/ui/tests/behat/duplicate_activities.feature
backup/util/ui/tests/behat/restore_moodle2_courses.feature
badges/classes/observer.php
badges/tests/behat/add_badge.feature
badges/tests/behat/award_badge.feature
blocks/tests/behat/behat_blocks.php
blocks/tests/behat/configure_block_throughout_site.feature
blocks/tests/behat/manage_blocks.feature
blocks/tests/behat/return_block_original_state.feature
blog/tests/behat/comment.feature
cache/stores/memcache/lib.php
cache/stores/memcached/lib.php
cache/stores/mongodb/lib.php
calendar/classes/rrule_manager.php [new file with mode: 0644]
calendar/lib.php
calendar/tests/behat/behat_calendar.php
calendar/tests/behat/calendar.feature
calendar/tests/rrule_manager_tests.php [new file with mode: 0644]
cohort/lib.php
cohort/tests/behat/add_cohort.feature
cohort/tests/behat/behat_cohort.php
completion/tests/behat/enable_manual_complete_mark.feature
completion/tests/behat/restrict_activity_by_date.feature
completion/tests/behat/restrict_activity_by_grade.feature
completion/tests/behat/restrict_section_availability.feature
composer.json
course/format/renderer.php
course/modlib.php
course/report/lib.php
course/tests/behat/activities_group_icons.feature
course/tests/behat/add_activities.feature
course/tests/behat/behat_course.php
course/tests/behat/category_management.feature
course/tests/behat/category_resort.feature
course/tests/behat/course_category_management_listing.feature
course/tests/behat/course_controls.feature
course/tests/behat/create_delete_course.feature
course/tests/behat/edit_settings.feature
course/tests/behat/force_group_mode.feature
course/tests/behat/max_number_sections.feature
course/tests/behat/move_activities.feature
course/tests/behat/move_sections.feature
course/tests/behat/rename_roles.feature
course/tests/courselib_test.php
enrol/externallib.php
enrol/guest/tests/behat/guest_access.feature
enrol/imsenterprise/importnow.php
enrol/imsenterprise/settings.php
enrol/self/tests/behat/self_enrolment.feature
enrol/tests/behat/behat_enrol.php
enrol/tests/externallib_test.php
files/renderer.php
filter/mediaplugin/filter.php
grade/grading/form/rubric/tests/behat/behat_gradingform_rubric.php
grade/grading/form/rubric/tests/behat/edit_rubric.feature
grade/grading/form/rubric/tests/behat/publish_rubric_templates.feature
grade/grading/form/rubric/tests/behat/reuse_own_rubrics.feature
grade/grading/tests/behat/behat_grading.php
grade/tests/behat/behat_grade.php
grade/tests/behat/grade_view.feature
group/externallib.php
group/tests/behat/auto_creation.feature
group/tests/behat/create_groups.feature
group/tests/behat/delete_groups.feature
group/tests/behat/groups_import.feature
group/tests/behat/id_uniqueness.feature
group/tests/behat/update_groups.feature
install/lang/ckb/moodle.php
install/lang/it/error.php
lang/en/admin.php
lang/en/calendar.php
lang/en/moodle.php
lang/en/question.php
lang/en/repository.php
lang/en/role.php
lib/accesslib.php
lib/adminlib.php
lib/ajax/ajaxlib.php
lib/behat/behat_base.php
lib/behat/behat_field_manager.php
lib/behat/form_field/behat_form_checkbox.php
lib/behat/form_field/behat_form_date_selector.php
lib/behat/form_field/behat_form_date_time_selector.php
lib/behat/form_field/behat_form_editor.php
lib/behat/form_field/behat_form_field.php
lib/behat/form_field/behat_form_group.php [new file with mode: 0644]
lib/behat/form_field/behat_form_modvisible.php
lib/behat/form_field/behat_form_radio.php
lib/behat/form_field/behat_form_select.php
lib/behat/form_field/behat_form_selectyesno.php
lib/behat/form_field/behat_form_text.php [new file with mode: 0644]
lib/behat/form_field/behat_form_textarea.php [new file with mode: 0644]
lib/classes/event/assessable_submitted.php
lib/classes/event/assessable_uploaded.php
lib/classes/event/base.php
lib/classes/event/course_module_completion_updated.php
lib/classes/event/course_module_created.php
lib/classes/event/course_module_instance_list_viewed.php
lib/classes/event/course_module_updated.php
lib/classes/event/course_module_viewed.php
lib/classes/log/dummy_manager.php [new file with mode: 0644]
lib/classes/log/manager.php [new file with mode: 0644]
lib/classes/log/reader.php [new file with mode: 0644]
lib/classes/log/sql_internal_reader.php [new file with mode: 0644]
lib/classes/log/sql_select_reader.php [new file with mode: 0644]
lib/classes/plugin_manager.php
lib/classes/task/adhoc_task.php [new file with mode: 0644]
lib/classes/task/automated_backup_task.php [new file with mode: 0644]
lib/classes/task/backup_cleanup_task.php [new file with mode: 0644]
lib/classes/task/badges_cron_task.php [new file with mode: 0644]
lib/classes/task/blog_cron_task.php [new file with mode: 0644]
lib/classes/task/cache_cleanup_task.php [new file with mode: 0644]
lib/classes/task/cache_cron_task.php [new file with mode: 0644]
lib/classes/task/calendar_cron_task.php [new file with mode: 0644]
lib/classes/task/check_for_updates_task.php [new file with mode: 0644]
lib/classes/task/completion_cron_task.php [new file with mode: 0644]
lib/classes/task/context_cleanup_task.php [new file with mode: 0644]
lib/classes/task/create_contexts_task.php [new file with mode: 0644]
lib/classes/task/delete_incomplete_users_task.php [new file with mode: 0644]
lib/classes/task/delete_unconfirmed_users_task.php [new file with mode: 0644]
lib/classes/task/events_cron_task.php [new file with mode: 0644]
lib/classes/task/file_temp_cleanup_task.php [new file with mode: 0644]
lib/classes/task/file_trash_cleanup_task.php [new file with mode: 0644]
lib/classes/task/grade_cron_task.php [new file with mode: 0644]
lib/classes/task/legacy_plugin_cron_task.php [new file with mode: 0644]
lib/classes/task/manager.php [new file with mode: 0644]
lib/classes/task/messaging_cleanup_task.php [new file with mode: 0644]
lib/classes/task/password_reset_cleanup_task.php [new file with mode: 0644]
lib/classes/task/plagiarism_cron_task.php [new file with mode: 0644]
lib/classes/task/portfolio_cron_task.php [new file with mode: 0644]
lib/classes/task/question_cron_task.php [new file with mode: 0644]
lib/classes/task/registration_cron_task.php [new file with mode: 0644]
lib/classes/task/scheduled_task.php [new file with mode: 0644]
lib/classes/task/send_failed_login_notifications_task.php [new file with mode: 0644]
lib/classes/task/send_new_user_passwords_task.php [new file with mode: 0644]
lib/classes/task/session_cleanup_task.php [new file with mode: 0644]
lib/classes/task/stats_cron_task.php [new file with mode: 0644]
lib/classes/task/tag_cron_task.php [new file with mode: 0644]
lib/classes/task/task_base.php [new file with mode: 0644]
lib/completionlib.php
lib/cronlib.php
lib/csslib.php
lib/customcheckslib.php
lib/datalib.php
lib/db/access.php
lib/db/events.php
lib/db/install.xml
lib/db/services.php
lib/db/tasks.php [new file with mode: 0644]
lib/db/upgrade.php
lib/deprecatedlib.php
lib/dml/sqlsrv_native_moodle_database.php
lib/dml/tests/dml_test.php
lib/dtl/database_exporter.php
lib/dtl/database_importer.php
lib/dtl/file_xml_database_exporter.php
lib/dtl/string_xml_database_exporter.php
lib/environmentlib.php
lib/filestorage/file_exceptions.php
lib/flowplayer/README.txt
lib/flowplayer/README_audio.txt
lib/flowplayer/flowplayer-3.2.12.min.js [deleted file]
lib/flowplayer/flowplayer-3.2.13.js [moved from lib/flowplayer/flowplayer-3.2.12.js with 98% similarity]
lib/flowplayer/flowplayer-3.2.13.min.js [new file with mode: 0644]
lib/flowplayer/flowplayer-3.2.16.swf [deleted file]
lib/flowplayer/flowplayer-3.2.18.swf [new file with mode: 0644]
lib/flowplayer/flowplayer.audio-3.2.10.swf [deleted file]
lib/flowplayer/flowplayer.audio-3.2.11.swf [new file with mode: 0644]
lib/flowplayer/flowplayer.controls-3.2.15.swf [deleted file]
lib/flowplayer/flowplayer.controls-3.2.16.swf [new file with mode: 0644]
lib/form/yui/build/moodle-form-dateselector/moodle-form-dateselector-debug.js [new file with mode: 0644]
lib/form/yui/build/moodle-form-dateselector/moodle-form-dateselector-min.js [new file with mode: 0644]
lib/form/yui/build/moodle-form-dateselector/moodle-form-dateselector.js [new file with mode: 0644]
lib/form/yui/dateselector/assets/skins/sam/dateselector.css [deleted file]
lib/form/yui/dateselector/dateselector.js [deleted file]
lib/form/yui/src/dateselector/build.json [new file with mode: 0644]
lib/form/yui/src/dateselector/js/calendar.js [new file with mode: 0644]
lib/form/yui/src/dateselector/js/dateselector.js [new file with mode: 0644]
lib/form/yui/src/dateselector/js/moodlecalendar.js [new file with mode: 0644]
lib/form/yui/src/dateselector/meta/dateselector.json [new file with mode: 0644]
lib/formslib.php
lib/javascript-static.js
lib/moodlelib.php
lib/outputcomponents.php
lib/outputlib.php
lib/outputrequirementslib.php
lib/pagelib.php
lib/phpunit/classes/util.php
lib/portfolio/exporter.php
lib/portfoliolib.php
lib/questionlib.php
lib/setuplib.php
lib/statslib.php
lib/testing/generator/data_generator.php
lib/tests/adhoc_task_test.php [new file with mode: 0644]
lib/tests/behat/behat_data_generators.php
lib/tests/behat/behat_deprecated.php
lib/tests/behat/behat_forms.php
lib/tests/behat/behat_general.php
lib/tests/behat/behat_hooks.php
lib/tests/behat/behat_permissions.php
lib/tests/completionlib_test.php
lib/tests/cronlib_test.php
lib/tests/datalib_update_with_unique_index_test.php [new file with mode: 0644]
lib/tests/event_test.php
lib/tests/fixtures/event_fixtures.php
lib/tests/scheduled_task_test.php [new file with mode: 0644]
lib/thirdpartylibs.xml
lib/upgrade.txt
lib/upgradelib.php
lib/uploadlib.php
lib/yui/build/moodle-core-blocks/moodle-core-blocks-debug.js
lib/yui/build/moodle-core-blocks/moodle-core-blocks-min.js
lib/yui/build/moodle-core-blocks/moodle-core-blocks.js
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-debug.js
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue-min.js
lib/yui/build/moodle-core-chooserdialogue/moodle-core-chooserdialogue.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-debug.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-min.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue.js
lib/yui/build/moodle-core-tooltip/moodle-core-tooltip-debug.js
lib/yui/build/moodle-core-tooltip/moodle-core-tooltip-min.js
lib/yui/build/moodle-core-tooltip/moodle-core-tooltip.js
lib/yui/build/moodle-core-widget-focusafterclose/moodle-core-widget-focusafterclose-debug.js [new file with mode: 0644]
lib/yui/build/moodle-core-widget-focusafterclose/moodle-core-widget-focusafterclose-min.js [new file with mode: 0644]
lib/yui/build/moodle-core-widget-focusafterclose/moodle-core-widget-focusafterclose.js [new file with mode: 0644]
lib/yui/src/blocks/js/blockregion.js
lib/yui/src/blocks/js/blocks.js
lib/yui/src/blocks/js/manager.js
lib/yui/src/chooserdialogue/js/chooserdialogue.js
lib/yui/src/notification/js/dialogue.js
lib/yui/src/notification/meta/notification.json
lib/yui/src/tooltip/js/tooltip.js
lib/yui/src/widget-focusafterclose/build.json [new file with mode: 0644]
lib/yui/src/widget-focusafterclose/js/focusafter.js [new file with mode: 0644]
lib/yui/src/widget-focusafterclose/meta/notification.json [new file with mode: 0644]
message/tests/behat/behat_message.php
message/tests/behat/block_users.feature
message/tests/behat/display_history.feature
message/tests/behat/manage_contacts.feature
message/tests/behat/message_participants.feature
message/tests/behat/search_history.feature
mod/assign/externallib.php
mod/assign/feedback/editpdf/fpdi/fpdf_tpl.php
mod/assign/tests/behat/allow_another_attempt.feature
mod/assign/tests/behat/comment_inline.feature
mod/assign/tests/behat/edit_previous_feedback.feature
mod/assign/tests/behat/group_submission.feature
mod/assign/tests/behat/online_submissions.feature
mod/assign/tests/behat/prevent_submission_changes.feature
mod/assign/tests/behat/quickgrading.feature
mod/book/edit.php
mod/book/index.php
mod/book/view.php
mod/chat/chat_ajax.php
mod/chat/index.php
mod/choice/index.php
mod/choice/tests/behat/behat_mod_choice.php
mod/choice/tests/behat/change_response.feature
mod/choice/tests/behat/publish_results.feature
mod/choice/view.php
mod/data/index.php
mod/data/mod_form.php
mod/data/view.php
mod/feedback/classes/event/course_module_viewed.php
mod/feedback/complete.php
mod/feedback/complete_guest.php
mod/feedback/index.php
mod/feedback/tests/events_test.php
mod/feedback/view.php
mod/folder/index.php
mod/folder/view.php
mod/forum/classes/event/course_module_viewed.php [moved from mod/forum/classes/event/forum_viewed.php with 65% similarity]
mod/forum/index.php
mod/forum/lang/en/forum.php
mod/forum/lib.php
mod/forum/post.php
mod/forum/renderer.php
mod/forum/search.php
mod/forum/tests/behat/behat_mod_forum.php
mod/forum/tests/behat/completion_condition_number_discussions.feature
mod/forum/tests/behat/discussion_display.feature
mod/forum/tests/behat/edit_post_student.feature
mod/forum/tests/behat/edit_post_teacher.feature
mod/forum/tests/events_test.php
mod/forum/view.php
mod/glossary/lib.php
mod/glossary/tests/behat/behat_mod_glossary.php
mod/glossary/tests/behat/prevent_duplicate_entries.feature
mod/glossary/tests/behat/search_entries.feature
mod/imscp/backup/moodle1/lib.php
mod/imscp/backup/moodle2/backup_imscp_stepslib.php
mod/imscp/backup/moodle2/restore_imscp_activity_task.class.php
mod/imscp/backup/moodle2/restore_imscp_stepslib.php
mod/imscp/classes/event/course_module_instance_list_viewed.php [new file with mode: 0644]
mod/imscp/classes/event/course_module_viewed.php [new file with mode: 0644]
mod/imscp/db/install.php
mod/imscp/db/upgrade.php
mod/imscp/index.php
mod/imscp/lang/en/imscp.php
mod/imscp/lib.php
mod/imscp/locallib.php
mod/imscp/mod_form.php
mod/imscp/settings.php
mod/imscp/version.php
mod/imscp/view.php
mod/label/backup/moodle1/lib.php
mod/label/backup/moodle2/backup_label_stepslib.php
mod/label/backup/moodle2/restore_label_activity_task.class.php
mod/label/backup/moodle2/restore_label_stepslib.php
mod/label/db/upgrade.php
mod/label/index.php
mod/label/lang/en/label.php
mod/label/lib.php
mod/label/mod_form.php
mod/label/version.php
mod/label/view.php
mod/lesson/backup/moodle1/lib.php
mod/lesson/backup/moodle2/backup_lesson_stepslib.php
mod/lesson/backup/moodle2/restore_lesson_activity_task.class.php
mod/lesson/backup/moodle2/restore_lesson_stepslib.php
mod/lesson/continue.php
mod/lesson/db/messages.php
mod/lesson/db/upgrade.php
mod/lesson/edit.php
mod/lesson/editpage.php
mod/lesson/editpage_form.php
mod/lesson/essay.php
mod/lesson/essay_form.php
mod/lesson/format.php
mod/lesson/highscores.php
mod/lesson/import.php
mod/lesson/import_form.php
mod/lesson/index.php
mod/lesson/lang/en/lesson.php
mod/lesson/lesson.php
mod/lesson/lib.php
mod/lesson/locallib.php
mod/lesson/mediafile.php
mod/lesson/mod_form.php
mod/lesson/pagetypes/branchtable.php
mod/lesson/pagetypes/cluster.php
mod/lesson/pagetypes/endofbranch.php
mod/lesson/pagetypes/endofcluster.php
mod/lesson/pagetypes/essay.php
mod/lesson/pagetypes/matching.php
mod/lesson/pagetypes/multichoice.php
mod/lesson/pagetypes/numerical.php
mod/lesson/pagetypes/shortanswer.php
mod/lesson/pagetypes/truefalse.php
mod/lesson/reformat.php
mod/lesson/renderer.php
mod/lesson/report.php
mod/lesson/settings.php
mod/lesson/tabs.php
mod/lesson/tests/behat/date_availability.feature
mod/lesson/tests/behat/lesson_navigation.feature
mod/lesson/tests/behat/password_protection.feature
mod/lesson/tests/behat/time_limit.feature
mod/lesson/version.php
mod/lesson/view.php
mod/lesson/view_form.php
mod/lti/TrivialStore.php
mod/lti/backup/moodle1/lib.php
mod/lti/backup/moodle2/backup_lti_stepslib.php
mod/lti/backup/moodle2/restore_lti_activity_task.class.php
mod/lti/backup/moodle2/restore_lti_stepslib.php
mod/lti/db/upgrade.php
mod/lti/edit_form.php
mod/lti/grade.php
mod/lti/index.php
mod/lti/instructor_edit_tool_type.php
mod/lti/lang/en/lti.php
mod/lti/launch.php
mod/lti/lib.php
mod/lti/localadminlib.php
mod/lti/locallib.php
mod/lti/mod_form.php
mod/lti/request_tool.php
mod/lti/return.php
mod/lti/service.php
mod/lti/servicelib.php
mod/lti/settings.php
mod/lti/typessettings.php
mod/lti/version.php
mod/lti/view.php
mod/page/backup/moodle1/lib.php
mod/page/backup/moodle2/backup_page_stepslib.php
mod/page/backup/moodle2/restore_page_activity_task.class.php
mod/page/backup/moodle2/restore_page_stepslib.php
mod/page/db/install.php
mod/page/db/upgrade.php
mod/page/index.php
mod/page/lang/en/page.php
mod/page/lib.php
mod/page/locallib.php
mod/page/mod_form.php
mod/page/settings.php
mod/page/version.php
mod/page/view.php
mod/quiz/accessrule/delaybetweenattempts/tests/rule_test.php
mod/quiz/accessrule/ipaddress/tests/rule_test.php
mod/quiz/accessrule/numattempts/tests/rule_test.php
mod/quiz/accessrule/openclosedate/tests/rule_test.php
mod/quiz/accessrule/password/tests/rule_test.php
mod/quiz/accessrule/safebrowser/tests/rule_test.php
mod/quiz/accessrule/securewindow/tests/rule_test.php
mod/quiz/accessrule/timelimit/tests/rule_test.php
mod/quiz/attemptlib.php
mod/quiz/backup/moodle2/backup_quiz_stepslib.php
mod/quiz/backup/moodle2/restore_quiz_stepslib.php
mod/quiz/db/install.xml
mod/quiz/db/upgrade.php
mod/quiz/edit.php
mod/quiz/editlib.php
mod/quiz/lib.php
mod/quiz/locallib.php
mod/quiz/mod_form.php
mod/quiz/override_form.php
mod/quiz/report/attemptsreport_table.php
mod/quiz/report/grading/report.php
mod/quiz/report/overview/report.php
mod/quiz/report/reportlib.php
mod/quiz/report/responses/first_or_all_responses_table.php [new file with mode: 0644]
mod/quiz/report/responses/last_responses_table.php [moved from mod/quiz/report/responses/responses_table.php with 88% similarity]
mod/quiz/report/responses/report.php
mod/quiz/report/responses/responses_form.php
mod/quiz/report/responses/responses_options.php
mod/quiz/report/responses/tests/fixtures/questions00.csv [new file with mode: 0644]
mod/quiz/report/responses/tests/fixtures/quizzes.csv [new file with mode: 0644]
mod/quiz/report/responses/tests/fixtures/responses00.csv [new file with mode: 0644]
mod/quiz/report/responses/tests/fixtures/steps00.csv [new file with mode: 0644]
mod/quiz/report/responses/tests/responses_from_steps_walkthrough_test.php [new file with mode: 0644]
mod/quiz/report/statistics/report.php
mod/quiz/styles.css
mod/quiz/tests/attempt_walkthrough_from_csv_test.php
mod/quiz/tests/attempt_walkthrough_test.php
mod/quiz/tests/behat/add_quiz.feature [new file with mode: 0644]
mod/quiz/tests/behat/behat_mod_quiz.php [new file with mode: 0644]
mod/quiz/tests/editlib_test.php
mod/quiz/tests/generator/lib.php
mod/quiz/tests/locallib_test.php
mod/quiz/tests/quizobj_test.php
mod/quiz/upgrade.txt
mod/quiz/version.php
mod/quiz/view.php
mod/resource/index.php
mod/resource/view.php
mod/scorm/backup/moodle1/lib.php
mod/scorm/backup/moodle2/backup_scorm_stepslib.php
mod/scorm/backup/moodle2/restore_scorm_activity_task.class.php
mod/scorm/backup/moodle2/restore_scorm_stepslib.php
mod/scorm/datamodels/aicclib.php
mod/scorm/datamodels/scormlib.php
mod/scorm/db/upgrade.php
mod/scorm/index.php
mod/scorm/lang/en/scorm.php
mod/scorm/lib.php
mod/scorm/locallib.php
mod/scorm/mod_form.php
mod/scorm/report/userreportinteractions.php
mod/scorm/tabs.php
mod/scorm/tests/behat/add_scorm.feature
mod/scorm/version.php
mod/scorm/view.php
mod/survey/backup/moodle1/lib.php
mod/survey/backup/moodle2/backup_survey_stepslib.php
mod/survey/backup/moodle2/restore_survey_activity_task.class.php
mod/survey/backup/moodle2/restore_survey_stepslib.php
mod/survey/classes/event/course_module_instance_list_viewed.php [new file with mode: 0644]
mod/survey/classes/event/course_module_viewed.php [new file with mode: 0644]
mod/survey/classes/event/report_downloaded.php [new file with mode: 0644]
mod/survey/classes/event/report_viewed.php [new file with mode: 0644]
mod/survey/classes/event/response_submitted.php [new file with mode: 0644]
mod/survey/download.php
mod/survey/index.php
mod/survey/lang/en/survey.php
mod/survey/lib.php
mod/survey/report.php
mod/survey/save.php
mod/survey/tests/behat/survey_types.feature
mod/survey/tests/events_test.php [new file with mode: 0644]
mod/survey/version.php
mod/survey/view.php
mod/url/index.php
mod/url/view.php
mod/wiki/admin.php
mod/wiki/backup/moodle1/lib.php
mod/wiki/backup/moodle2/backup_wiki_settingslib.php
mod/wiki/backup/moodle2/backup_wiki_stepslib.php
mod/wiki/backup/moodle2/restore_wiki_activity_task.class.php
mod/wiki/backup/moodle2/restore_wiki_stepslib.php
mod/wiki/comments.php
mod/wiki/create_form.php
mod/wiki/db/upgrade.php
mod/wiki/diff.php
mod/wiki/edit.php
mod/wiki/edit_form.php
mod/wiki/editcomments.php
mod/wiki/editors/html.php
mod/wiki/editors/wiki_editor.php
mod/wiki/editors/wikieditor.php
mod/wiki/editors/wikifiletable.php
mod/wiki/files.php
mod/wiki/filesedit.php
mod/wiki/filesedit_form.php
mod/wiki/history.php
mod/wiki/index.php
mod/wiki/instancecomments.php
mod/wiki/lang/en/wiki.php
mod/wiki/lib.php
mod/wiki/locallib.php
mod/wiki/lock.php
mod/wiki/map.php
mod/wiki/mod_form.php
mod/wiki/overridelocks.php
mod/wiki/pagelib.php
mod/wiki/parser/markups/creole.php
mod/wiki/parser/markups/html.php
mod/wiki/parser/markups/nwiki.php
mod/wiki/parser/markups/wikimarkup.php
mod/wiki/parser/parser.php
mod/wiki/parser/utils.php
mod/wiki/prettyview.php
mod/wiki/renderer.php
mod/wiki/restoreversion.php
mod/wiki/search.php
mod/wiki/styles.css
mod/wiki/tests/behat/collaborative_individual.feature
mod/wiki/tests/behat/page_history.feature
mod/wiki/tests/behat/preview_page.feature
mod/wiki/tests/behat/wiki_formats.feature
mod/wiki/version.php
mod/wiki/view.php
mod/wiki/viewversion.php
mod/workshop/aggregate.php
mod/workshop/allocation.php
mod/workshop/allocation/lib.php
mod/workshop/allocation/manual/tests/behat/behat_workshopallocation_manual.php [new file with mode: 0644]
mod/workshop/assessment.php
mod/workshop/backup/moodle1/lib.php
mod/workshop/backup/moodle2/restore_workshop_activity_task.class.php
mod/workshop/backup/moodle2/restore_workshop_stepslib.php
mod/workshop/classes/event/assessable_uploaded.php
mod/workshop/classes/event/assessment_evaluated.php [new file with mode: 0644]
mod/workshop/classes/event/assessment_evaluations_reset.php [new file with mode: 0644]
mod/workshop/classes/event/assessment_reevaluated.php [new file with mode: 0644]
mod/workshop/classes/event/assessments_reset.php [new file with mode: 0644]
mod/workshop/classes/event/course_module_instance_list_viewed.php [new file with mode: 0644]
mod/workshop/classes/event/course_module_viewed.php
mod/workshop/classes/event/phase_switched.php [new file with mode: 0644]
mod/workshop/classes/event/submission_assessed.php [new file with mode: 0644]
mod/workshop/classes/event/submission_created.php [new file with mode: 0644]
mod/workshop/classes/event/submission_reassessed.php [new file with mode: 0644]
mod/workshop/classes/event/submission_updated.php [new file with mode: 0644]
mod/workshop/classes/event/submission_viewed.php [new file with mode: 0644]
mod/workshop/db/subplugins.php
mod/workshop/db/uninstall.php
mod/workshop/editform.php
mod/workshop/editformpreview.php
mod/workshop/eval/lib.php
mod/workshop/exassessment.php
mod/workshop/excompare.php
mod/workshop/exsubmission.php
mod/workshop/feedbackauthor_form.php
mod/workshop/feedbackreviewer_form.php
mod/workshop/form/assessment_form.php
mod/workshop/form/edit_form.php
mod/workshop/form/lib.php
mod/workshop/index.php
mod/workshop/lang/en/workshop.php
mod/workshop/lib.php
mod/workshop/locallib.php
mod/workshop/mod_form.php
mod/workshop/renderer.php
mod/workshop/settings.php
mod/workshop/submission.php
mod/workshop/submission_form.php
mod/workshop/switchphase.php
mod/workshop/tests/behat/behat_mod_workshop.php [new file with mode: 0644]
mod/workshop/tests/behat/workshop_assessment.feature [new file with mode: 0644]
mod/workshop/tests/events_test.php [new file with mode: 0644]
mod/workshop/tests/fixtures/testable.php [new file with mode: 0644]
mod/workshop/tests/locallib_test.php
mod/workshop/toolbox.php
mod/workshop/view.php
question/behaviour/adaptive/behaviour.php
question/behaviour/adaptive/behaviourtype.php
question/behaviour/behaviourbase.php
question/behaviour/behaviourtypebase.php
question/behaviour/interactive/behaviour.php
question/behaviour/interactive/behaviourtype.php
question/behaviour/upgrade.txt
question/engine/datalib.php
question/engine/questionattempt.php
question/engine/questionusage.php
question/engine/upgrade/upgradelib.php
question/format/blackboard_six/format.php
question/format/blackboard_six/formatbase.php
question/format/blackboard_six/formatpool.php
question/format/blackboard_six/formatqti.php
question/format/blackboard_six/tests/blackboardformatpool_test.php
question/format/blackboard_six/tests/blackboardsixformatqti_test.php
question/tests/behat/behat_question.php
question/tests/behat/copy_questions.feature
question/tests/behat/edit_questions.feature
question/tests/behat/preview_question.feature
question/tests/behat/question_categories.feature
question/type/calculated/questiontype.php
question/type/calculated/tests/upgradelibnewqe_test.php
question/type/calculatedmulti/tests/upgradelibnewqe_test.php
question/type/calculatedsimple/edit_calculatedsimple_form.php
question/type/calculatedsimple/tests/upgradelibnewqe_test.php
question/type/description/tests/upgradelibnewqe_test.php
question/type/edit_question_form.php
question/type/essay/tests/upgradelibnewqe_test.php
question/type/match/tests/upgradelibnewqe_test.php
question/type/multianswer/edit_multianswer_form.php
question/type/multianswer/tests/upgradelibnewqe_test.php
question/type/multichoice/tests/upgradelibnewqe_test.php
question/type/numerical/tests/upgradelibnewqe_test.php
question/type/random/tests/upgradelibnewqe_test.php
question/type/shortanswer/tests/upgradelibnewqe_test.php
question/type/truefalse/tests/upgradelibnewqe_test.php
repository/alfresco/db/upgrade.php [new file with mode: 0644]
repository/alfresco/db/upgradelib.php [new file with mode: 0644]
repository/alfresco/lang/en/repository_alfresco.php
repository/alfresco/lib.php
repository/alfresco/version.php
repository/flickr_public/lang/en/repository_flickr_public.php
repository/flickr_public/lib.php
repository/recent/tests/behat/add_recent.feature
repository/tests/behat/cancel_add_file.feature
repository/tests/behat/create_folders.feature
repository/tests/behat/create_shortcut.feature
repository/tests/behat/overwrite_file.feature
repository/tests/behat/zip_and_unzip.feature
theme/afterburner/config.php
theme/afterburner/db/upgrade.php
theme/afterburner/lang/en/theme_afterburner.php
theme/afterburner/layout/default.php
theme/afterburner/layout/embedded.php
theme/afterburner/lib.php
theme/afterburner/renderers.php
theme/afterburner/settings.php
theme/afterburner/version.php
theme/anomaly/config.php
theme/anomaly/lang/en/theme_anomaly.php
theme/anomaly/layout/frontpage.php
theme/anomaly/layout/general.php
theme/anomaly/layout/report.php
theme/anomaly/lib.php
theme/anomaly/renderers.php
theme/anomaly/settings.php
theme/anomaly/version.php
theme/arialist/layout/frontpage.php
theme/arialist/layout/general.php
theme/arialist/layout/report.php
theme/arialist/lib.php
theme/arialist/settings.php
theme/base/cli/svgtool.php
theme/base/config.php
theme/base/lang/en/theme_base.php
theme/base/layout/embedded.php
theme/base/layout/frontpage.php
theme/base/layout/general.php
theme/base/layout/report.php
theme/base/style/admin.css
theme/base/style/filemanager.css
theme/base/version.php
theme/binarius/config.php
theme/binarius/layout/frontpage.php
theme/binarius/layout/general.php
theme/binarius/layout/report.php
theme/binarius/version.php
theme/bootstrapbase/config.php
theme/bootstrapbase/lang/en/theme_bootstrapbase.php
theme/bootstrapbase/layout/columns1.php
theme/bootstrapbase/layout/columns2.php
theme/bootstrapbase/layout/columns3.php
theme/bootstrapbase/layout/embedded.php
theme/bootstrapbase/layout/maintenance.php
theme/bootstrapbase/layout/popup.php
theme/bootstrapbase/layout/secure.php
theme/bootstrapbase/less/README
theme/bootstrapbase/less/moodle.less
theme/bootstrapbase/less/moodle/admin.less
theme/bootstrapbase/less/moodle/bootstrapoverride.less
theme/bootstrapbase/less/moodle/filemanager.less
theme/bootstrapbase/less/moodle/responsive.less
theme/bootstrapbase/renderers/core_renderer.php
theme/bootstrapbase/style/moodle.css
theme/bootstrapbase/version.php
theme/boxxie/layout/embedded.php
theme/boxxie/layout/frontpage.php
theme/boxxie/layout/general.php
theme/brick/layout/frontpage.php
theme/brick/layout/general.php
theme/brick/lib.php
theme/brick/settings.php
theme/canvas/lang/en/theme_canvas.php
theme/canvas/layout/embedded.php
theme/canvas/layout/frontpage.php
theme/canvas/layout/general.php
theme/canvas/layout/report.php
theme/canvas/style/admin.css
theme/clean/layout/columns1.php
theme/clean/layout/columns2.php
theme/clean/layout/columns3.php
theme/clean/layout/embedded.php
theme/clean/layout/maintenance.php
theme/clean/layout/secure.php
theme/formal_white/style/core.css
theme/formfactor/layout/embedded.php
theme/formfactor/layout/frontpage.php
theme/formfactor/layout/general.php
theme/formfactor/version.php
theme/fusion/layout/frontpage.php
theme/fusion/layout/general.php
theme/fusion/lib.php
theme/fusion/settings.php
theme/leatherbound/layout/frontpage.php
theme/leatherbound/layout/general.php
theme/leatherbound/layout/report.php
theme/magazine/config.php
theme/magazine/lang/en/theme_magazine.php
theme/magazine/layout/embedded.php
theme/magazine/layout/frontpage.php
theme/magazine/layout/general.php
theme/magazine/lib.php
theme/magazine/settings.php
theme/magazine/version.php
theme/nimble/layout/frontpage.php
theme/nimble/layout/general.php
theme/nimble/lib.php
theme/nimble/settings.php
theme/nonzero/layout/frontpage.php
theme/nonzero/layout/general.php
theme/nonzero/lib.php
theme/nonzero/settings.php
theme/overlay/layout/frontpage.php
theme/overlay/layout/general.php
theme/overlay/lib.php
theme/overlay/settings.php
theme/overlay/version.php
theme/serenity/config.php
theme/serenity/lang/en/theme_serenity.php
theme/sky_high/config.php
theme/sky_high/lang/en/theme_sky_high.php
theme/sky_high/layout/frontpage.php
theme/sky_high/layout/general.php
theme/sky_high/layout/report.php
theme/sky_high/lib.php
theme/sky_high/settings.php
theme/sky_high/version.php
theme/splash/layout/embedded.php
theme/splash/layout/report.php
theme/standard/style/admin.css
theme/standardold/layout/embedded.php
theme/standardold/layout/frontpage.php
theme/standardold/layout/general.php
theme/styles.php
theme/styles_debug.php
theme/upgrade.txt
theme/yui_combo.php
user/action_redir.php
user/addnote.php
user/edit.php
user/edit_form.php
user/editadvanced.php
user/editadvanced_form.php
user/editlib.php
user/emailupdate.php
user/externallib.php
user/files.php
user/files_form.php
user/filters/checkbox.php
user/filters/cohort.php
user/filters/courserole.php
user/filters/date.php
user/filters/globalrole.php
user/filters/lib.php
user/filters/profilefield.php
user/filters/select.php
user/filters/simpleselect.php
user/filters/text.php
user/filters/user_filter_forms.php
user/filters/yesno.php
user/groupaddnote.php
user/grouppix.php
user/index.php
user/lib.php
user/managetoken.php
user/messageselect.php
user/pix.php
user/pixgroup.php
user/policy.php
user/portfolio.php
user/portfoliologs.php
user/profile.php
user/profile/definelib.php
user/profile/field/checkbox/define.class.php
user/profile/field/checkbox/field.class.php
user/profile/field/checkbox/lang/en/profilefield_checkbox.php
user/profile/field/checkbox/version.php
user/profile/field/datetime/define.class.php
user/profile/field/datetime/field.class.php
user/profile/field/menu/define.class.php
user/profile/field/menu/field.class.php
user/profile/field/menu/lang/en/profilefield_menu.php
user/profile/field/menu/version.php
user/profile/field/text/define.class.php
user/profile/field/text/field.class.php
user/profile/field/text/lang/en/profilefield_text.php
user/profile/field/text/version.php
user/profile/field/textarea/define.class.php
user/profile/field/textarea/field.class.php
user/profile/field/textarea/lang/en/profilefield_textarea.php
user/profile/field/textarea/version.php
user/profile/index.php
user/profile/index_category_form.php
user/profile/index_field_form.php
user/profile/lib.php
user/profilesys.php
user/renderer.php
user/repository.php
user/selector/lib.php
user/selector/module.js
user/selector/search.php
user/tests/behat/edituserpassword.feature
user/tests/externallib_test.php
user/view.php
version.php

index 4edfcd1..b1cfc26 100644 (file)
         </FEEDBACK>
       </PHP_SETTING>
     </PHP_SETTINGS>
+    <CUSTOM_CHECKS>
+      <CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="quizattemptsupgradedmessage" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+    </CUSTOM_CHECKS>
   </MOODLE>
 </COMPATIBILITY_MATRIX>
diff --git a/admin/handlevirus.php b/admin/handlevirus.php
deleted file mode 100644 (file)
index 36cc0e3..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-<?php
-/** This expects the output from a command like
- * clamscan -r --infected --no-summary <files> 2>&1 | php -d error_log=/path/to/log thisfile.php
- * also it's important that the output of clamscan prints the FULL PATH to each infected file, so use absolute paths for area to scan
- * also it should be run as root, or whatever the webserver runs as so that it has the right permissions in the quarantine dir etc.
- * php -d error_log=/path/to/log thisfile.php will override the default error log for php cli, which is stderr, so if you want this script to just print stuff out, use php thisfile.php instead.
- */
-
-die('TODO: MDL-19380');
-
-$fd = fopen('php://stdin','r');
-if (!$fd) {
-    exit();
-}
-
-require_once(dirname(dirname(__FILE__)).'/config.php');
-require_once($CFG->libdir.'/eventslib.php');
-require_once($CFG->dirroot.'/lib/uploadlib.php'); // contains virus handling stuff.
-
-$site = get_site();
-
-while(!feof($fd)) {
-    $entry = fgets($fd);
-    if (strlen(trim($entry)) == 0) {
-        continue;
-    }
-    if (!$file = validate_line($entry)) {
-        continue;
-    }
-    $bits = explode('/',$file);
-    $a->filename = $bits[count($bits)-1];
-
-    if (!$log = $DB->get_record("log", array("module"=>"upload", "info"=>$file, "action"=>"upload"))) {
-        $a->action = clam_handle_infected_file($file,0,false);
-        clam_replace_infected_file($file);
-        notify_admins_unknown($file,$a);
-        continue;
-    }
-    $action = clam_handle_infected_file($file,$log->userid,true);
-    clam_replace_infected_file($file);
-
-    $ctxselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
-    $ctxjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
-    $sql = "SELECT c.id, c.fullname $ctxselect FROM {course} c $ctxjoin WHERE c.id = :courseid";
-    $course = $DB->get_record_sql($sql, array('courseid' => $log->course, 'contextlevel' => CONTEXT_COURSE));
-    context_helper::preload_from_record($course);
-
-    $user = $DB->get_record("user", array("id"=>$log->userid));
-    $subject = get_string('virusfoundsubject','moodle',format_string($site->fullname));
-    $a->date = userdate($log->time);
-
-    $a->action = $action;
-    $a->course = format_string($course->fullname, true, array('context' => context_course::instance($course->id)));
-    $a->user = fullname($user);
-
-    notify_user($user,$subject,$a);
-    notify_admins($user,$subject,$a);
-}
-fclose($fd);
-
-
-function notify_user($user,$subject,$a) {
-
-    if (!$user) {
-        return false;
-    }
-    $body = get_string('virusfoundlater','moodle',$a);
-
-    $eventdata = new stdClass();
-    $eventdata->modulename        = 'moodle';
-    $eventdata->userfrom          = get_admin();
-    $eventdata->userto            = $user;
-    $eventdata->subject           = $subject;
-    $eventdata->fullmessage       = $body;
-    $eventdata->fullmessageformat = FORMAT_PLAIN;
-    $eventdata->fullmessagehtml   = '';
-    $eventdata->smallmessage      = '';
-    message_send($eventdata);
-}
-
-
-function notify_admins($user,$subject,$a) {
-
-    $admins = get_admins();
-
-    $body = get_string('virusfoundlateradmin','moodle',$a);
-    foreach ($admins as $admin) {
-        $eventdata = new stdClass();
-        $eventdata->modulename        = 'moodle';
-        $eventdata->userfrom          = get_admin();
-        $eventdata->userto            = $admin;
-        $eventdata->subject           = $subject;
-        $eventdata->fullmessage       = $body;
-        $eventdata->fullmessageformat = FORMAT_PLAIN;
-        $eventdata->fullmessagehtml   = '';
-        $eventdata->smallmessage      = '';
-        message_send($eventdata);
-    }
-}
-
-function notify_admins_unknown($file,$a) {
-
-    global $site;
-
-    $admins = get_admins();
-    $subject = get_string('virusfoundsubject','moodle',format_string($site->fullname));
-    $body = get_string('virusfoundlateradminnolog','moodle',$a);
-    foreach ($admins as $admin) {
-        $eventdata = new stdClass();
-        $eventdata->modulename        = 'moodle';
-        $eventdata->userfrom          = get_admin();
-        $eventdata->userto            = $admin;
-        $eventdata->subject           = $subject;
-        $eventdata->fullmessage       = $body;
-        $eventdata->fullmessageformat = FORMAT_PLAIN;
-        $eventdata->fullmessagehtml   = '';
-        $eventdata->smallmessage      = '';
-        message_send($eventdata);
-    }
-}
-
-function validate_line($line) {
-    global $CFG;
-    if (strpos($line,"FOUND") === false) {
-        return false;
-    }
-    $index = strpos($line,":");
-    $file = substr($line,0,$index);
-    if (!(strpos($file,$CFG->dataroot) === false)) {
-        if (!file_exists($file)) {
-            return false;
-        }
-    }
-    else {
-        if ($file{0} == "/") {
-            $file = $CFG->dataroot.$file;
-        }
-        else {
-            $file = $CFG->dataroot."/".$file;
-        }
-        if (!file_exists($file)) {
-            return false;
-        }
-    }
-    // clean up
-    $file = preg_replace('/\.\//','/',$file);
-    $file = preg_replace('/\/\//','/',$file);
-    return $file;
-}
-
-
index 3ba44bb..1588436 100644 (file)
@@ -610,10 +610,10 @@ class core_admin_renderer extends plugin_renderer_base {
         }
 
         $maturitylevel = get_string('maturity' . $maturity, 'admin');
-        return $this->box(
+        return $this->warning(
                     $this->container(get_string('maturitycorewarning', 'admin', $maturitylevel)) .
                     $this->container($this->doc_link('admin/versions', get_string('morehelp'))),
-                'generalbox maturitywarning');
+                'error');
     }
 
     /*
@@ -628,10 +628,8 @@ class core_admin_renderer extends plugin_renderer_base {
             return '';
         }
 
-        return $this->box(
-            $this->container(get_string('testsiteupgradewarning', 'admin', $testsite)),
-            'generalbox testsitewarning'
-        );
+        $warning = (get_string('testsiteupgradewarning', 'admin', $testsite));
+        return $this->warning($warning, 'error');
     }
 
     /**
@@ -663,11 +661,16 @@ class core_admin_renderer extends plugin_renderer_base {
             return ''; // No worries.
         }
 
+        $level = 'warning';
+
+        if ($maturity == MATURITY_ALPHA) {
+            $level = 'error';
+        }
+
         $maturitylevel = get_string('maturity' . $maturity, 'admin');
-        return $this->box(
-                    get_string('maturitycoreinfo', 'admin', $maturitylevel) . ' ' .
-                    $this->doc_link('admin/versions', get_string('morehelp')),
-                'generalbox adminwarning maturityinfo maturity'.$maturity);
+        $warningtext = get_string('maturitycoreinfo', 'admin', $maturitylevel);
+        $warningtext .= ' ' . $this->doc_link('admin/versions', get_string('morehelp'));
+        return $this->warning($warningtext, $level);
     }
 
     /**
@@ -682,7 +685,7 @@ class core_admin_renderer extends plugin_renderer_base {
      */
     protected function available_updates($updates, $fetch) {
 
-        $updateinfo = $this->box_start('generalbox adminwarning availableupdatesinfo');
+        $updateinfo = '';
         $someupdateavailable = false;
         if (is_array($updates)) {
             if (is_array($updates['core'])) {
@@ -719,9 +722,7 @@ class core_admin_renderer extends plugin_renderer_base {
         }
         $updateinfo .= $this->container_end();
 
-        $updateinfo .= $this->box_end();
-
-        return $updateinfo;
+        return $this->warning($updateinfo);
     }
 
     /**
index 20f69b2..ec37e43 100644 (file)
@@ -137,21 +137,6 @@ $temp->add(new admin_setting_configselect('deleteincompleteusers', new lang_stri
                                                                                                                                                                     48 => new lang_string('numdays', '', 2),
                                                                                                                                                                     24 => new lang_string('numdays', '', 1))));
 
-$temp->add(new admin_setting_configcheckbox('logguests', new lang_string('logguests', 'admin'),
-                                            new lang_string('logguests_help', 'admin'), 1));
-$temp->add(new admin_setting_configselect('loglifetime', new lang_string('loglifetime', 'admin'), new lang_string('configloglifetime', 'admin'), 0, array(0 => new lang_string('neverdeletelogs'),
-                                                                                                                                                1000 => new lang_string('numdays', '', 1000),
-                                                                                                                                                365 => new lang_string('numdays', '', 365),
-                                                                                                                                                180 => new lang_string('numdays', '', 180),
-                                                                                                                                                150 => new lang_string('numdays', '', 150),
-                                                                                                                                                120 => new lang_string('numdays', '', 120),
-                                                                                                                                                90 => new lang_string('numdays', '', 90),
-                                                                                                                                                60 => new lang_string('numdays', '', 60),
-                                                                                                                                                35 => new lang_string('numdays', '', 35),
-                                                                                                                                                10 => new lang_string('numdays', '', 10),
-                                                                                                                                                5 => new lang_string('numdays', '', 5),
-                                                                                                                                                2 => new lang_string('numdays', '', 2))));
-
 
 $temp->add(new admin_setting_configcheckbox('disablegradehistory', new lang_string('disablegradehistory', 'grades'),
                                             new lang_string('disablegradehistory_help', 'grades'), 0));
index 5a50bce..2231bab 100644 (file)
@@ -127,6 +127,7 @@ if ($hassiteconfig
                              'msnid' => new lang_string('msnid'),
                              'firstaccess' => new lang_string('firstaccess'),
                              'lastaccess' => new lang_string('lastaccess'),
+                             'lastip' => new lang_string('lastip'),
                              'mycourses' => new lang_string('mycourses'),
                              'groups' => new lang_string('groups'),
                              'suspended' => new lang_string('suspended', 'auth'),
index b5d6096..1b41f65 100644 (file)
@@ -17,7 +17,7 @@ Feature: Display extended course names
   Scenario: Courses list with extended course names
     Given I expand "Site administration" node
     And I click on "Courses" "link" in the "//div[@id='settingsnav']/descendant::li[contains(concat(' ', normalize-space(@class), ' '), ' type_setting ')][contains(., 'Appearance')]" "xpath_element"
-    And I check "Display extended course names"
+    And I set the field "Display extended course names" to "1"
     When I press "Save changes"
     And I am on homepage
     Then I should see "C_shortname Course fullname"
index 4b7f6ef..1b7de06 100644 (file)
@@ -29,7 +29,7 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
 
   @javascript
   Scenario: Filter user accounts by role and cohort
-    When I fill the moodle form with:
+    When I set the following fields to these values:
       | courserole_rl | Student |
       | courserole_ct | any category |
       | courserole | C1 |
@@ -38,7 +38,7 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
     And I should see "User Two"
     And I should see "User Three"
     And I should not see "User Four"
-    And I fill the moodle form with:
+    And I set the following fields to these values:
       | cohort | CH1 |
     And I press "Add filter"
     And I should not see "User One"
@@ -53,14 +53,14 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
 
   @javascript
   Scenario: Filter user accounts by confirm and authentication method
-    When I fill the moodle form with:
+    When I set the following fields to these values:
       | Confirmed | No |
     And I press "Add filter"
     Then I should see "User One"
     And I should not see "User Two"
     And I should not see "User Three"
     And I should see "User Four"
-    And I fill the moodle form with:
+    And I set the following fields to these values:
       | Authentication | manual |
     And I press "Add filter"
     And I should see "User One"
index 5cde0e8..d67085b 100644 (file)
@@ -41,5 +41,5 @@ Feature: Upload users
     And I follow "Maths"
     And I expand "Users" node
     And I follow "Groups"
-    And I select "Section 1 (1)" from "groups"
+    And I set the field "groups" to "Section 1 (1)"
     And the "members" select box should contain "Tom Jones"
index b07e92f..88a1ef7 100644 (file)
@@ -29,6 +29,8 @@ $string['errorcomposer'] = 'Composer dependencies are not installed.';
 $string['errordataroot'] = '$CFG->behat_dataroot is not set or is invalid.';
 $string['errorsetconfig'] = '$CFG->behat_dataroot, $CFG->behat_prefix and $CFG->behat_wwwroot need to be set in config.php.';
 $string['erroruniqueconfig'] = '$CFG->behat_dataroot, $CFG->behat_prefix and $CFG->behat_wwwroot values need to be different than $CFG->dataroot, $CFG->prefix, $CFG->wwwroot, $CFG->phpunit_dataroot and $CFG->phpunit_prefix values.';
+$string['fieldvalueargument'] = 'Field value arguments';
+$string['fieldvalueargument_help'] = 'This argument should be completed by a field value, there are many field types, simple ones like checkboxes, selects or textareas or complex ones like date selectors. You can check <a href="http://docs.moodle.org/dev/Acceptance_testing#Providing_values_to_steps" target="_blank">Field values</a> to see the expected field value depending on the field type you provide.';
 $string['giveninfo'] = 'Given. Processes to set up the environment';
 $string['infoheading'] = 'Info';
 $string['installinfo'] = 'Read {$a} for installation and tests execution info';
index cc5b4ab..0454436 100644 (file)
@@ -84,6 +84,33 @@ class tool_behat_renderer extends plugin_renderer_base {
                 $stepsdefinitions
             );
 
+            $stepsdefinitions = preg_replace_callback('/(FIELD_VALUE_STRING)/',
+                function ($matches) {
+                    global $CFG;
+
+                    // Creating a link to a popup with the help.
+                    $url = new moodle_url(
+                        '/help.php',
+                        array(
+                            'component' => 'tool_behat',
+                            'identifier' => 'fieldvalueargument',
+                            'lang' => current_language()
+                        )
+                    );
+
+                    // Note: this title is displayed only if JS is disabled,
+                    // otherwise the link will have the new ajax tooltip.
+                    $title = get_string('fieldvalueargument', 'tool_behat');
+                    $title = get_string('helpprefix2', '', trim($title, ". \t"));
+
+                    $attributes = array('href' => $url, 'title' => $title,
+                        'aria-haspopup' => 'true', 'target' => '_blank');
+
+                    $output = html_writer::tag('a', 'FIELD_VALUE_STRING', $attributes);
+                    return html_writer::tag('span', $output, array('class' => 'helptooltip'));
+                },
+                $stepsdefinitions
+            );
         }
 
         // Steps definitions.
index 83f0320..4f482dc 100644 (file)
@@ -11,7 +11,7 @@ Feature: Page contents assertions
     And I expand "Users" node
     And I follow "Groups"
     And I press "Create group"
-    And I fill the moodle form with:
+    And I set the following fields to these values:
       | Group name | I'm the name |
       | Group description | I'm the description |
     And I press "Save changes"
index 558c848..59e5339 100644 (file)
@@ -89,11 +89,11 @@ Feature: Set up contextual data for tests
     And I follow "Course 1"
     And I expand "Users" node
     And I follow "Permissions"
-    And I select "Student (1)" from "Advanced role override"
-    Then the "mod/forum:editanypost" field should match "1" value
+    And I set the field "Advanced role override" to "Student (1)"
+    Then "mod/forum:editanypost" capability has "Allow" permission
     And I press "Cancel"
-    And I select "Teacher (1)" from "Advanced role override"
-    And the "mod/forum:replynews" field should match "-1" value
+    And I set the field "Advanced role override" to "Teacher (1)"
+    And "mod/forum:replynews" capability has "Prevent" permission
     And I press "Cancel"
 
   Scenario: Add course enrolments
@@ -111,22 +111,32 @@ Feature: Set up contextual data for tests
     Then I should see "Topic 1"
 
   Scenario: Add role assigns
-    Given the following "users" exists:
+    Given the following "roles" exists:
+      | name                   | shortname | description      | archetype      |
+      | Custom editing teacher | custom1   | My custom role 1 | editingteacher |
+      | Custom student         | custom2   |                  |                |
+    And the following "users" exists:
       | username | firstname | lastname | email |
       | user1 | User | 1 | user1@moodlemoodle.com |
       | user2 | User | 2 | user2@moodlemoodle.com |
       | user3 | User | 3 | user3@moodlemoodle.com |
+      | user4 | User | 4 | user4@moodlemoodle.com |
+      | user5 | User | 5 | user5@moodlemoodle.com |
     And the following "categories" exists:
       | name | category | idnumber |
       | Cat 1 | 0 | CAT1 |
     And the following "courses" exists:
       | fullname | shortname | category |
       | Course 1 | C1 | CAT1 |
+    And the following "course enrolments" exists:
+      | user | course | role |
+      | user4 | C1 | custom1 |
     And the following "role assigns" exists:
       | user  | role           | contextlevel | reference |
       | user1 | manager        | System       |           |
       | user2 | editingteacher | Category     | CAT1      |
       | user3 | editingteacher | Course       | C1        |
+      | user5 | custom2        | System       |           |
     When I log in as "user1"
     Then I should see "Front page settings"
     And I log out
@@ -137,6 +147,16 @@ Feature: Set up contextual data for tests
     And I log in as "user3"
     And I follow "Course 1"
     And I should see "Turn editing on"
+    And I log out
+    And I log in as "user4"
+    And I follow "Course 1"
+    And I should see "Turn editing on"
+    And I log out
+    And I log in as "user5"
+    And I should see "You are logged in as"
+    And I follow "Course 1"
+    And I should see "You can not enrol yourself in this course."
+
 
   Scenario: Add modules
     Given the following "courses" exists:
@@ -229,7 +249,7 @@ Feature: Set up contextual data for tests
     And I follow "Groups"
     Then the "groups" select box should contain "Group 1 (1)"
     And the "groups" select box should contain "Group 2 (1)"
-    And I select "Group 1 (1)" from "groups"
+    And I set the field "groups" to "Group 1 (1)"
     And the "members" select box should contain "Student 1"
-    And I select "Group 2 (1)" from "groups"
+    And I set the field "groups" to "Group 2 (1)"
     And the "members" select box should contain "Student 2"
index b16b0e0..c2111ec 100644 (file)
@@ -25,10 +25,10 @@ Feature: Edit capabilities
       | moodle/grade:managesharedforms | Prevent |
       | moodle/course:request | Prohibit |
     When I follow "Edit Teacher role"
-    Then the "block/mnet_hosts:myaddinstance" field should match "1" value
-    And the "moodle/community:add" field should match "0" value
-    And the "moodle/grade:managesharedforms" field should match "-1" value
-    And the "moodle/course:request" field should match "-1000" value
+    Then "block/mnet_hosts:myaddinstance" capability has "Allow" permission
+    And "moodle/community:add" capability has "Not set" permission
+    And "moodle/grade:managesharedforms" capability has "Prevent" permission
+    And "moodle/course:request" capability has "Prohibit" permission
 
   @javascript
   Scenario: Course capabilities overrides
@@ -40,10 +40,10 @@ Feature: Edit capabilities
       | mod/forum:deleteanypost | Prohibit |
       | mod/forum:editanypost | Prevent |
       | mod/forum:addquestion | Allow |
-    When I select "Student (3)" from "Advanced role override"
-    Then the "mod/forum:deleteanypost" field should match "-1000" value
-    And the "mod/forum:editanypost" field should match "-1" value
-    And the "mod/forum:addquestion" field should match "1" value
+    When I set the field "Advanced role override" to "Student (3)"
+    Then "mod/forum:deleteanypost" capability has "Prohibit" permission
+    And "mod/forum:editanypost" capability has "Prevent" permission
+    And "mod/forum:addquestion" capability has "Allow" permission
 
   @javascript
   Scenario: Module capabilities overrides
@@ -59,7 +59,7 @@ Feature: Edit capabilities
       | mod/forum:deleteanypost | Prohibit |
       | mod/forum:editanypost | Prevent |
       | mod/forum:addquestion | Allow |
-    When I select "Student (3)" from "Advanced role override"
-    Then the "mod/forum:deleteanypost" field should match "-1000" value
-    And the "mod/forum:editanypost" field should match "-1" value
-    And the "mod/forum:addquestion" field should match "1" value
+    When I set the field "Advanced role override" to "Student (3)"
+    Then "mod/forum:deleteanypost" capability has "Prohibit" permission
+    And "mod/forum:editanypost" capability has "Prevent" permission
+    And "mod/forum:addquestion" capability has "Allow" permission
diff --git a/admin/tool/behat/tests/behat/get_and_set_fields.feature b/admin/tool/behat/tests/behat/get_and_set_fields.feature
new file mode 100644 (file)
index 0000000..3857653
--- /dev/null
@@ -0,0 +1,173 @@
+@tool_behat
+Feature: Verify that all form fields values can be get and set
+  In order to use behat steps definitions
+  As a test writer
+  I need to verify it all works in real moodle forms
+
+  Background:
+    Given the following "courses" exists:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "users" exists:
+      | username | email | firstname | lastname |
+      | student1 | s1@asd.com | Student | 1 |
+      | student2 | s2@asd.com | Student | 2 |
+      | student3 | s3@asd.com | Student | 3 |
+    And the following "course enrolments" exists:
+      | user | course | role |
+      | student1 | C1 | student |
+      | student2 | C1 | student |
+      | student3 | C1 | student |
+      | admin | C1 | editingteacher |
+    And the following "groups" exists:
+      | name | description | course | idnumber |
+      | Group 1 | G1 description | C1 | G1 |
+      | Group 2 | G1 description | C1 | G2 |
+    And the following "group members" exists:
+      | user | group |
+      | student1 | G1 |
+      | student2 | G1 |
+      | student2 | G2 |
+      | student3 | G2 |
+    And the following "activities" exists:
+      | activity | course | idnumber | name | intro | firstpagetitle | wikimode | visible |
+      | wiki | C1 | wiki1 | Test this one | Test this one | Test this one | collaborative | 0 |
+    And I log in as "admin"
+    And I expand "Site administration" node
+    And I expand "Appearance" node
+    And I follow "Manage tags"
+    # Select (multi-select) - We will check "I set the field...".
+    And I set the field "otagsadd" to "OT1, OT2, OT3, OT4, OT5"
+    And I press "Add official tags"
+    And I am on homepage
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I follow "Test this one"
+    And I press "Create page"
+    # Select (multi-select) - Checking "the select box should contain".
+    And the "tags[officialtags][]" select box should contain "OT1"
+    And the "tags[officialtags][]" select box should contain "OT2"
+    And the "tags[officialtags][]" select box should contain "OT3"
+    And the "tags[officialtags][]" select box should contain "OT4"
+    And the "tags[officialtags][]" select box should contain "OT5"
+    And the "tags[officialtags][]" select box should contain "OT1, OT2, OT3, OT4, OT5"
+    And the "tags[officialtags][]" select box should contain "OT5, OT4, OT3, OT2, OT1"
+    And the "tags[officialtags][]" select box should not contain "OT6"
+    And the "tags[officialtags][]" select box should not contain "OT7"
+    And the "tags[officialtags][]" select box should not contain "OT6, OT7"
+    # Text (textarea & editor) & Select (multi-select) - Checking "I set the following fields to these values".
+    When I set the following fields to these values:
+      | HTML format | Student page contents to be tagged |
+      | tags[officialtags][] | OT1, OT3, OT5 |
+    And I press "Save"
+    Then I should see "Student page contents to be tagged" in the "region-main" "region"
+    And I should see "OT1" in the ".wiki-tags" "css_element"
+    And I should see "OT3" in the ".wiki-tags" "css_element"
+    And I should see "OT5" in the ".wiki-tags" "css_element"
+    And I should not see "OT2" in the ".wiki-tags" "css_element"
+    And I should not see "OT4" in the ".wiki-tags" "css_element"
+    And I follow "Edit"
+    # Select (multi-select) - Checking "I set the field".
+    And I set the field "tags[officialtags][]" to "OT2, OT4"
+    And I press "Save"
+    And I should see "OT2" in the ".wiki-tags" "css_element"
+    And I should see "OT4" in the ".wiki-tags" "css_element"
+    And I should not see "OT1" in the ".wiki-tags" "css_element"
+    And I should not see "OT3" in the ".wiki-tags" "css_element"
+    And I should not see "OT5" in the ".wiki-tags" "css_element"
+    And I follow "Edit"
+    # Select (multi-select) - Checking "the field matches value" and "the field does not match value".
+    And the field "tags[officialtags][]" matches value "OT2, OT4"
+    And the field "tags[officialtags][]" does not match value "OT4"
+    And the field "tags[officialtags][]" does not match value "OT2"
+    And the field "tags[officialtags][]" does not match value "OT1, OT3, OT5"
+    And I press "Cancel"
+    And I follow "Edit settings"
+    And I expand all fieldsets
+    # Checkbox - Checking "I set the field".
+    And I set the field "Display description on course page" to "1"
+    # Checkbox - Checking "I set the following fields to these values:".
+    And I set the following fields to these values:
+      | Force format | 1 |
+    # Checkbox - Checking "the field matches value" and "the field does not match value".
+    And the field "Display description on course page" matches value "1"
+    And the field "Display description on course page" does not match value ""
+    And I press "Save and return to course"
+    And I should see "Test this one"
+    And I follow "Test this one"
+    And I follow "Edit settings"
+    # Checkbox - Checking "the field matches value" and "the following fields match these values".
+    And the following fields match these values:
+      | Display description on course page | 1 |
+      | Default format | HTML |
+      | Wiki name | Test this one |
+    And the field "Force format" matches value "1"
+    # Select (simple) - Checking "I set the following fields to these values:".
+    And I set the following fields to these values:
+      | Default format | NWiki |
+      | Display description on course page | |
+    # Checkbox - Checking "I set the field" to uncheck.
+    And I set the field "Force format" to ""
+    # Select (simple) - Checking "I set the field".
+    And I set the field "Group mode" to "Separate groups"
+    And I press "Save and display"
+    And I follow "Edit settings"
+    And the following fields match these values:
+      | Default format | NWiki |
+      | Group mode | Separate groups |
+      | Display description on course page | |
+      | Force format | |
+    # All fields - Checking "the following fields do not match these values".
+    And the following fields do not match these values:
+      | Wiki name | Test this one baby |
+      | Default format | HTML |
+      | Force format | 1 |
+    And I press "Cancel"
+    And I follow "Course 1"
+    # Radio - Checking "I set the field" and "the field matches value".
+    And I add a "Choice" to section "1" and I fill the form with:
+      | Choice name | Test choice name |
+      | Description | Test choice description |
+      | Allow choice to be updated | Yes |
+      | Option 1 | one |
+      | Option 2 | two |
+      | Option 3 | three |
+    And I follow "Test choice name"
+    And I set the field "one" to "1"
+    And I press "Save my choice"
+    And the field "one" matches value "1"
+    And the field "two" matches value ""
+
+  Scenario: with JS disabled all form fields getters and setters works as expected
+
+  @javascript
+  Scenario: with JS enabled all form fields getters and setters works as expected
+    Then I follow "Course 1"
+    And I expand "Users" node
+    And I follow "Groups"
+    # Select (multi-select & AJAX) - Checking "I set the field" and "select box should contain".
+    And I set the field "groups" to "Group 2"
+    And the "members" select box should contain "Student 2"
+    And the "members" select box should contain "Student 3"
+    And the "members" select box should not contain "Student 1"
+    And I set the field "groups" to "Group 1"
+    And the "members" select box should contain "Student 1"
+    And the "members" select box should contain "Student 2"
+    And the "members" select box should not contain "Student 3"
+    # Checkbox (AJAX) - Checking "I set the field" and "I set the following fields to these values".
+    And I follow "Course 1"
+    And I add a "Lesson" to section "1"
+    And I set the following fields to these values:
+      | Name | Test lesson |
+      | available[enabled] | 1 |
+    And I set the field "deadline[enabled]" to "1"
+    # Checkbox (AJAX) - Checking "the field matches value" before saving.
+    And the field "available[enabled]" matches value "1"
+    And the "available[day]" "field" should be enabled
+    And the field "deadline[enabled]" matches value "1"
+    And I press "Save and display"
+    And I follow "Edit settings"
+    And the field "available[enabled]" matches value "1"
+    And the "available[day]" "field" should be enabled
+    And the field "deadline[enabled]" matches value "1"
+    And I press "Cancel"
index 3fc9ce8..8061f4e 100644 (file)
@@ -18,14 +18,14 @@ Feature: List the system steps definitions
 
   @javascript
   Scenario: Filtering by type
-    Given I select "Then. Checkings to ensure the outcomes are the expected ones" from "Type"
+    Given I set the field "Type" to "Then. Checkings to ensure the outcomes are the expected ones"
     When I press "Filter"
     Then I should see "Checks, that page contains specified text."
     And I should not see "Opens Moodle homepage."
 
   @javascript
   Scenario: Filtering by keyword
-    Given I fill in "Contains" with "homepage"
+    Given I set the field "Contains" to "homepage"
     When I press "Filter"
     Then I should see "Opens Moodle homepage."
 
index 664bbd6..ce44fad 100644 (file)
@@ -9,14 +9,14 @@ Feature: Forms manipulation
     Given I log in as "admin"
     And I follow "Admin User"
     And I follow "Edit profile"
-    When I fill in "First name" with "Field value"
-    And I select "Plain text area" from "Text editor"
-    And I check "Unmask"
-    Then the "First name" field should match "Field value" value
+    When I set the field "First name" to "Field value"
+    And I set the field "Text editor" to "Plain text area"
+    And I set the field "Unmask" to "1"
+    Then the field "First name" matches value "Field value"
     And the "Text editor" select box should contain "Plain text area"
-    And the "Unmask" checkbox should be checked
-    And I uncheck "Unmask"
-    And the "Unmask" checkbox should not be checked
+    And the field "Unmask" matches value "1"
+    And I set the field "Unmask" to ""
+    And the field "Unmask" matches value ""
     And I press "Update profile"
 
   @javascript
index 8ced5fd..c67d6cd 100644 (file)
@@ -14,47 +14,47 @@ Feature: Transform steps arguments
     And I follow "Edit profile"
 
   Scenario: Use nasty strings on steps arguments
-    When I fill in "Surname" with "$NASTYSTRING1"
-    And I fill in "Description" with "$NASTYSTRING2"
-    And I fill in "City/town" with "$NASTYSTRING3"
+    When I set the field "Surname" to "$NASTYSTRING1"
+    And I set the field "Description" to "$NASTYSTRING2"
+    And I set the field "City/town" to "$NASTYSTRING3"
     And I press "Update profile"
     And I follow "Edit profile"
     Then I should not see "NASTYSTRING"
-    And the "Surname" field should match "$NASTYSTRING1" value
-    And the "City/town" field should match "$NASTYSTRING3" value
+    And the field "Surname" matches value "$NASTYSTRING1"
+    And the field "City/town" matches value "$NASTYSTRING3"
 
   Scenario: Use nasty strings on table nodes
-    When I fill the moodle form with:
+    When I set the following fields to these values:
       | Surname | $NASTYSTRING1 |
       | Description | $NASTYSTRING2 |
       | City/town | $NASTYSTRING3 |
     And I press "Update profile"
     And I follow "Edit profile"
     Then I should not see "NASTYSTRING"
-    And the "Surname" field should match "$NASTYSTRING1" value
-    And the "City/town" field should match "$NASTYSTRING3" value
+    And the field "Surname" matches value "$NASTYSTRING1"
+    And the field "City/town" matches value "$NASTYSTRING3"
 
   Scenario: Use double quotes
-    When I fill the moodle form with:
+    When I set the following fields to these values:
       | First name | va"lue1 |
       | Description | va\"lue2 |
-    And I fill in "City/town" with "va\"lue3"
+    And I set the field "City/town" to "va\"lue3"
     And I press "Update profile"
     And I follow "Edit profile"
     Then I should not see "NASTYSTRING"
-    And the "First name" field should match "va\"lue1" value
-    And the "Description" field should match "va\\"lue2" value
-    And the "City/town" field should match "va\"lue3" value
+    And the field "First name" matches value "va\"lue1"
+    And the field "Description" matches value "va\\"lue2"
+    And the field "City/town" matches value "va\"lue3"
 
   @javascript
   Scenario: Nasty strings with other contents
-    When I fill in "First name" with "My Firstname $NASTYSTRING1"
-    And I fill the moodle form with:
+    When I set the field "First name" to "My Firstname $NASTYSTRING1"
+    And I set the following fields to these values:
       | Surname | My Surname $NASTYSTRING2 |
     And I press "Update profile"
     And I follow "Edit profile"
     Then I should not see "NASTYSTRING"
     And I should see "My Firstname"
     And I should see "My Surname"
-    And the "First name" field should match "My Firstname $NASTYSTRING1" value
-    And the "Surname" field should match "My Surname $NASTYSTRING2" value
+    And the field "First name" matches value "My Firstname $NASTYSTRING1"
+    And the field "Surname" matches value "My Surname $NASTYSTRING2"
index e677b90..525aa94 100644 (file)
@@ -1,6 +1,8 @@
-This files describes API changes in the assign code.
+This files describes API changes in the tool_behat code.
 
 === 2.7 ===
-
+* Constants behat_base::cap_allow, behat_base::cap_prevent and
+  behat_base::cap_prohibit have been removed in favour of the
+  lang/en/role.php language strings 'allow', 'prevent' and 'prohibit'.
 * @_only_local tag used in .feature files replaced by @_file_upload tag
 * @_alerts tag used in .feature files replaced by @_alert tag
diff --git a/admin/tool/log/classes/helper/buffered_writer.php b/admin/tool/log/classes/helper/buffered_writer.php
new file mode 100644 (file)
index 0000000..d341452
--- /dev/null
@@ -0,0 +1,106 @@
+<?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/>.
+
+/**
+ * Helper trait buffered_writer
+ *
+ * @package    tool_log
+ * @copyright  2014 onwards Ankit Agarwal
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace tool_log\helper;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Helper trait buffered_writer. Adds buffer support for the store.
+ * \tool_log\helper\store must be included before using this trait.
+ *
+ * @package    tool_log
+ * @copyright  2014 onwards Ankit Agarwal
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+trait buffered_writer {
+
+    /** @var array $buffer buffer of events. */
+    protected $buffer = array();
+
+    /** @var array $buffer buffer size of events. */
+    protected $buffersize;
+
+    /** @var int $count Counter. */
+    protected $count = 0;
+
+    /**
+     * Write event in the store with buffering. Method insert_events() must be
+     * defined.
+     *
+     * @param \core\event\base $event
+     *
+     * @return void
+     */
+    public function write(\core\event\base $event) {
+        $this->buffer[] = $event;
+        $this->count++;
+
+        if (!isset($this->buffersize)) {
+            $this->buffersize = $this->get_config('buffersize', 50);
+        }
+
+        if ($this->count >= $this->buffersize) {
+            $this->flush();
+        }
+    }
+
+    /**
+     * Flush event buffer.
+     */
+    public function flush() {
+        if ($this->count == 0) {
+            return;
+        }
+        $events = $this->buffer;
+        $this->count = 0;
+        $this->buffer = array();
+        $this->insert_events($events);
+    }
+
+    /**
+     * Bulk write a given array of events to the backend. Stores must implement this.
+     *
+     * @param array $events An array of events to write.
+     */
+    abstract protected function insert_events($events);
+
+    /**
+     * Get a config value for the store.
+     *
+     * @param string $name Config name
+     * @param mixed $default default value
+     *
+     * @return mixed config value if set, else the default value.
+     */
+    abstract protected function get_config($name, $default = null);
+
+    /**
+     * Push any remaining events to the database. Insert_events() must be
+     * defined. override in stores if the store doesn't support buffering.
+     *
+     */
+    public function dispose() {
+        $this->flush();
+    }
+}
diff --git a/admin/tool/log/classes/helper/reader.php b/admin/tool/log/classes/helper/reader.php
new file mode 100644 (file)
index 0000000..036f874
--- /dev/null
@@ -0,0 +1,75 @@
+<?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/>.
+
+/**
+ * Reader helper trait.
+ *
+ * @package    tool_log
+ * @copyright  2014 onwards Ankit Agarwal
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace tool_log\helper;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Reader helper trait.
+ * \tool_log\helper\store must be included before using this trait.
+ *
+ * @package    tool_log
+ * @copyright  2014 onwards Ankit Agarwal
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ *
+ * @property string $component Frankenstyle plugin name initialised in store trait.
+ * @property string $store short plugin name initialised in store trait.
+ */
+trait reader {
+    /**
+     * Default get name api.
+     *
+     * @return string name of the store.
+     */
+    public function get_name() {
+        if (get_string_manager()->string_exists('pluginname', $this->component)) {
+            return get_string('pluginname', $this->component);
+        }
+        return $this->store;
+    }
+
+    /**
+     * Default get description method.
+     *
+     * @return string description of the store.
+     */
+    public function get_description() {
+        if (get_string_manager()->string_exists('pluginname_desc', $this->component)) {
+            return get_string('pluginname_desc', $this->component);
+        }
+        return $this->store;
+    }
+
+    /**
+     * If the current user can access current store or not.
+     *
+     * @param \context $context
+     *
+     * @return bool
+     */
+    public function can_access(\context $context) {
+        return has_capability('logstore/' . $this->store . ':read', $context);
+    }
+}
diff --git a/admin/tool/log/classes/helper/store.php b/admin/tool/log/classes/helper/store.php
new file mode 100644 (file)
index 0000000..f3bf4bb
--- /dev/null
@@ -0,0 +1,79 @@
+<?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/>.
+
+/**
+ * Helper trait store.
+ *
+ * @package    tool_log
+ * @copyright  2014 onwards Ankit Agarwal
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace tool_log\helper;
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Helper trait store. Adds some helper methods for stores.
+ *
+ * @package    tool_log
+ * @copyright  2014 onwards Ankit Agarwal
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+trait store {
+
+    /** @var \tool_log\log\manager $manager manager instance. */
+    protected $manager;
+
+    /** @var string $component Frankenstyle store name. */
+    protected $component;
+
+    /** @var string $store name of the store. */
+    protected $store;
+
+
+    /**
+     * Setup store specific variables.
+     *
+     * @param \tool_log\log\manager $manager manager instance.
+     */
+    protected function helper_setup(\tool_log\log\manager $manager) {
+        $this->manager = $manager;
+        $called = get_called_class();
+        $parts = explode('\\', $called);
+        if (!isset($parts[0]) || strpos($parts[0], 'logstore_') !== 0) {
+            throw new \coding_exception("Store $called doesn't define classes in correct namespaces.");
+        }
+        $this->component = $parts[0];
+        $this->store = str_replace('logstore_', '', $this->store);
+    }
+
+    /**
+     * Api to get plugin config
+     *
+     * @param string $name name of the config.
+     * @param null|mixed $default default value to return.
+     *
+     * @return mixed|null return config value.
+     */
+    protected function get_config($name, $default = null) {
+        $value = get_config($this->component, $name);
+        if ($value !== false) {
+            return $value;
+        }
+        return $default;
+    }
+
+}
diff --git a/admin/tool/log/classes/log/manager.php b/admin/tool/log/classes/log/manager.php
new file mode 100644 (file)
index 0000000..894fe94
--- /dev/null
@@ -0,0 +1,168 @@
+<?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/>.
+
+/**
+ * Log store manager.
+ *
+ * @package    tool_log
+ * @copyright  2013 Petr Skoda {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace tool_log\log;
+
+defined('MOODLE_INTERNAL') || die();
+
+class manager implements \core\log\manager {
+    /** @var \core\log\reader[] $readers list of initialised log readers */
+    protected $readers;
+
+    /** @var \tool_log\log\writer[] $writers list of initialised log writers */
+    protected $writers;
+
+    /** @var \tool_log\log\store[] $stores list of all enabled stores */
+    protected $stores;
+
+    /**
+     * Delayed initialisation of singleton.
+     */
+    protected function init() {
+        if (isset($this->stores)) {
+            // Do not bother checking readers and writers here
+            // because everything is init here.
+            return;
+        }
+        $this->stores = array();
+        $this->readers = array();
+        $this->writers = array();
+
+        // Register shutdown handler - this may be useful for buffering, file handle closing, etc.
+        \core_shutdown_manager::register_function(array($this, 'dispose'));
+
+        $plugins = get_config('tool_log', 'enabled_stores');
+        if (empty($plugins)) {
+            return;
+        }
+
+        $plugins = explode(',', $plugins);
+        foreach ($plugins as $plugin) {
+            $classname = "\\$plugin\\log\\store";
+            if (class_exists($classname)) {
+                $store = new $classname($this);
+                $this->stores[$plugin] = $store;
+                if ($store instanceof \tool_log\log\writer) {
+                    $this->writers[$plugin] = $store;
+                }
+                if ($store instanceof \core\log\reader) {
+                    $this->readers[$plugin] = $store;
+                }
+            }
+        }
+    }
+
+    /**
+     * Called from the observer only.
+     *
+     * @param \core\event\base $event
+     */
+    public function process(\core\event\base $event) {
+        $this->init();
+        foreach ($this->writers as $plugin => $writer) {
+            try {
+                $writer->write($event, $this);
+            } catch (\Exception $e) {
+                debugging('Exception detected when logging event ' . $event->eventname . ' in ' . $plugin . ': ' .
+                    $e->getMessage(), DEBUG_NORMAL, $e->getTrace());
+            }
+        }
+    }
+
+    /**
+     * Returns list of available log readers.
+     *
+     * This way the reports find out available sources of data.
+     *
+     * @param string $interface Returned stores must implement this interface.
+     *
+     * @return \core\log\reader[] list of available log data readers
+     */
+    public function get_readers($interface = null) {
+        $this->init();
+        $return = array();
+        foreach ($this->readers as $plugin => $reader) {
+            if (empty($interface) || ($reader instanceof $interface)) {
+                $return[$plugin] = $reader;
+            }
+        }
+        return $return;
+    }
+
+    /**
+     * Intended for store management, do not use from reports.
+     *
+     * @return store[] Returns list of available store plugins.
+     */
+    public static function get_store_plugins() {
+        return \core_component::get_plugin_list_with_class('logstore', 'log\store');
+    }
+
+    /**
+     * Usually called automatically from shutdown manager,
+     * this allows us to implement buffering of write operations.
+     */
+    public function dispose() {
+        if ($this->stores) {
+            foreach ($this->stores as $store) {
+                $store->dispose();
+            }
+        }
+        $this->stores = null;
+        $this->readers = null;
+        $this->writers = null;
+    }
+
+    /**
+     * Execute cron actions.
+     */
+    public function cron() {
+        $this->init();
+        foreach ($this->stores as $store) {
+            $store->cron();
+        }
+    }
+
+    /**
+     * Legacy add_to_log() redirection.
+     *
+     * To be used only from deprecated add_to_log() function and event trigger() method.
+     *
+     * NOTE: this is hardcoded to legacy log store plugin, hopefully we can get rid of it soon.
+     *
+     * @param int $courseid The course id
+     * @param string $module The module name  e.g. forum, journal, resource, course, user etc
+     * @param string $action 'view', 'update', 'add' or 'delete', possibly followed by another word to clarify
+     * @param string $url The file and parameters used to see the results of the action
+     * @param string $info Additional description information
+     * @param int $cm The course_module->id if there is one
+     * @param int|\stdClass $user If log regards $user other than $USER
+     */
+    public function legacy_add_to_log($courseid, $module, $action, $url = '', $info = '', $cm = 0, $user = 0) {
+        $this->init();
+        if (isset($this->stores['logstore_legacy'])) {
+            $this->stores['logstore_legacy']->legacy_add_to_log($courseid, $module, $action, $url, $info, $cm, $user);
+        }
+    }
+}
diff --git a/admin/tool/log/classes/log/observer.php b/admin/tool/log/classes/log/observer.php
new file mode 100644 (file)
index 0000000..0728937
--- /dev/null
@@ -0,0 +1,43 @@
+<?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/>.
+
+/**
+ * Event observer.
+ *
+ * @package    tool_log
+ * @copyright  2013 Petr Skoda {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace tool_log\log;
+
+defined('MOODLE_INTERNAL') || die();
+
+class observer {
+    /**
+     * Redirect all events to this log manager, but only if this
+     * log manager is actually used.
+     *
+     * @param \core\event\base $event
+     */
+    public static function store(\core\event\base $event) {
+        $logmanager = get_log_manager();
+        if (get_class($logmanager) === 'tool_log\log\manager') {
+            /** @var \tool_log\log\manager $logmanager */
+            $logmanager->process($event);
+        }
+    }
+}
diff --git a/admin/tool/log/classes/log/store.php b/admin/tool/log/classes/log/store.php
new file mode 100644 (file)
index 0000000..1e40265
--- /dev/null
@@ -0,0 +1,49 @@
+<?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/>.
+
+/**
+ * Log store interface.
+ *
+ * @package    tool_log
+ * @copyright  2013 Petr Skoda {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace tool_log\log;
+
+defined('MOODLE_INTERNAL') || die();
+
+interface store {
+    /**
+     * Create new instance of store,
+     * the calling code must make sure only one instance exists.
+     *
+     * @param manager $manager
+     */
+    public function __construct(\tool_log\log\manager $manager);
+
+    /**
+     * Notify store no more events are going to be written/read from it.
+     * @return void
+     */
+    public function dispose();
+
+    /**
+     * Execute cron actions.
+     * @return void
+     */
+    public function cron();
+}
similarity index 63%
rename from admin/tool/qeupgradehelper/settings.php
rename to admin/tool/log/classes/log/writer.php
index 8e88a01..138dcc4 100644 (file)
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * Adds this plugin to the admin menu.
+ * Log store writer interface.
  *
- * @package    tool
- * @subpackage qeupgradehelper
- * @copyright  2011 The Open University
+ * @package    tool_log
+ * @copyright  2013 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-defined('MOODLE_INTERNAL') || die;
+namespace tool_log\log;
 
-if ($hassiteconfig) { // needs this condition or there is error on login page
-    $ADMIN->add('root', new admin_externalpage('qeupgradehelper',
-            get_string('pluginname', 'tool_qeupgradehelper'),
-            new moodle_url('/admin/tool/qeupgradehelper/index.php')));
+defined('MOODLE_INTERNAL') || die();
+
+interface writer extends store {
+    /**
+     * Write one event to the store.
+     *
+     * @param \core\event\base $event
+     * @return void
+     */
+    public function write(\core\event\base $event);
 }
diff --git a/admin/tool/log/classes/plugininfo/logstore.php b/admin/tool/log/classes/plugininfo/logstore.php
new file mode 100644 (file)
index 0000000..d7e19db
--- /dev/null
@@ -0,0 +1,89 @@
+<?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/>.
+
+/**
+ * Subplugin info class.
+ *
+ * @package   tool_log
+ * @copyright 2013 Petr Skoda {@link http://skodak.org}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace tool_log\plugininfo;
+
+use core\plugininfo\base, moodle_url, part_of_admin_tree, admin_settingpage;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Plugin info class for logging store plugins.
+ */
+class logstore extends base {
+
+    public function is_enabled() {
+        $enabled = get_config('tool_log', 'enabled_stores');
+        if (!$enabled) {
+            return false;
+        }
+
+        $enabled = array_flip(explode(',', $enabled));
+        return isset($enabled['logstore_' . $this->name]);
+    }
+
+    public function get_settings_section_name() {
+        return 'logsetting' . $this->name;
+    }
+
+    public function load_settings(part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) {
+        global $CFG, $USER, $DB, $OUTPUT, $PAGE; // In case settings.php wants to refer to them.
+        $ADMIN = $adminroot; // May be used in settings.php.
+        $section = $this->get_settings_section_name();
+
+        if (!$this->is_installed_and_upgraded()) {
+            return;
+        }
+
+        if (!$hassiteconfig or !file_exists($this->full_path('settings.php'))) {
+            return;
+        }
+
+        $settings = new admin_settingpage($section, $this->displayname, 'moodle/site:config', $this->is_enabled() === false);
+        include($this->full_path('settings.php'));
+
+        if ($settings) {
+            $ADMIN->add($parentnodename, $settings);
+        }
+    }
+
+    public static function get_manage_url() {
+        return new moodle_url('/admin/settings.php', array('section' => 'managelogging'));
+    }
+
+    public function is_uninstall_allowed() {
+        return true;
+    }
+
+    public function uninstall_cleanup() {
+        $enabled = get_config('tool_log', 'enabled_stores');
+        if ($enabled) {
+            $enabled = array_flip(explode(',', $enabled));
+            unset($enabled['logstore_' . $this->name]);
+            $enabled = array_flip($enabled);
+            set_config('enabled_stores', implode(',', $enabled), 'tool_log');
+        }
+
+        parent::uninstall_cleanup();
+    }
+}
diff --git a/admin/tool/log/classes/setting_managestores.php b/admin/tool/log/classes/setting_managestores.php
new file mode 100644 (file)
index 0000000..bb82a82
--- /dev/null
@@ -0,0 +1,233 @@
+<?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/>.
+
+/**
+ * Store management setting.
+ *
+ * @package    tool_log
+ * @copyright  2013 Petr Skoda {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once("$CFG->libdir/adminlib.php");
+
+class tool_log_setting_managestores extends admin_setting {
+    /**
+     * Calls parent::__construct with specific arguments
+     */
+    public function __construct() {
+        $this->nosave = true;
+        parent::__construct('tool_log_manageui', get_string('managelogging', 'tool_log'), '', '');
+    }
+
+    /**
+     * Always returns true, does nothing.
+     *
+     * @return true
+     */
+    public function get_setting() {
+        return true;
+    }
+
+    /**
+     * Always returns true, does nothing.
+     *
+     * @return true
+     */
+    public function get_defaultsetting() {
+        return true;
+    }
+
+    /**
+     * Always returns '', does not write anything.
+     *
+     * @param mixed $data ignored
+     * @return string Always returns ''
+     */
+    public function write_setting($data) {
+        // Do not write any setting.
+        return '';
+    }
+
+    /**
+     * Checks if $query is one of the available log plugins.
+     *
+     * @param string $query The string to search for
+     * @return bool Returns true if found, false if not
+     */
+    public function is_related($query) {
+        if (parent::is_related($query)) {
+            return true;
+        }
+
+        $query = core_text::strtolower($query);
+        $plugins = \tool_log\log\manager::get_store_plugins();
+        foreach ($plugins as $plugin => $fulldir) {
+            if (strpos(core_text::strtolower($plugin), $query) !== false) {
+                return true;
+            }
+            $localised = get_string('pluginname', $plugin);
+            if (strpos(core_text::strtolower($localised), $query) !== false) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Builds the XHTML to display the control.
+     *
+     * @param string $data Unused
+     * @param string $query
+     * @return string
+     */
+    public function output_html($data, $query = '') {
+        global $OUTPUT, $PAGE;
+
+        // Display strings.
+        $strup = get_string('up');
+        $strdown = get_string('down');
+        $strsettings = get_string('settings');
+        $strenable = get_string('enable');
+        $strdisable = get_string('disable');
+        $struninstall = get_string('uninstallplugin', 'core_admin');
+        $strversion = get_string('version');
+
+        $pluginmanager = core_plugin_manager::instance();
+
+        $available = \tool_log\log\manager::get_store_plugins();
+        $enabled = get_config('tool_log', 'enabled_stores');
+        if (!$enabled) {
+            $enabled = array();
+        } else {
+            $enabled = array_flip(explode(',', $enabled));
+        }
+
+        $allstores = array();
+        foreach ($enabled as $key => $store) {
+            $allstores[$key] = true;
+            $enabled[$key] = true;
+        }
+        foreach ($available as $key => $store) {
+            $allstores[$key] = true;
+            $available[$key] = true;
+        }
+
+        $return = $OUTPUT->heading(get_string('actlogshdr', 'tool_log'), 3, 'main', true);
+        $return .= $OUTPUT->box_start('generalbox loggingui');
+
+        $table = new html_table();
+        $table->head = array(get_string('name'), $strversion, $strenable, $strup . '/' . $strdown, $strsettings, $struninstall);
+        $table->colclasses = array('leftalign', 'centeralign', 'centeralign', 'centeralign', 'centeralign', 'centeralign');
+        $table->id = 'logstoreplugins';
+        $table->attributes['class'] = 'admintable generaltable';
+        $table->data = array();
+
+        // Iterate through store plugins and add to the display table.
+        $updowncount = 1;
+        $storecount = count($enabled);
+        $url = new moodle_url('/admin/tool/log/stores.php', array('sesskey' => sesskey()));
+        $printed = array();
+        foreach ($allstores as $store => $unused) {
+            $plugininfo = $pluginmanager->get_plugin_info($store);
+            $version = get_config($store, 'version');
+            if ($version === false) {
+                $version = '';
+            }
+
+            if (get_string_manager()->string_exists('pluginname', $store)) {
+                $name = get_string('pluginname', $store);
+            } else {
+                $name = $store;
+            }
+
+            // Hide/show links.
+            if (isset($enabled[$store])) {
+                $aurl = new moodle_url($url, array('action' => 'disable', 'store' => $store));
+                $hideshow = "<a href=\"$aurl\">";
+                $hideshow .= "<img src=\"" . $OUTPUT->pix_url('t/hide') . "\" class=\"iconsmall\" alt=\"$strdisable\" /></a>";
+                $isenabled = true;
+                $displayname = "<span>$name</span>";
+            } else {
+                if (isset($available[$store])) {
+                    $aurl = new moodle_url($url, array('action' => 'enable', 'store' => $store));
+                    $hideshow = "<a href=\"$aurl\">";
+                    $hideshow .= "<img src=\"" . $OUTPUT->pix_url('t/show') . "\" class=\"iconsmall\" alt=\"$strenable\" /></a>";
+                    $isenabled = false;
+                    $displayname = "<span class=\"dimmed_text\">$name</span>";
+                } else {
+                    $hideshow = '';
+                    $isenabled = false;
+                    $displayname = '<span class="notifyproblem">' . $name . '</span>';
+                }
+            }
+            if ($PAGE->theme->resolve_image_location('icon', $store, false)) {
+                $icon = $OUTPUT->pix_icon('icon', '', $store, array('class' => 'icon pluginicon'));
+            } else {
+                $icon = $OUTPUT->pix_icon('spacer', '', 'moodle', array('class' => 'icon pluginicon noicon'));
+            }
+
+            // Up/down link (only if store is enabled).
+            $updown = '';
+            if ($isenabled) {
+                if ($updowncount > 1) {
+                    $aurl = new moodle_url($url, array('action' => 'up', 'store' => $store));
+                    $updown .= "<a href=\"$aurl\">";
+                    $updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"$strup\" class=\"iconsmall\" /></a>&nbsp;";
+                } else {
+                    $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"iconsmall\" alt=\"\" />&nbsp;";
+                }
+                if ($updowncount < $storecount) {
+                    $aurl = new moodle_url($url, array('action' => 'down', 'store' => $store));
+                    $updown .= "<a href=\"$aurl\">";
+                    $updown .= "<img src=\"" . $OUTPUT->pix_url('t/down') . "\" alt=\"$strdown\" class=\"iconsmall\" /></a>";
+                } else {
+                    $updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"iconsmall\" alt=\"\" />";
+                }
+                ++$updowncount;
+            }
+
+            // Add settings link.
+            if (!$version) {
+                $settings = '';
+            } else {
+                if ($surl = $plugininfo->get_settings_url()) {
+                    $settings = html_writer::link($surl, $strsettings);
+                } else {
+                    $settings = '';
+                }
+            }
+
+            // Add uninstall info.
+            $uninstall = '';
+            if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url($store, 'manage')) {
+                $uninstall = html_writer::link($uninstallurl, $struninstall);
+            }
+
+            // Add a row to the table.
+            $table->data[] = array($icon . $displayname, $version, $hideshow, $updown, $settings, $uninstall);
+
+            $printed[$store] = true;
+        }
+
+        $return .= html_writer::table($table);
+        $return .= get_string('configlogplugins', 'tool_log') . '<br />' . get_string('tablenosave', 'admin');
+        $return .= $OUTPUT->box_end();
+        return highlight($query, $return);
+    }
+}
diff --git a/admin/tool/log/db/events.php b/admin/tool/log/db/events.php
new file mode 100644 (file)
index 0000000..660f2f6
--- /dev/null
@@ -0,0 +1,35 @@
+<?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/>.
+
+/**
+ * Event observer.
+ *
+ * @package   tool_log
+ * @category  event
+ * @copyright 2013 Petr Skoda {@link http://skodak.org}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$observers = array(
+    array(
+        'eventname' => '*',
+        'callback'  => '\tool_log\log\observer::store',
+        'internal'  => false, // This means that we get events only after transaction commit.
+        'priority'  => 1000,
+    ),
+);
diff --git a/admin/tool/log/db/install.php b/admin/tool/log/db/install.php
new file mode 100644 (file)
index 0000000..6fccec4
--- /dev/null
@@ -0,0 +1,38 @@
+<?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/>.
+
+/**
+ * Logging support.
+ *
+ * @package    tool_log
+ * @copyright  2013 Petr Skoda {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+function xmldb_tool_log_install() {
+    global $CFG;
+
+    $enabled = array();
+
+    // For now enable only the legacy logging, this keeps 100% BC.
+    if (file_exists("$CFG->dirroot/$CFG->admin/tool/log/store/legacy")) {
+        $enabled[] = 'logstore_legacy';
+    }
+
+    set_config('enabled_stores', implode(',', $enabled), 'tool_log');
+}
diff --git a/admin/tool/log/db/subplugins.php b/admin/tool/log/db/subplugins.php
new file mode 100644 (file)
index 0000000..9d1fe61
--- /dev/null
@@ -0,0 +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/>.
+
+/**
+ * Logging subplugins.
+ *
+ * @package   tool_log
+ * @copyright 2013 Petr Skoda {@link http://skodak.org}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$subplugins = array('logstore' => 'admin/tool/log/store');
diff --git a/admin/tool/log/lang/en/tool_log.php b/admin/tool/log/lang/en/tool_log.php
new file mode 100644 (file)
index 0000000..7301031
--- /dev/null
@@ -0,0 +1,29 @@
+<?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/>.
+
+/**
+ * Store management UI lang strings.
+ *
+ * @package    tool_log
+ * @copyright  2013 Petr Skoda {@link http://skodak.org}
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$string['actlogshdr'] = 'Available log stores';
+$string['configlogplugins'] = 'Please enable all required plugins and arrange then in appropriate order.';
+$string['logging'] = 'Logging';
+$string['managelogging'] = 'Manage log stores';
+$string['pluginname'] = 'Log store manager';
diff --git a/admin/tool/log/lib.php b/admin/tool/log/lib.php
new file mode 100644 (file)
index 0000000..9db2ee3
--- /dev/null
@@ -0,0 +1,37 @@
+<?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