Merge branch 'master_MDL-54575' of git://github.com/danmarsden/moodle
authorDavid Monllao <davidm@moodle.com>
Mon, 7 Nov 2016 05:58:04 +0000 (13:58 +0800)
committerDavid Monllao <davidm@moodle.com>
Mon, 7 Nov 2016 05:58:04 +0000 (13:58 +0800)
508 files changed:
.eslintignore
.stylelintignore
admin/media.php [new file with mode: 0644]
admin/mnet/peer_forms.php
admin/mnet/peers.php
admin/mnet/profilefields.php
admin/mnet/services.php
admin/roles/ajax.php
admin/roles/classes/permissions_table.php
admin/roles/define.php
admin/search.php
admin/settings/appearance.php
admin/settings/plugins.php
admin/settings/server.php
admin/settings/top.php
admin/templates/setting_configpasswordunmask.mustache
admin/templates/settings_search_results.mustache
admin/tool/lp/amd/build/menubar.min.js
admin/tool/lp/amd/src/menubar.js
admin/tool/lp/classes/form/user_evidence.php
admin/tool/lp/lib.php
admin/tool/lp/styles.css
admin/tool/lp/templates/action_selector.mustache
admin/tool/lp/templates/comment_area.mustache
admin/tool/lp/templates/competencies_move_tree.mustache
admin/tool/lp/templates/competencies_tree.mustache
admin/tool/lp/templates/competencies_tree_root.mustache
admin/tool/lp/templates/competency_grader.mustache
admin/tool/lp/templates/competency_path.mustache
admin/tool/lp/templates/competency_picker.mustache
admin/tool/lp/templates/competency_picker_competencyform.mustache
admin/tool/lp/templates/competency_picker_user_plans.mustache
admin/tool/lp/templates/competency_plan_navigation.mustache
admin/tool/lp/templates/competency_rule_config.mustache
admin/tool/lp/templates/competency_rule_points.mustache
admin/tool/lp/templates/competency_summary.mustache
admin/tool/lp/templates/course_competencies_page.mustache
admin/tool/lp/templates/course_competency_settings.mustache
admin/tool/lp/templates/course_competency_statistics.mustache
admin/tool/lp/templates/evidence_summary.mustache
admin/tool/lp/templates/linked_courses_summary.mustache
admin/tool/lp/templates/manage_competencies_page.mustache
admin/tool/lp/templates/manage_competency_frameworks_page.mustache
admin/tool/lp/templates/manage_templates_page.mustache
admin/tool/lp/templates/no_frameworks_warning.mustache
admin/tool/lp/templates/plan_page.mustache
admin/tool/lp/templates/plans_page.mustache
admin/tool/lp/templates/related_competencies.mustache
admin/tool/lp/templates/scale_configuration_page.mustache
admin/tool/lp/templates/template_competencies_page.mustache
admin/tool/lp/templates/template_statistics.mustache
admin/tool/lp/templates/user_competency_course_navigation.mustache
admin/tool/lp/templates/user_competency_summary.mustache
admin/tool/lp/templates/user_competency_summary_in_course.mustache
admin/tool/lp/templates/user_competency_summary_in_plan.mustache
admin/tool/lp/templates/user_evidence_list_page.mustache
admin/tool/lp/templates/user_evidence_page.mustache
admin/tool/lpimportcsv/lang/en/tool_lpimportcsv.php
admin/tool/lpmigrate/frameworks.php
admin/tool/messageinbound/classes/manager.php
admin/tool/messageinbound/settings.php
admin/tool/mobile/lang/en/tool_mobile.php
admin/tool/mobile/launch.php
admin/tool/monitor/classes/notification_task.php
admin/tool/recyclebin/lib.php
admin/tool/recyclebin/tests/behat/backup_user_data.feature
admin/tool/recyclebin/tests/behat/basic_functionality.feature
admin/tool/recyclebin/tests/course_bin_test.php
admin/tool/templatelibrary/amd/build/display.min.js
admin/tool/templatelibrary/amd/build/search.min.js
admin/tool/templatelibrary/amd/src/display.js
admin/tool/templatelibrary/amd/src/search.js
admin/tool/templatelibrary/classes/api.php
admin/tool/templatelibrary/classes/external.php
admin/tool/usertours/classes/local/filter/role.php
admin/tool/usertours/lang/en/tool_usertours.php
admin/tool/usertours/tests/role_filter_test.php
admin/user/user_bulk_forms.php
admin/user/user_bulk_message.php
auth/email/classes/external.php
auth/ldap/lang/en/auth_ldap.php
auth/radius/auth.php [deleted file]
auth/radius/config.html [deleted file]
auth/radius/db/install.php [deleted file]
auth/radius/lang/en/auth_radius.php [deleted file]
auth/upgrade.txt
availability/condition/completion/classes/frontend.php
availability/condition/grade/classes/frontend.php
backup/util/dbops/backup_plan_dbops.class.php
backup/util/helper/backup_cron_helper.class.php
backup/util/loggers/base_logger.class.php
badges/cron.php
blocks/recent_activity/tests/behat/structural_changes.feature
blog/external_blog_edit_form.php
blog/index.php
blog/rsslib.php
cache/classes/dummystore.php
cache/classes/factory.php
cache/classes/helper.php
cache/classes/store.php
cache/locallib.php
cache/stores/apcu/lang/en/cachestore_apcu.php
cache/stores/apcu/lib.php
cache/stores/apcu/tests/apcu_test.php
cache/stores/file/lib.php
cache/stores/memcache/lib.php
cache/stores/memcache/tests/memcache_test.php
cache/stores/memcached/lib.php
cache/stores/memcached/tests/memcached_test.php
cache/stores/mongodb/lib.php
cache/stores/mongodb/tests/mongodb_test.php
cache/stores/redis/README.md [new file with mode: 0644]
cache/stores/redis/addinstanceform.php [new file with mode: 0644]
cache/stores/redis/lang/en/cachestore_redis.php [new file with mode: 0644]
cache/stores/redis/lib.php [new file with mode: 0644]
cache/stores/redis/settings.php [new file with mode: 0644]
cache/stores/redis/tests/redis_test.php [new file with mode: 0644]
cache/stores/redis/version.php [new file with mode: 0644]
cache/stores/session/lib.php
cache/stores/static/lib.php
cache/tests/cache_test.php
cache/tests/fixtures/lib.php
cache/tests/fixtures/stores.php
cache/upgrade.txt
cohort/index.php
competency/classes/user_competency_plan.php
competency/lib.php
course/classes/task/course_delete_modules.php [new file with mode: 0644]
course/editsection.php
course/lib.php
course/rest.php
course/tests/courselib_test.php
enrol/flatfile/lang/en/enrol_flatfile.php
enrol/flatfile/lib.php
enrol/imsenterprise/lib.php
enrol/ldap/lang/en/enrol_ldap.php
enrol/lti/classes/data_connector.php
enrol/lti/classes/manage_table.php
enrol/lti/classes/task/sync_members.php
enrol/lti/classes/tool_provider.php
enrol/lti/db/install.xml
enrol/lti/db/upgrade.php
enrol/lti/index.php
enrol/lti/lang/en/deprecated.txt [new file with mode: 0644]
enrol/lti/lang/en/enrol_lti.php
enrol/lti/styles.css [deleted file]
enrol/lti/templates/copy_grid.mustache [new file with mode: 0644]
enrol/lti/tests/data_connector_test.php
enrol/lti/tests/sync_members_test.php [new file with mode: 0644]
enrol/lti/tool.php
enrol/lti/version.php
enrol/manual/lang/en/enrol_manual.php
enrol/meta/lib.php
enrol/paypal/classes/util.php
enrol/paypal/ipn.php
enrol/paypal/lang/en/enrol_paypal.php
enrol/self/lang/en/enrol_self.php
error/index.php
filter/mediaplugin/dev/perftest.php
filter/mediaplugin/filter.php
filter/mediaplugin/lang/en/filter_mediaplugin.php
filter/mediaplugin/settings.php [moved from auth/radius/version.php with 64% similarity]
filter/mediaplugin/styles.css
filter/mediaplugin/tests/filter_test.php
grade/lib.php
group/index.php
iplookup/tests/geoip_test.php
lang/en/admin.php
lang/en/auth.php
lang/en/deprecated.txt
lang/en/grades.php
lang/en/media.php
lang/en/moodle.php
lang/en/plugin.php
lang/en/role.php
lib/adminlib.php
lib/amd/build/inplace_editable.min.js
lib/amd/src/inplace_editable.js
lib/badgeslib.php
lib/classes/antivirus/scanner.php
lib/classes/component.php
lib/classes/event/message_sent.php
lib/classes/filetypes.php
lib/classes/message/manager.php
lib/classes/message/message.php
lib/classes/plugin_manager.php
lib/classes/plugininfo/media.php [new file with mode: 0644]
lib/classes/task/send_failed_login_notifications_task.php
lib/classes/update/checker.php
lib/classes/user.php
lib/classes/useragent.php
lib/completionlib.php
lib/db/access.php
lib/db/install.php
lib/db/install.xml
lib/db/services.php
lib/db/upgrade.php
lib/editor/tinymce/plugins/moodlemedia/preview.php
lib/enrollib.php
lib/externallib.php
lib/filestorage/file_storage.php
lib/flowplayer/LICENSE.txt [deleted file]
lib/flowplayer/README.txt [deleted file]
lib/flowplayer/README_audio.txt [deleted file]
lib/flowplayer/flowplayer-3.2.13.js [deleted file]
lib/flowplayer/flowplayer-3.2.13.min.js [deleted file]
lib/flowplayer/flowplayer-3.2.18.swf [deleted file]
lib/flowplayer/flowplayer-3.2.18.swf.bin [deleted file]
lib/flowplayer/flowplayer.audio-3.2.11.swf [deleted file]
lib/flowplayer/flowplayer.audio-3.2.11.swf.bin [deleted file]
lib/flowplayer/flowplayer.controls-3.2.16.swf [deleted file]
lib/flowplayer/flowplayer.controls-3.2.16.swf.bin [deleted file]
lib/flowplayer/lib.php [deleted file]
lib/flowplayer/readme_moodle.txt [deleted file]
lib/form/autocomplete.php
lib/form/editor.php
lib/form/group.php
lib/form/searchableselector.js [deleted file]
lib/form/searchableselector.php
lib/form/select.php
lib/form/selectgroups.php
lib/form/selectwithlink.php
lib/form/static.php
lib/form/templates/editor_textarea.mustache
lib/form/url.php
lib/grade/grade_item.php
lib/javascript-static.js
lib/ltiprovider/readme_moodle.txt
lib/ltiprovider/src/ToolProvider/Context.php
lib/ltiprovider/src/ToolProvider/DataConnector/DataConnector_mysql.php
lib/ltiprovider/src/ToolProvider/DataConnector/DataConnector_pdo.php
lib/ltiprovider/src/ToolProvider/ToolConsumer.php
lib/ltiprovider/src/ToolProvider/ToolProvider.php
lib/medialib.php
lib/messagelib.php
lib/modinfolib.php
lib/moodlelib.php
lib/outputrenderers.php
lib/pagelib.php
lib/phpunit/classes/util.php
lib/phpunit/tests/advanced_test.php
lib/portfolio/forms.php
lib/portfoliolib.php
lib/setuplib.php
lib/templates/copy_box.mustache
lib/templates/popover_region.mustache
lib/testing/classes/util.php
lib/tests/behat/behat_general.php
lib/tests/medialib_test.php
lib/tests/message_test.php
lib/tests/messagelib_test.php
lib/tests/moodlelib_test.php
lib/thirdpartylibs.xml
lib/upgrade.txt
lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu-debug.js
lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu-min.js
lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu.js
lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-debug.js
lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker-min.js
lib/yui/build/moodle-core-formchangechecker/moodle-core-formchangechecker.js
lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer-debug.js
lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer-min.js
lib/yui/build/moodle-core-maintenancemodetimer/moodle-core-maintenancemodetimer.js
lib/yui/src/actionmenu/js/actionmenu.js
lib/yui/src/formchangechecker/js/formchangechecker.js
lib/yui/src/maintenancemodetimer/js/maintenancemodetimer.js
login/confirm.php
login/token.php
media/classes/manager.php [new file with mode: 0644]
media/classes/player.php [new file with mode: 0644]
media/classes/player_external.php [new file with mode: 0644]
media/classes/player_native.php [new file with mode: 0644]
media/player/html5audio/classes/plugin.php [new file with mode: 0644]
media/player/html5audio/lang/en/media_html5audio.php [moved from lib/flowplayer/flowplayer-3.2.18.swf.php with 63% similarity]
media/player/html5audio/pix/icon.png [new file with mode: 0644]
media/player/html5audio/tests/player_test.php [new file with mode: 0644]
media/player/html5audio/version.php [new file with mode: 0644]
media/player/html5video/classes/plugin.php [new file with mode: 0644]
media/player/html5video/lang/en/media_html5video.php [moved from lib/flowplayer/flowplayer.audio-3.2.11.swf.php with 63% similarity]
media/player/html5video/pix/icon.png [new file with mode: 0644]
media/player/html5video/tests/player_test.php [new file with mode: 0644]
media/player/html5video/version.php [new file with mode: 0644]
media/player/swf/classes/plugin.php [new file with mode: 0644]
media/player/swf/lang/en/media_swf.php [new file with mode: 0644]
media/player/swf/pix/icon.png [new file with mode: 0644]
media/player/swf/tests/player_test.php [new file with mode: 0644]
media/player/swf/version.php [moved from lib/flowplayer/flowplayer.controls-3.2.16.swf.php with 62% similarity]
media/player/videojs/amd/build/Youtube.min.js [new file with mode: 0644]
media/player/videojs/amd/build/video.min.js [new file with mode: 0644]
media/player/videojs/amd/src/Youtube.js [new file with mode: 0644]
media/player/videojs/amd/src/video.js [new file with mode: 0644]
media/player/videojs/classes/plugin.php [new file with mode: 0644]
media/player/videojs/fonts/VideoJS.eot [new file with mode: 0644]
media/player/videojs/fonts/VideoJS.svg [new file with mode: 0644]
media/player/videojs/fonts/VideoJS.ttf [new file with mode: 0644]
media/player/videojs/fonts/VideoJS.woff [new file with mode: 0644]
media/player/videojs/lang/en/media_videojs.php [new file with mode: 0644]
media/player/videojs/pix/icon.png [new file with mode: 0644]
media/player/videojs/readme_moodle.txt [new file with mode: 0644]
media/player/videojs/settings.php [new file with mode: 0644]
media/player/videojs/styles.css [new file with mode: 0644]
media/player/videojs/tests/player_test.php [new file with mode: 0644]
media/player/videojs/thirdpartylibs.xml [new file with mode: 0644]
media/player/videojs/version.php [new file with mode: 0644]
media/player/videojs/video-js.swf [new file with mode: 0644]
media/player/videojs/videojs/LICENSE [new file with mode: 0644]
media/player/videojs/videojs/lang/ar.js [new file with mode: 0644]
media/player/videojs/videojs/lang/ba.js [new file with mode: 0644]
media/player/videojs/videojs/lang/bg.js [new file with mode: 0644]
media/player/videojs/videojs/lang/ca.js [new file with mode: 0644]
media/player/videojs/videojs/lang/cs.js [new file with mode: 0644]
media/player/videojs/videojs/lang/da.js [new file with mode: 0644]
media/player/videojs/videojs/lang/de.js [new file with mode: 0644]
media/player/videojs/videojs/lang/el.js [new file with mode: 0644]
media/player/videojs/videojs/lang/en.js [new file with mode: 0644]
media/player/videojs/videojs/lang/es.js [new file with mode: 0644]
media/player/videojs/videojs/lang/fa.js [new file with mode: 0644]
media/player/videojs/videojs/lang/fi.js [new file with mode: 0644]
media/player/videojs/videojs/lang/fr.js [new file with mode: 0644]
media/player/videojs/videojs/lang/hr.js [new file with mode: 0644]
media/player/videojs/videojs/lang/hu.js [new file with mode: 0644]
media/player/videojs/videojs/lang/it.js [new file with mode: 0644]
media/player/videojs/videojs/lang/ja.js [new file with mode: 0644]
media/player/videojs/videojs/lang/ko.js [new file with mode: 0644]
media/player/videojs/videojs/lang/nb.js [new file with mode: 0644]
media/player/videojs/videojs/lang/nl.js [new file with mode: 0644]
media/player/videojs/videojs/lang/nn.js [new file with mode: 0644]
media/player/videojs/videojs/lang/pl.js [new file with mode: 0644]
media/player/videojs/videojs/lang/pt-BR.js [new file with mode: 0644]
media/player/videojs/videojs/lang/ru.js [new file with mode: 0644]
media/player/videojs/videojs/lang/sr.js [new file with mode: 0644]
media/player/videojs/videojs/lang/sv.js [new file with mode: 0644]
media/player/videojs/videojs/lang/tr.js [new file with mode: 0644]
media/player/videojs/videojs/lang/uk.js [new file with mode: 0644]
media/player/videojs/videojs/lang/vi.js [new file with mode: 0644]
media/player/videojs/videojs/lang/zh-CN.js [new file with mode: 0644]
media/player/videojs/videojs/lang/zh-TW.js [new file with mode: 0644]
media/player/vimeo/classes/plugin.php [new file with mode: 0644]
media/player/vimeo/lang/en/media_vimeo.php [new file with mode: 0644]
media/player/vimeo/pix/icon.png [new file with mode: 0644]
media/player/vimeo/tests/player_test.php [new file with mode: 0644]
media/player/vimeo/version.php [new file with mode: 0644]
media/player/youtube/classes/plugin.php [new file with mode: 0644]
media/player/youtube/lang/en/media_youtube.php [new file with mode: 0644]
media/player/youtube/pix/icon.png [new file with mode: 0644]
media/player/youtube/tests/player_test.php [new file with mode: 0644]
media/player/youtube/version.php [new file with mode: 0644]
message/amd/build/message_area_contacts.min.js
message/amd/src/message_area_contacts.js
message/classes/api.php
message/externallib.php
message/lib.php
message/output/email/lang/en/message_email.php
message/output/email/settings.php [deleted file]
message/templates/message_preferences_component.mustache
message/templates/message_preferences_notification_processor.mustache
message/templates/notification_preferences_component.mustache
message/templates/notification_preferences_component_notification.mustache
message/tests/api_test.php
message/tests/events_test.php
message/tests/externallib_test.php
message/tests/messagelib_test.php
message/tests/search_test_received.php
message/tests/search_test_sent.php
mod/assign/backup/moodle2/backup_assign_stepslib.php
mod/assign/backup/moodle2/restore_assign_stepslib.php
mod/assign/classes/event/group_override_created.php [new file with mode: 0644]
mod/assign/classes/event/group_override_deleted.php [new file with mode: 0644]
mod/assign/classes/event/group_override_updated.php [new file with mode: 0644]
mod/assign/classes/event/user_override_created.php [new file with mode: 0644]
mod/assign/classes/event/user_override_deleted.php [new file with mode: 0644]
mod/assign/classes/event/user_override_updated.php [new file with mode: 0644]
mod/assign/classes/group_observers.php [new file with mode: 0644]
mod/assign/db/access.php
mod/assign/db/events.php [new file with mode: 0644]
mod/assign/db/install.xml
mod/assign/db/upgrade.php
mod/assign/externallib.php
mod/assign/gradingtable.php
mod/assign/lang/en/assign.php
mod/assign/lib.php
mod/assign/locallib.php
mod/assign/override_form.php [new file with mode: 0644]
mod/assign/overridedelete.php [new file with mode: 0644]
mod/assign/overrideedit.php [new file with mode: 0644]
mod/assign/overrides.php [new file with mode: 0644]
mod/assign/styles.css
mod/assign/templates/grading_navigation.mustache
mod/assign/templates/grading_navigation_user_summary.mustache
mod/assign/tests/behat/assign_course_reset.feature [new file with mode: 0644]
mod/assign/tests/behat/assign_group_override.feature [new file with mode: 0644]
mod/assign/tests/behat/assign_user_override.feature [new file with mode: 0644]
mod/assign/tests/events_test.php
mod/assign/tests/locallib_test.php
mod/assign/version.php
mod/assign/view.php
mod/data/view.php
mod/feedback/classes/complete_form.php
mod/feedback/edit_form.php
mod/feedback/lib.php
mod/feedback/show_nonrespondents.php
mod/forum/externallib.php
mod/forum/lib.php
mod/forum/settings.php
mod/forum/tests/mail_test.php
mod/forum/upgrade.txt
mod/lesson/essay.php
mod/lesson/locallib.php
mod/lesson/tests/behat/import_images.feature
mod/lesson/view.php
mod/lti/amd/build/tool_configure_controller.min.js
mod/lti/amd/src/tool_configure_controller.js
mod/lti/classes/output/tool_configure_page.php
mod/lti/lang/en/deprecated.txt [new file with mode: 0644]
mod/lti/lang/en/lti.php
mod/lti/mod_form.php
mod/lti/templates/cartridge_registration_form.mustache
mod/lti/tests/behat/addtool.feature
mod/lti/tests/behat/addtype.feature
mod/lti/tests/behat/contentitem.feature
mod/lti/tests/behat/contentitemregistration.feature
mod/quiz/accessrule/offlineattempts/lang/en/quizaccess_offlineattempts.php
mod/quiz/lang/en/quiz.php
mod/quiz/locallib.php
mod/quiz/override_form.php
mod/quiz/renderer.php
mod/quiz/tests/behat/attempt_redo_questions.feature
mod/resource/locallib.php
mod/scorm/locallib.php
mod/scorm/module.js
mod/scorm/report/basic/classes/report.php
mod/scorm/report/interactions/classes/report.php
mod/scorm/report/objectives/classes/report.php
mod/scorm/styles.css
mod/url/locallib.php
mod/wiki/view.php
portfolio/googledocs/tests/plugin_test.php [new file with mode: 0644]
question/type/calculated/lang/en/qtype_calculated.php
report/security/locallib.php
theme/boost/amd/build/form-display-errors.min.js
theme/boost/amd/src/form-display-errors.js
theme/boost/classes/output/core_renderer.php
theme/boost/config.php
theme/boost/lang/en/theme_boost.php
theme/boost/layout/columns1.php
theme/boost/layout/columns2.php
theme/boost/lib.php
theme/boost/scss/moodle/admin.scss
theme/boost/scss/moodle/blocks.scss
theme/boost/scss/moodle/bootswatch.scss
theme/boost/scss/moodle/core.scss
theme/boost/scss/moodle/course.scss
theme/boost/scss/moodle/drawer.scss
theme/boost/scss/moodle/expendable.scss
theme/boost/scss/moodle/forms.scss
theme/boost/scss/moodle/icons.scss
theme/boost/scss/moodle/modules.scss
theme/boost/scss/moodle/popover-region.scss
theme/boost/scss/moodle/search.scss
theme/boost/scss/moodle/undo.scss
theme/boost/scss/preset-flatly.scss [deleted file]
theme/boost/scss/preset-paper.scss [deleted file]
theme/boost/scss/preset-readable.scss [deleted file]
theme/boost/scss/preset.scss [new file with mode: 0644]
theme/boost/scss/preset/default.scss [moved from theme/boost/scss/preset-default.scss with 100% similarity]
theme/boost/scss/preset/plain.scss [moved from theme/boost/scss/preset-plain.scss with 100% similarity]
theme/boost/settings.php
theme/boost/templates/columns1.mustache
theme/boost/templates/columns2.mustache
theme/boost/templates/core/block.mustache
theme/boost/templates/core/help_icon.mustache
theme/boost/templates/core_admin/setting_configpasswordunmask.mustache
theme/boost/templates/core_admin/settings_search_results.mustache
theme/boost/templates/core_form/editor_textarea.mustache
theme/boost/templates/core_form/element-advcheckbox-inline.mustache
theme/boost/templates/core_form/element-advcheckbox.mustache
theme/boost/templates/core_form/element-checkbox-inline.mustache
theme/boost/templates/core_form/element-checkbox.mustache
theme/boost/templates/core_form/element-date_selector.mustache
theme/boost/templates/core_form/element-date_time_selector-inline.mustache
theme/boost/templates/core_form/element-date_time_selector.mustache
theme/boost/templates/core_form/element-group-inline.mustache
theme/boost/templates/core_form/element-group.mustache
theme/boost/templates/core_form/element-radio-inline.mustache
theme/boost/templates/core_form/element-radio.mustache
theme/boost/templates/core_form/element-select-inline.mustache
theme/boost/templates/core_form/element-select.mustache
theme/boost/templates/core_form/element-selectgroups-inline.mustache
theme/boost/templates/core_form/element-selectgroups.mustache
theme/boost/templates/core_form/element-selectwithlink.mustache
theme/boost/templates/core_form/element-static.mustache
theme/boost/templates/core_form/element-template.mustache
theme/boost/templates/flat_navigation.mustache
theme/boost/templates/header.mustache
theme/boost/templates/maintenance.mustache
theme/boost/templates/mod_assign/grading_navigation.mustache
theme/boost/templates/tool_lp/progress_bar.mustache [new file with mode: 0644]
theme/boost/thirdpartylibs.xml
theme/boost/version.php
theme/bootstrapbase/less/moodle/bs4-compat.less
theme/bootstrapbase/less/moodle/buttons.less
theme/bootstrapbase/less/moodle/course.less
theme/bootstrapbase/less/moodle/tool_usertours.less
theme/bootstrapbase/style/moodle.css
user/edit.php
user/profile/lib.php
version.php
webservice/renderer.php

index 9ad89b7..fe5da7b 100644 (file)
@@ -24,7 +24,6 @@ lib/htmlpurifier/
 lib/jabber/
 lib/minify/matthiasmullie-minify/
 lib/minify/matthiasmullie-pathconverter/
-lib/flowplayer/
 lib/pear/Auth/RADIUS.php
 lib/pear/Crypt/CHAP.php
 lib/pear/HTML/Common.php
@@ -57,6 +56,8 @@ lib/amd/src/chartjs-lazy.js
 lib/maxmind/GeoIp2/
 lib/maxmind/MaxMind/
 lib/ltiprovider/
+media/player/videojs/amd/src/
+media/player/videojs/videojs/
 mod/assign/feedback/editpdf/fpdi/
 repository/s3/S3.php
 theme/boost/scss/bootstrap/
@@ -72,9 +73,6 @@ theme/boost/amd/src/tab.js
 theme/boost/amd/src/tooltip.js
 theme/boost/amd/src/util.js
 theme/boost/amd/src/tether.js
-theme/boost/scss/preset-flatly.scss
-theme/boost/scss/preset-paper.scss
-theme/boost/scss/preset-readable.scss
 theme/bootstrapbase/less/bootstrap/
 theme/bootstrapbase/javascript/html5shiv.js
 theme/bootstrapbase/amd/src/bootstrap.js
\ No newline at end of file
index f6ac277..cafa933 100644 (file)
@@ -25,7 +25,6 @@ lib/htmlpurifier/
 lib/jabber/
 lib/minify/matthiasmullie-minify/
 lib/minify/matthiasmullie-pathconverter/
-lib/flowplayer/
 lib/pear/Auth/RADIUS.php
 lib/pear/Crypt/CHAP.php
 lib/pear/HTML/Common.php
@@ -58,6 +57,8 @@ lib/amd/src/chartjs-lazy.js
 lib/maxmind/GeoIp2/
 lib/maxmind/MaxMind/
 lib/ltiprovider/
+media/player/videojs/amd/src/
+media/player/videojs/videojs/
 mod/assign/feedback/editpdf/fpdi/
 repository/s3/S3.php
 theme/boost/scss/bootstrap/
@@ -73,9 +74,6 @@ theme/boost/amd/src/tab.js
 theme/boost/amd/src/tooltip.js
 theme/boost/amd/src/util.js
 theme/boost/amd/src/tether.js
-theme/boost/scss/preset-flatly.scss
-theme/boost/scss/preset-paper.scss
-theme/boost/scss/preset-readable.scss
 theme/bootstrapbase/less/bootstrap/
 theme/bootstrapbase/javascript/html5shiv.js
 theme/bootstrapbase/amd/src/bootstrap.js
\ No newline at end of file
diff --git a/admin/media.php b/admin/media.php
new file mode 100644 (file)
index 0000000..d6886a0
--- /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/>.
+
+/**
+ * Enrol config manipulation script.
+ *
+ * @package    core
+ * @subpackage media
+ * @copyright  2016 Marina Glancy
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define('NO_OUTPUT_BUFFERING', true);
+
+require_once('../config.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+$action  = required_param('action', PARAM_ALPHANUMEXT);
+$media   = required_param('media', PARAM_PLUGIN);
+$confirm = optional_param('confirm', 0, PARAM_BOOL);
+
+$PAGE->set_url('/admin/media.php');
+$PAGE->set_context(context_system::instance());
+
+require_login();
+require_capability('moodle/site:config', context_system::instance());
+require_sesskey();
+
+$plugins = core_plugin_manager::instance()->get_plugins_of_type('media');
+$sortorder = array_values(\core\plugininfo\media::get_enabled_plugins());
+
+$return = new moodle_url('/admin/settings.php', array('section' => 'managemediaplayers'));
+
+if (!array_key_exists($media, $plugins)) {
+    redirect($return);
+}
+
+switch ($action) {
+    case 'disable':
+        $plugins[$media]->set_enabled(false);
+        break;
+
+    case 'enable':
+        $plugins[$media]->set_enabled(true);
+        break;
+
+    case 'up':
+        if (($pos = array_search($media, $sortorder)) > 0) {
+            $tmp = $sortorder[$pos - 1];
+            $sortorder[$pos - 1] = $sortorder[$pos];
+            $sortorder[$pos] = $tmp;
+            \core\plugininfo\media::set_enabled_plugins($sortorder);
+        }
+        break;
+
+    case 'down':
+        if ((($pos = array_search($media, $sortorder)) !== false) && ($pos < count($sortorder) - 1)) {
+            $tmp = $sortorder[$pos + 1];
+            $sortorder[$pos + 1] = $sortorder[$pos];
+            $sortorder[$pos] = $tmp;
+            \core\plugininfo\media::set_enabled_plugins($sortorder);
+        }
+        break;
+}
+
+redirect($return);
index a9339b0..5769e6d 100644 (file)
@@ -60,7 +60,8 @@ class mnet_simple_host_form extends moodleform {
         }
         if ($host = $DB->get_record('mnet_host', array('wwwroot' => $wwwroot))) {
             global $CFG;
-            return array('wwwroot' => get_string('hostexists', 'mnet', $CFG->wwwroot . '/admin/mnet/peers.php?hostid=' . $host->id));
+            return array('wwwroot' => get_string('hostexists', 'mnet',
+                new moodle_url('/admin/mnet/peers.php', array('hostid' => $host->id))));
         }
         return array();
     }
index df1f6e2..559d2f4 100644 (file)
@@ -109,7 +109,7 @@ if (!empty($hostid)) {
     $mnet_peer->set_id($hostid);
     echo $OUTPUT->header();
     $currenttab = 'mnetdetails';
-    require_once($CFG->dirroot . '/admin/mnet/tabs.php');
+    require_once($CFG->dirroot . '/' . $CFG->admin . '/mnet/tabs.php');
 
     if ($hostid != $CFG->mnet_all_hosts_id) {
         $mnet_peer->currentkey = mnet_get_public_key($mnet_peer->wwwroot, $mnet_peer->application);
@@ -144,7 +144,7 @@ if (empty($noreviewform) && $id = optional_param('id', 0, PARAM_INT)) {
     // we're editing an existing one, so set up the tabs
     $currenttab = 'mnetdetails';
     $mnet_peer->set_id($id);
-    require_once($CFG->dirroot . '/admin/mnet/tabs.php');
+    require_once($CFG->dirroot . '/' . $CFG->admin . '/mnet/tabs.php');
 } else if (empty($noreviewform) && ($wwwroot = optional_param('wwwroot', '', PARAM_URL)) && ($applicationid = optional_param('applicationid', 0, PARAM_INT))) {
     $application = $DB->get_field('mnet_application', 'name', array('id'=>$applicationid));
     $mnet_peer->bootstrap($wwwroot, null, $application);
index 24ba79c..a27f162 100644 (file)
@@ -26,7 +26,7 @@
 
 require(__DIR__.'/../../config.php');
 require_once($CFG->libdir.'/adminlib.php');
-require_once($CFG->dirroot . '/admin/mnet/profilefields_form.php');
+require_once($CFG->dirroot . '/' . $CFG->admin .'/mnet/profilefields_form.php');
 $mnet = get_mnet_environment();
 
 require_login();
index ea588cd..79e46e9 100644 (file)
@@ -27,7 +27,7 @@
 
 require(__DIR__.'/../../config.php');
 require_once($CFG->libdir.'/adminlib.php');
-require_once($CFG->dirroot . '/admin/mnet/services_form.php');
+require_once($CFG->dirroot . '/' . $CFG->admin . '/mnet/services_form.php');
 $mnet = get_mnet_environment();
 
 require_login();
@@ -82,7 +82,7 @@ if ($formdata = $mform->get_data()) {
 
 echo $OUTPUT->header();
 $currenttab = 'mnetservices';
-require_once($CFG->dirroot . '/admin/mnet/tabs.php');
+require_once($CFG->dirroot . '/' . $CFG->admin . '/mnet/tabs.php');
 echo $OUTPUT->box_start();
 $s = mnet_get_service_info($mnet_peer, false); // basic data only
 $mform->set_data($s);
index 2b66c9f..d98e379 100644 (file)
@@ -32,6 +32,8 @@ $getroles = optional_param('getroles', 0, PARAM_BOOL);
 
 list($context, $course, $cm) = get_context_info_array($contextid);
 
+$PAGE->set_context($context);
+
 require_login($course, false, $cm);
 require_capability('moodle/role:review', $context);
 require_sesskey();
index 9f339d8..76260c7 100644 (file)
@@ -132,7 +132,7 @@ class core_role_permissions_table extends core_role_capability_table_base {
 
         $risks = $this->get_risks($capability);
 
-        $contents = html_writer::tag('td', $risks, array('class' => 'risks'));
+        $contents = html_writer::tag('td', $risks, array('class' => 'risks text-nowrap'));
         $contents .= html_writer::tag('td', $neededroles, array('class' => 'allowedroles'));
         $contents .= html_writer::tag('td', $forbiddenroles, array('class' => 'forbiddenroles'));
         return $contents;
index 5a5e6a3..093c693 100644 (file)
@@ -256,9 +256,9 @@ if ($action === 'view') {
 <input type="hidden" name="sesskey" value="<?php p(sesskey()) ?>" />
 <input type="hidden" name="return" value="<?php p($return); ?>" />
 <input type="hidden" name="resettype" value="none" />
-<div class="submit buttons">
-    <input type="submit" name="savechanges" value="<?php p($submitlabel); ?>" />
-    <input type="submit" name="cancel" value="<?php print_string('cancel'); ?>" />
+<div class="submitbuttons">
+    <input type="submit" name="savechanges" class="btn btn-primary" value="<?php p($submitlabel); ?>" />
+    <input type="submit" name="cancel" class="btn btn-secondary" value="<?php print_string('cancel'); ?>" />
 </div>
     <?php
 }
@@ -271,9 +271,9 @@ if ($action === 'view') {
     echo '</div>';
 } else {
     ?>
-<div class="submit buttons">
-    <input type="submit" name="savechanges" value="<?php p($submitlabel); ?>" />
-    <input type="submit" name="cancel" value="<?php print_string('cancel'); ?>" />
+<div class="submitbuttons">
+    <input type="submit" name="savechanges" class="btn btn-primary" value="<?php p($submitlabel); ?>" />
+    <input type="submit" name="cancel" class="btn btn-secondary" value="<?php print_string('cancel'); ?>" />
 </div>
 </div></form>
 <?php
index 0e9a531..7dd8e2c 100644 (file)
@@ -7,7 +7,8 @@ require_once($CFG->libdir.'/adminlib.php');
 
 $query = trim(optional_param('query', '', PARAM_NOTAGS));  // Search string
 
-$PAGE->set_context(context_system::instance());
+$context = context_system::instance();
+$PAGE->set_context($context);
 
 admin_externalpage_setup('search', '', array('query' => $query)); // now hidden page
 
@@ -18,7 +19,8 @@ $errormsg  = '';
 $focus = '';
 
 // now we'll deal with the case that the admin has submitted the form with changed settings
-if ($data = data_submitted() and confirm_sesskey()) {
+if ($data = data_submitted() and confirm_sesskey() and isset($data->action) and $data->action == 'save-settings') {
+    require_capability('moodle/site:config', $context);
     if (admin_write_settings($data)) {
         redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
     }
@@ -45,14 +47,20 @@ if ($errormsg !== '') {
     echo $OUTPUT->notification($statusmsg, 'notifysuccess');
 }
 
-require_once("admin_settings_search_form.php");
-$form = new admin_settings_search_form();
-$form->display();
-echo '<hr>';
+$showsettingslinks = true;
 
-if ($query) {
-    echo admin_search_settings_html($query);
-} else {
+if (has_capability('moodle/site:config', $context)) {
+    require_once("admin_settings_search_form.php");
+    $form = new admin_settings_search_form();
+    $form->display();
+    echo '<hr>';
+    if ($query) {
+        echo admin_search_settings_html($query);
+        $showsettingslinks = false;
+    }
+}
+
+if ($showsettingslinks) {
     $node = $PAGE->settingsnav->find('root', navigation_node::TYPE_SITE_ADMIN);
     if ($node) {
         echo $OUTPUT->render_from_template('core/settings_link_page', ['node' => $node]);
index 7ee3f70..398c777 100644 (file)
@@ -196,49 +196,6 @@ preferences,moodle|/user/preferences.php|preferences',
     $ADMIN->add('appearance', new admin_externalpage('resetemoticons', new lang_string('emoticonsreset', 'admin'),
         new moodle_url('/admin/resetemoticons.php'), 'moodle/site:config', true));
 
-
-    // The "media" subpage.
-    $temp = new admin_settingpage('mediasettings', get_string('mediasettings', 'core_media'));
-
-    $temp->add(new admin_setting_heading('mediaformats', get_string('mediaformats', 'core_media'),
-            format_text(get_string('mediaformats_desc', 'core_media'), FORMAT_MARKDOWN)));
-
-    // External services.
-    $temp->add(new admin_setting_configcheckbox('core_media_enable_youtube',
-            get_string('siteyoutube', 'core_media'), get_string('siteyoutube_desc', 'core_media'), 1));
-    $temp->add(new admin_setting_configcheckbox('core_media_enable_vimeo',
-            get_string('sitevimeo', 'core_media'), get_string('sitevimeo_desc', 'core_media'), 0));
-
-    // Options which require Flash.
-    $temp->add(new admin_setting_configcheckbox('core_media_enable_mp3',
-            get_string('mp3audio', 'core_media'), get_string('mp3audio_desc', 'core_media'), 1));
-    $temp->add(new admin_setting_configcheckbox('core_media_enable_flv',
-            get_string('flashvideo', 'core_media'), get_string('flashvideo_desc', 'core_media'), 1));
-    $temp->add(new admin_setting_configcheckbox('core_media_enable_swf',
-            get_string('flashanimation', 'core_media'), get_string('flashanimation_desc', 'core_media'), 1));
-
-    // HTML 5 media.
-    // Audio now enabled by default so that it can provide a fallback for mp3 on devices without flash.
-    $temp->add(new admin_setting_configcheckbox('core_media_enable_html5audio',
-            get_string('html5audio', 'core_media'), get_string('html5audio_desc', 'core_media'), 1));
-    // Video now enabled by default so it can provide mp4 support.
-    $temp->add(new admin_setting_configcheckbox('core_media_enable_html5video',
-            get_string('html5video', 'core_media'), get_string('html5video_desc', 'core_media'), 1));
-
-    // Legacy players.
-    $temp->add(new admin_setting_heading('legacymediaformats',
-            get_string('legacyheading', 'core_media'), get_string('legacyheading_desc', 'core_media')));
-
-    $temp->add(new admin_setting_configcheckbox('core_media_enable_qt',
-            get_string('legacyquicktime', 'core_media'), get_string('legacyquicktime_desc', 'core_media'), 1));
-    $temp->add(new admin_setting_configcheckbox('core_media_enable_wmp',
-            get_string('legacywmp', 'core_media'), get_string('legacywmp_desc', 'core_media'), 1));
-    $temp->add(new admin_setting_configcheckbox('core_media_enable_rm',
-            get_string('legacyreal', 'core_media'), get_string('legacyreal_desc', 'core_media'), 1));
-
-    $ADMIN->add('appearance', $temp);
-
-
     // "documentation" settingpage
     $temp = new admin_settingpage('documentation', new lang_string('moodledocs'));
     $temp->add(new admin_setting_configtext('docroot', new lang_string('docroot', 'admin'), new lang_string('configdocroot', 'admin'), 'http://docs.moodle.org', PARAM_URL));
index 2dbff19..bd759a7 100644 (file)
@@ -215,6 +215,28 @@ if ($hassiteconfig) {
         $plugin->load_settings($ADMIN, 'filtersettings', $hassiteconfig);
     }
 
+    // Media players.
+    $ADMIN->add('modules', new admin_category('mediaplayers', new lang_string('type_media_plural', 'plugin')));
+    $temp = new admin_settingpage('managemediaplayers', new lang_string('managemediaplayers', 'media'));
+    $temp->add(new admin_setting_heading('mediaformats', get_string('mediaformats', 'core_media'),
+        format_text(get_string('mediaformats_desc', 'core_media'), FORMAT_MARKDOWN)));
+    $temp->add(new admin_setting_managemediaplayers());
+    $temp->add(new admin_setting_heading('managemediaplayerscommonheading', new lang_string('commonsettings', 'admin'), ''));
+    $temp->add(new admin_setting_configtext('media_default_width',
+        new lang_string('defaultwidth', 'core_media'), new lang_string('defaultwidthdesc', 'core_media'),
+        400, PARAM_INT, 10));
+    $temp->add(new admin_setting_configtext('media_default_height',
+        new lang_string('defaultheight', 'core_media'), new lang_string('defaultheightdesc', 'core_media'),
+        300, PARAM_INT, 10));
+    $ADMIN->add('mediaplayers', $temp);
+
+    $plugins = core_plugin_manager::instance()->get_plugins_of_type('media');
+    core_collator::asort_objects_by_property($plugins, 'displayname');
+    foreach ($plugins as $plugin) {
+        /** @var \core\plugininfo\media $plugin */
+        $plugin->load_settings($ADMIN, 'mediaplayers', $hassiteconfig);
+    }
+
     // Data format settings.
     $ADMIN->add('modules', new admin_category('dataformatsettings', new lang_string('dataformats')));
     $temp = new admin_settingpage('managedataformats', new lang_string('managedataformats'));
index aae21f9..3c56ff1 100644 (file)
@@ -213,6 +213,60 @@ $ADMIN->add('server', $temp);
 $ADMIN->add('server', new admin_externalpage('adminregistration', new lang_string('hubs', 'admin'),
     "$CFG->wwwroot/$CFG->admin/registration/index.php"));
 
+// E-mail settings.
+$ADMIN->add('server', new admin_category('email', new lang_string('categoryemail', 'admin')));
+
+$temp = new admin_settingpage('outgoingmailconfig', new lang_string('outgoingmailconfig', 'admin'));
+
+$temp->add(new admin_setting_heading('smtpheading', new lang_string('smtp', 'admin'),
+            new lang_string('smtpdetail', 'admin')));
+$temp->add(new admin_setting_configtext('smtphosts', new lang_string('smtphosts', 'admin'),
+            new lang_string('configsmtphosts', 'admin'), '', PARAM_RAW));
+$options = array('' => new lang_string('none', 'admin'), 'ssl' => 'SSL', 'tls' => 'TLS');
+$temp->add(new admin_setting_configselect('smtpsecure', new lang_string('smtpsecure', 'admin'),
+            new lang_string('configsmtpsecure', 'admin'), '', $options));
+$authtypeoptions = array('LOGIN' => 'LOGIN', 'PLAIN' => 'PLAIN', 'NTLM' => 'NTLM', 'CRAM-MD5' => 'CRAM-MD5');
+$temp->add(new admin_setting_configselect('smtpauthtype', new lang_string('smtpauthtype', 'admin'),
+            new lang_string('configsmtpauthtype', 'admin'), 'LOGIN', $authtypeoptions));
+$temp->add(new admin_setting_configtext('smtpuser', new lang_string('smtpuser', 'admin'),
+            new lang_string('configsmtpuser', 'admin'), '', PARAM_NOTAGS));
+$temp->add(new admin_setting_configpasswordunmask('smtppass', new lang_string('smtppass', 'admin'),
+            new lang_string('configsmtpuser', 'admin'), ''));
+$temp->add(new admin_setting_configtext('smtpmaxbulk', new lang_string('smtpmaxbulk', 'admin'),
+           new lang_string('configsmtpmaxbulk', 'admin'), 1, PARAM_INT));
+$temp->add(new admin_setting_heading('noreplydomainheading', new lang_string('noreplydomain', 'admin'),
+        new lang_string('noreplydomaindetail', 'admin')));
+$temp->add(new admin_setting_configtext('noreplyaddress', new lang_string('noreplyaddress', 'admin'),
+          new lang_string('confignoreplyaddress', 'admin'), 'noreply@' . get_host_from_url($CFG->wwwroot), PARAM_NOTAGS));
+$temp->add(new admin_setting_configtextarea('allowedemaildomains',
+        new lang_string('allowedemaildomains', 'admin'),
+        new lang_string('configallowedemaildomains', 'admin'),
+        ''));
+$temp->add(new admin_setting_heading('emaildoesnotfit', new lang_string('doesnotfit', 'admin'),
+        new lang_string('doesnotfitdetail', 'admin')));
+$charsets = get_list_of_charsets();
+unset($charsets['UTF-8']); // Not needed here.
+$options = array();
+$options['0'] = 'UTF-8';
+$options = array_merge($options, $charsets);
+$temp->add(new admin_setting_configselect('sitemailcharset', new lang_string('sitemailcharset', 'admin'),
+          new lang_string('configsitemailcharset','admin'), '0', $options));
+$temp->add(new admin_setting_configcheckbox('allowusermailcharset', new lang_string('allowusermailcharset', 'admin'),
+          new lang_string('configallowusermailcharset', 'admin'), 0));
+$temp->add(new admin_setting_configcheckbox('allowattachments', new lang_string('allowattachments', 'admin'),
+          new lang_string('configallowattachments', 'admin'), 1));
+$options = array('LF' => 'LF', 'CRLF' => 'CRLF');
+$temp->add(new admin_setting_configselect('mailnewline', new lang_string('mailnewline', 'admin'),
+          new lang_string('configmailnewline', 'admin'), 'LF', $options));
+
+$choices = array(new lang_string('never', 'admin'),
+                 new lang_string('always', 'admin'),
+                 new lang_string('onlynoreply', 'admin'));
+$temp->add(new admin_setting_configselect('emailfromvia', new lang_string('emailfromvia', 'admin'),
+          new lang_string('configemailfromvia', 'admin'), 1, $choices));
+
+$ADMIN->add('email', $temp);
+
 // "update notifications" settingpage
 if (empty($CFG->disableupdatenotifications)) {
     $temp = new admin_settingpage('updatenotifications', new lang_string('updatenotifications', 'core_admin'));
index 59a6102..5d4495c 100644 (file)
@@ -47,4 +47,4 @@ $ADMIN->add('root', new admin_category('development', new lang_string('developme
 $ADMIN->add('root', new admin_category('unsupported', new lang_string('unsupported', 'admin'), true));
 
 // hidden search script
-$ADMIN->add('root', new admin_externalpage('search', new lang_string('search', 'admin'), "$CFG->wwwroot/$CFG->admin/search.php", 'moodle/site:config', true));
+$ADMIN->add('root', new admin_externalpage('search', new lang_string('search', 'admin'), "$CFG->wwwroot/$CFG->admin/search.php", 'moodle/site:configview', true));
index bf00ea7..cf7565c 100644 (file)
 }}
 <div class="form-password">
     <span data-passwordunmask="wrapper" data-passwordunmaskid="{{ id }}">
-        <noscript>
-            <!-- Backwards compatability for Behat -->
-            <input  type="password"
-                    name="{{ name }}"
-                    id="{{ id }}"
-                    value="{{ value }}"
-                    size="{{ size }}"
-                    >
-        </noscript>
         <span class="visibleifjs">
             <span data-passwordunmask="editor">
-                <!-- The input in the noscript will be moved here as part of the page load -->
+                <input  type="hidden"
+                        name="{{ name }}"
+                        id="{{ id }}"
+                        value="{{ value }}"
+                        size="{{ size }}"
+                        >
             </span>
             <a href="#" data-passwordunmask="edit" title="{{ edithint }}">
                 <span data-passwordunmask="displayvalue">{{> core_form/element-passwordunmask-fill }}</span>
                 {{# str }} passwordunmaskinstructions, form {{/ str }}
             </span>
         </span>
+        <noscript>
+            <!-- Backwards compatability for Behat -->
+            <input  type="password"
+                    name="{{ name }}"
+                    id="{{ id }}"
+                    value="{{ value }}"
+                    size="{{ size }}"
+                    >
+        </noscript>
     </span>
 </div>
 {{#js}}
index c6f7bbb..78b6205 100644 (file)
@@ -37,6 +37,7 @@
 <form action="{{actionurl}}" method="post" id="adminsettings">
     <div>
         <input type="hidden" name="sesskey" value="{{sesskey}}">
+        <input type="hidden" name="action" value="save-settings">
     </div>
     <fieldset>
         <div class="clearer"></div>
index f249b03..6d50e26 100644 (file)
Binary files a/admin/tool/lp/amd/build/menubar.min.js and b/admin/tool/lp/amd/build/menubar.min.js differ
index 0434b56..76595fe 100644 (file)
@@ -258,7 +258,7 @@ define(['jquery'], function($) {
     Menubar.prototype.setOpenDirection = function() {
         var pos = this.menuRoot.offset();
         var isRTL = $(document.body).hasClass('dir-rtl');
-        var openLeft = false;
+        var openLeft = true;
         var heightmenuRoot = this.rootMenus.outerHeight();
         var widthmenuRoot = this.rootMenus.outerWidth();
         // Sometimes the menuMinWidth is not enough to figure out if menu exceeds the window width.
index 28de24c..74bb0c8 100644 (file)
@@ -56,7 +56,7 @@ class user_evidence extends persistent {
         $mform->addElement('editor', 'description', get_string('userevidencedescription', 'tool_lp'), array('rows' => 10));
         $mform->setType('description', PARAM_RAW);
 
-        $mform->addElement('url', 'url', get_string('userevidenceurl', 'tool_lp'), array(), array('usefilepicker' => false));
+        $mform->addElement('url', 'url', get_string('userevidenceurl', 'tool_lp'), array('size' => '60'), array('usefilepicker' => false));
         $mform->setType('url', PARAM_RAW_TRIMMED);      // Can not use PARAM_URL, it silently converts bad URLs to ''.
         $mform->addHelpButton('url', 'userevidenceurl', 'tool_lp');
 
index 7f1ba9c..aed8874 100644 (file)
@@ -142,7 +142,7 @@ function tool_lp_coursemodule_standard_elements($formwrapper, $mform) {
     $mform->addElement('header', 'competenciessection', get_string('competencies', 'core_competency'));
 
     MoodleQuickForm::registerElementType('course_competencies',
-                                         "$CFG->dirroot/admin/tool/lp/classes/course_competencies_form_element.php",
+                                         "$CFG->dirroot/$CFG->admin/tool/lp/classes/course_competencies_form_element.php",
                                          'tool_lp_course_competencies_form_element');
     $cmid = null;
     if ($cm = $formwrapper->get_coursemodule()) {
@@ -155,7 +155,7 @@ function tool_lp_coursemodule_standard_elements($formwrapper, $mform) {
     $mform->addElement('course_competencies', 'competencies', get_string('modcompetencies', 'tool_lp'), $options);
     $mform->addHelpButton('competencies', 'modcompetencies', 'tool_lp');
     MoodleQuickForm::registerElementType('course_competency_rule',
-                                         "$CFG->dirroot/admin/tool/lp/classes/course_competency_rule_form_element.php",
+                                         "$CFG->dirroot/$CFG->admin/tool/lp/classes/course_competency_rule_form_element.php",
                                          'tool_lp_course_competency_rule_form_element');
     // Reuse the same options.
     $mform->addElement('course_competency_rule', 'competency_rule', get_string('uponcoursemodulecompletion', 'tool_lp'), $options);
index e811b9a..73e7313 100644 (file)
 }
 
 .tool-lp-menu.tool-lp-menu-open-left .tool-lp-sub-menu {
-    margin-left: -120px;
+    left: auto;
+    right: 0;
 }
 
 /** This highlighting is copied from bootstrap - but can be overridden by a theme */
index 1f307a7..7ebb157 100644 (file)
@@ -15,6 +15,8 @@
     along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 }}
 {{!
+    @template tool_lp/action_selector
+
     Select an action to execute.
 
     Classes required for JS:
     * choices - List of possible actions
     * confirm - Text for button confirms
     * cancel -  Text for button cancel
- }}
+
+    Example context (json):
+    {
+        "message": "Message",
+        "choices": [
+            { "value": "1", "text": "One" },
+            { "value": "2", "text": "Two" }
+        ],
+        "confirm": "Confirm",
+        "cancel": "Cancel"
+    }
+}}
 <div data-region="action-selector">
     <div data-region="action-selector-message">
        {{message}}<br>
     </div><br>
     <div data-region="action-selector-radio-buttons">
        {{#choices}}
-        <input id="action-selection-option-{{value}}" type="radio" name="choice" value="{{value}}"/><label for="action-selection-option-{{value}}">{{text}}</label><br>
+        <input id="action-selection-option-{{value}}" type="radio" class="m-r-1" name="choice" value="{{value}}"/><label for="action-selection-option-{{value}}">{{text}}</label><br>
        {{/choices}}
     </div><br>
     <div data-region="action_selector-buttons">
-       <input type="button" data-action="action-selector-confirm" value="{{confirm}}"/>
-       <input type="button" data-action="action-selector-cancel" value="{{cancel}}"/>
+       <input type="button" data-action="action-selector-confirm" class="btn btn-primary" value="{{confirm}}"/>
+       <input type="button" data-action="action-selector-cancel" class="btn btn-secondary" value="{{cancel}}"/>
     </div>
 </div>
index e2ac064..a93697a 100644 (file)
@@ -45,6 +45,7 @@
     * template
     * uniqid
 
+    // This template has no example context because it would trigger real updates to the DB.
     Example context (json):
     {
     }
index d6ae8e6..06b5e24 100644 (file)
@@ -15,6 +15,8 @@
     along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 }}
 {{!
+    @template tool_lp/competencies_move_tree
+
     Manage competencies template.
 
     Classes required for JS:
     Context variables required for this template:
     * framework -
     * competencies - array of objects containing id, shortname, idnumber, sortorder, parentid, competencyframeworkid, path
+
+    Example context (json):
+    {
+        "framework": {
+            "shortname":"framework"
+        },
+        "competencies": [
+            { "name": "Competency", "id": 1 }
+        ]
+    }
 }}
 <div data-region="competencymovetree" >
 <label>{{#str}}selectcompetencymovetarget, tool_lp{{/str}}</label>
@@ -41,7 +53,8 @@
 </ul>
 </div>
 
-<div data-region="move-buttons">
-    <input type="button" data-action="move" value="{{#str}}move{{/str}}"/>
-    <input type="button" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
+<div data-region="move-buttons" class="pull-xs-right">
+    <input type="button" data-action="move" class="btn btn-primary" value="{{#str}}move{{/str}}"/>
+    <input type="button" data-action="cancel" class="btn btn-secondary" value="{{#str}}cancel{{/str}}"/>
 </div>
+<div class="clearfix"></div>
index 75c2282..73ded30 100644 (file)
@@ -1,3 +1,54 @@
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/competencies_tree
+
+    Recursively build a competencies tree.
+
+    Classes required for JS:
+
+    Data attibutes required for JS:
+    * data-enhance=movetree
+
+    Context variables required for this template:
+    * id, shortname, idnumber, sortorder, parentid, competencyframeworkid, path, children
+
+    Example context (json):
+    {
+        "id": 1,
+        "shortname": "short",
+        "idnumber": "SHORT",
+        "sortorder": 1,
+        "parentid": 0,
+        "competencyframeworkid": 1,
+        "path": "/",
+        "haschildren": true,
+        "children": [{
+            "id": 2,
+            "shortname": "child",
+            "idnumber": "CHILD",
+            "sortorder": 1,
+            "parentid": 1,
+            "competencyframeworkid": 1,
+            "path": "/1/",
+            "children": []
+        }]
+    }
+}}
 <li data-id="{{id}}">
     {{#canmanage}}
     <span draggable="true">
index d138fe1..ed911f7 100644 (file)
@@ -1,4 +1,49 @@
-<ul data-enhance="tree">
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/competencies_tree_root
+
+    Recursively build a competencies tree.
+
+    Classes required for JS:
+
+    Data attibutes required for JS:
+    * data-enhance=movetree
+
+    Context variables required for this template:
+    * id, shortname, idnumber, sortorder, parentid, competencyframeworkid, path, children
+
+    Example context (json):
+    {
+        "shortname": "short",
+        "haschildren": true,
+        "competencies": [{
+            "id": 2,
+            "shortname": "child",
+            "idnumber": "CHILD",
+            "sortorder": 1,
+            "parentid": 1,
+            "competencyframeworkid": 1,
+            "path": "/1/",
+            "children": []
+        }]
+    }
+}}
+<ul data-enhance="tree" class="competency-tree">
     <li><span>{{{shortname}}}</span>
         <ul>
             {{#competencies}}
index 6b47042..20060b7 100644 (file)
@@ -1,26 +1,59 @@
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/competency_grader
+
+    Template for grading a competency.
+
+    Classes required for JS:
+      None
+
+    Data required for JS:
+    * ratings - list of value, name selected for valid ratings
+
+    Example context (json):
+    {
+        "ratings": [
+            {"name": "Bad", "value": 0, "selected": true},
+            {"name": "OK", "value": 1},
+            {"name": "Good", "value": 2}
+        ]
+    }
+}}
 <div class="competency-grader" data-region="competency-grader">
     <form>
         <div class="content">
             <div data-region="rating">
                 <label for="rating_{{uniqid}}">{{#str}}rating, tool_lp{{/str}}</label>
-                <select name="rating" id="rating_{{uniqid}}">
+                <select name="rating" id="rating_{{uniqid}}" class="custom-select">
                     {{#ratings}}
                         <option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
                     {{/ratings}}
                 </select>
             </div>
-            <div data-region="comment">
+            <div data-region="comment" class="m-t-1">
                 <label for="comment_{{uniqid}}">{{#str}}ratecomment, tool_lp{{/str}}</label>
-                <textarea name="comment" id="comment_{{uniqid}}"></textarea>
+                <textarea name="comment" id="comment_{{uniqid}}" class="form-control m-b-1"></textarea>
             </div>
         </div>
-        <div data-region="footer">
-            <div class="pull-right">
-                <input type="button" data-action="rate" value="{{#str}}rate, tool_lp{{/str}}" class="btn">
-            </div>
-            <div>
-                <button data-action="cancel" class="btn btn-link">{{#str}}cancel{{/str}}</button>
-            </div>
+        <div data-region="footer" class="pull-xs-right">
+            <input type="button" data-action="rate" value="{{#str}}rate, tool_lp{{/str}}" class="btn btn-primary">
+            <button data-action="cancel" class="btn btn-secondary">{{#str}}cancel{{/str}}</button>
         </div>
+        <div class="clearfix"></div>
     </form>
 </div>
index f756098..96afe15 100644 (file)
@@ -15,6 +15,8 @@
     along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 }}
 {{!
+    @template tool_lp/competency_path
+
     Competency path template.
 
     Classes required for JS:
     * framework - The competency framework
       * id - competency id
       * name - competency idnumber
-      * first - true if node is in first position
-      * last - true if node is in last position
-      * position - the position of the node in the list
 
     * ancestors - array of nodes
       * id - competency id
       * name - competency idnumber
       * first - true if node is in first position
       * last - true if node is in last position
-      * position - the position of the node in the list
 
     * pluginbaseurl - base url of plugin tool_lp
+
+    Example context (json):
+    {
+        "framework": {
+            "id": "1",
+            "name": "Framework"
+        },
+        "ancestors": [
+            {
+                "id": "1",
+                "name": "C1"
+            },
+            {
+                "id": "1",
+                "name": "C2",
+                "last": true
+            }
+        ]
+    }
 }}
 <nav id="competency-path-{{uniqid}}">
     <small>
index 916522b..f9693d0 100644 (file)
@@ -1,20 +1,75 @@
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/competency_picker
+
+    Show a competency tree and allow picking a competency.
+
+    Context variables required for this template:
+    * frameworks - array of competency framework
+      * id
+      * shortname
+      * idnumber
+      * selected
+
+    * framework - competency framework
+      * id
+      * name
+      * shortname
+      * idnumber
+
+    * competencies - array of nodes
+      * id - competency id
+      * name - competency idnumber
+      * children - array of children
+      * haschildren - boolean
+
+    Example context (json):
+    {
+        "frameworks": [
+            {
+                "id": "1",
+                "shortname": "Framework",
+                "idnumber": "F1"
+            }
+        ],
+        "competencies": [
+        ]
+    }
+}}
 <div data-region="competencylinktree">
 {{^singleFramework}}
 <h3>{{#str}}competencyframeworks, tool_lp{{/str}}</h3>
-<select data-action="chooseframework">
+<select data-action="chooseframework" class="custom-select">
 {{#frameworks}}
 <option value="{{id}}" {{#selected}}selected="selected"{{/selected}}>{{{shortname}}} <em>{{idnumber}}</em></option>
 {{/frameworks}}
 </select>
 {{/singleFramework}}
-<h3>{{#str}}locatecompetency, tool_lp{{/str}}</h3>
+<h3 class="m-t-1">{{#str}}locatecompetency, tool_lp{{/str}}</h3>
 
-<form data-region="filtercompetencies" data-frameworkid="{{framework.id}}">
-    <label class="accesshide" for="filter{{uniqid}}">{{#str}}search, tool_lp{{/str}}</label>
-    <input type="text" id="filter{{uniqid}}" placeholder="{{#str}}search, tool_lp{{/str}}" value="{{search}}">
-    <button>{{#pix}}a/search, ,{{#str}}search{{/str}}{{/pix}}</button>
+<form data-region="filtercompetencies" class="form-inline" data-frameworkid="{{framework.id}}">
+    <div class="form-group">
+        <label class="accesshide" for="filter{{uniqid}}">{{#str}}search, tool_lp{{/str}}</label>
+        <input type="text" class="form-control" id="filter{{uniqid}}" placeholder="{{#str}}search, tool_lp{{/str}}" value="{{search}}">
+        <button class="btn btn-secondary">{{#pix}}a/search, ,{{#str}}search{{/str}}{{/pix}}</button>
+    </div>
 </form>
-<ul data-enhance="linktree" style="display: none;">
+<ul data-enhance="linktree" style="display: none;" class="m-t-1 competency-tree">
     <li><span>{{{framework.shortname}}}</span>
         <ul>
             {{#competencies}}
@@ -23,8 +78,9 @@
         </ul>
     </li>
 </ul>
-<div data-region="link-buttons">
-    <input type="button" data-action="add" value="{{#str}}add{{/str}}"/>
-    <input type="button" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
+<div data-region="link-buttons" class="m-t-1 pull-xs-right">
+    <input type="button" class="btn btn-primary" data-action="add" value="{{#str}}add{{/str}}"/>
+    <input type="button" class="btn btn-secondary" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
 </div>
+<div class="clearfix"></div>
 </div>
index e255dfd..08b38ef 100644 (file)
@@ -1,12 +1,57 @@
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/competency_picker_competencyform
+
+    Show a competency tree and allow picking a competency.
+
+    Context variables required for this template:
+    * framework - The competency framework
+      * id
+      * name
+      * shortname
+
+    * competencies - array of nodes
+      * id - competency id
+      * name - competency idnumber
+      * children - array of children
+      * haschildren - boolean
+
+    Example context (json):
+    {
+        "framework": {
+            "id": "1",
+            "name": "Framework"
+        },
+        "competencies": [
+        ]
+    }
+}}
 <div data-region="competencylinktree">
 <h3>{{#str}}locatecompetency, tool_lp{{/str}}</h3>
 
-<form data-region="filtercompetencies" data-frameworkid="{{framework.id}}">
-    <label class="accesshide" for="filter{{uniqid}}">{{#str}}search, tool_lp{{/str}}</label>
-    <input type="text" id="filter{{uniqid}}" placeholder="{{#str}}search, tool_lp{{/str}}" value="{{search}}">
-    <button>{{#pix}}a/search, ,{{#str}}search{{/str}}{{/pix}}</button>
+<form data-region="filtercompetencies" class="form-inline" data-frameworkid="{{framework.id}}">
+    <div class="form-group">
+        <label class="accesshide" for="filter{{uniqid}}">{{#str}}search, tool_lp{{/str}}</label>
+        <input type="text" class="form-control" id="filter{{uniqid}}" placeholder="{{#str}}search, tool_lp{{/str}}" value="{{search}}">
+        <button class="btn btn-secondary">{{#pix}}a/search, ,{{#str}}search{{/str}}{{/pix}}</button>
+    </div>
 </form>
-<ul data-enhance="linktree" style="display: none;">
+<ul data-enhance="linktree" style="display: none;" class="m-t-1 competency-tree">
     <li data-id="0"><span>{{{framework.shortname}}}</span>
         <ul>
             {{#competencies}}
@@ -15,8 +60,9 @@
         </ul>
     </li>
 </ul>
-<div data-region="link-buttons">
-    <input type="button" data-action="add" value="{{#str}}select{{/str}}"/>
-    <input type="button" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
+<div data-region="link-buttons" class="m-t-1 pull-xs-right">
+    <input type="button" class="btn btn-primary" data-action="add" value="{{#str}}select{{/str}}"/>
+    <input type="button" class="btn btn-secondary" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
 </div>
+<div class="clearfix"></div>
 </div>
index bddebc9..7ee035d 100644 (file)
@@ -1,22 +1,80 @@
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/competency_picker_user_plans
+
+    Show a competency tree and allow picking a competency.
+
+    Context variables required for this template:
+    * singlePlan - boolean
+
+    * plans - array of plans
+      * id
+      * selected
+      * name
+
+    * plan
+      * id
+      * name
+
+    * competencies - array of nodes
+      * id - competency id
+      * name - competency idnumber
+      * children - array of children
+      * haschildren - boolean
+
+    Example context (json):
+    {
+        "singlePlan": false,
+        "plans": [
+            {
+                "id": "1",
+                "name": "Plan"
+            }
+        ],
+        "plan": {
+            "id": "1",
+            "name": "Plan"
+        },
+        "competencies": []
+    }
+}}
+
 <div data-region="competencylinktree">
 {{^singlePlan}}
     <h3>{{#str}}learningplans, tool_lp{{/str}}</h3>
-    <select data-action="chooseplan">
+    <select data-action="chooseplan" class="custom-select">
     {{#plans}}
         <option value="{{id}}" {{#selected}}selected="selected"{{/selected}}>{{{name}}}</option>
     {{/plans}}
     </select>
 {{/singlePlan}}
 
-<h3>{{#str}}locatecompetency, tool_lp{{/str}}</h3>
+<h3 class="m-t-1">{{#str}}locatecompetency, tool_lp{{/str}}</h3>
 
-<form data-region="filtercompetencies" data-planid="{{plan.id}}">
-    <label class="accesshide" for="filter{{uniqid}}">{{#str}}search, tool_lp{{/str}}</label>
-    <input type="text" id="filter{{uniqid}}" placeholder="{{#str}}search, tool_lp{{/str}}" value="{{search}}">
-    <button>{{#pix}}a/search, ,{{#str}}search{{/str}}{{/pix}}</button>
+<form data-region="filtercompetencies" data-planid="{{plan.id}}" class="form-inline">
+    <div class="form-group">
+        <label class="accesshide" for="filter{{uniqid}}">{{#str}}search, tool_lp{{/str}}</label>
+        <input type="text" class="form-control" id="filter{{uniqid}}" placeholder="{{#str}}search, tool_lp{{/str}}" value="{{search}}">
+        <button class="btn btn-secondary">{{#pix}}a/search, ,{{#str}}search{{/str}}{{/pix}}</button>
+    </div>
 </form>
 
-<ul data-enhance="linktree" style="display: none;">
+<ul data-enhance="linktree" style="display: none;" class="m-t-1 competency-tree">
     <li><span>{{{plan.name}}}</span>
         <ul>
             {{#competencies}}
@@ -26,9 +84,9 @@
     </li>
 </ul>
 
-<div data-region="link-buttons">
-    <input type="button" data-action="add" value="{{#str}}add{{/str}}"/>
-    <input type="button" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
+<div data-region="link-buttons" class="m-t-1 pull-xs-right">
+    <input type="button" class="btn btn-primary" data-action="add" value="{{#str}}add{{/str}}"/>
+    <input type="button" class="btn btn-secondary" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
 </div>
-
+<div class="clearfix"></div>
 </div>
index d3eb766..21bd7af 100644 (file)
@@ -1,4 +1,38 @@
-<div class="pull-right well">
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/competency_plan_navigation
+
+    Show an auto-complete for jumping to competencies in a plan.
+
+    Context variables required for this template:
+    * hascompetencies - boolean
+    * competencies - array of competencies
+      * id
+      * shortname
+      * idnumber
+      * selected
+    * userid
+    * competencyid
+    * planid
+
+    // No example context because the JS is connected to webservices
+}}
+<div class="pull-xs-right card card-block">
 {{#hascompetencies}}
 <span>
 <label for="competency-nav-{{uniqid}}" class="accesshide">{{#str}}jumptocompetency, tool_lp{{/str}}</label>
@@ -9,7 +43,6 @@
 </select>
 </span>
 {{/hascompetencies}}
-</form>
 </div>
 {{#js}}
 require(['core/form-autocomplete', 'tool_lp/competency_plan_navigation'], function(autocomplete, nav) {
index 7c64ab6..b0e9db8 100644 (file)
@@ -1,3 +1,54 @@
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/competency_rule_config
+
+    Configuration dialogue for competency rules.
+
+    Context variables required for this template:
+    * config - boolean
+    * outcomes - array
+      * code
+      * name
+      * selected
+    * rules - array
+      * type
+      * name
+      * selected
+
+    Example context (json):
+    {
+        "config": true,
+        "outcomes": [
+            {
+                "code": "C1",
+                "name": "Complete",
+                "selected": true
+            }
+        ],
+        "rules": [
+            {
+                "type": "Type",
+                "name": "Something happens",
+                "selected": true
+            }
+        ]
+    }
+}}
 <div data-region="competencyruleconfig">
     <div data-region="content">
 
         {{/config}}
 
         {{#config}}
-        <div data-region="rule-base">
-            <div data-region="rule-outcome">
+        <div data-region="rule-base" class="form">
+            <div data-region="rule-outcome" class="form-group">
                 <label>{{#str}}outcome, tool_lp{{/str}}</label>
-                <select name="outcome" ng-label="{{#str}}outcome, tool_lp{{/str}}">
+                <select name="outcome" class="custom-select" ng-label="{{#str}}outcome, tool_lp{{/str}}">
                     {{#outcomes}}
                     <option value="{{code}}" {{#selected}}selected{{/selected}}>{{name}}</option>
                     {{/outcomes}}
                 </select>
             </div>
-            <div data-region="rule-type">
+            <div data-region="rule-type" class="form-group">
                 <label>{{#str}}when, tool_lp{{/str}}</label>
-                <select name="rule" ng-label="{{#str}}when, tool_lp{{/str}}">
+                <select name="rule" class="custom-select" ng-label="{{#str}}when, tool_lp{{/str}}">
                     <option value="-1">{{#str}}choosedots{{/str}}</option>
                     {{#rules}}
                     <option value="{{type}}" {{#selected}}selected{{/selected}}>{{name}}</option>
         {{/config}}
     </div>
 
-    <div data-region="footer">
+    <div data-region="footer" class="pull-xs-right">
         {{#config}}
-        <input type="button" data-action="save" value="{{#str}}savechanges{{/str}}"/>
+        <input type="button" class="btn btn-primary" data-action="save" value="{{#str}}savechanges{{/str}}"/>
         {{/config}}
-        <input type="button" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
+        <input type="button" class="btn btn-secondary" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
     </div>
 </div>
index 907e731..07e4392 100644 (file)
@@ -1,3 +1,43 @@
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/competency_rule_points
+
+    Configuration dialogue for competency points rule.
+
+    Context variables required for this template:
+    * children
+      * id
+      * shortname
+      * points
+    * requiredpoints
+
+    Example context (json):
+    {
+        "children": [
+            {
+                "id": "1",
+                "shortname": "Competency",
+                "points": 2
+            }
+        ],
+        "requiredpoints": 4
+    }
+}}
 <div class="competency-rule-points">
     <table class="table table-condensed">
         <thead>
@@ -13,7 +53,7 @@
                 <th scope="row">{{{shortname}}}</th>
                 <td>
                     <label class="accesshide" for="pointsforcompetency-{{id}}">{{#str}}pointsgivenfor, tool_lp, {{{competency.shortname}}}{{/str}}</label>
-                    <input id="pointsforcompetency-{{id}}" type="number" min="0" value="{{points}}" name="points" />
+                    <input id="pointsforcompetency-{{id}}" type="number" min="0" value="{{points}}" name="points" class="form-control"/>
                 </td>
                 <td>
                     <label class="accesshide" for="competency-{{id}}-isrequired">{{#str}}aisrequired, tool_lp, {{{competency.shortname}}}{{/str}}</label>
@@ -25,7 +65,7 @@
         <tfoot>
             <tr>
                 <th scope="row">{{#str}}totalrequiredtocomplete, tool_lp{{/str}}</th>
-                <td><input type="number" min="1" value="{{requiredpoints}}" name="requiredpoints" aria-label="{{#str}}totalrequiredtocomplete, tool_lp{{/str}}"></td>
+                <td><input type="number" min="1" value="{{requiredpoints}}" name="requiredpoints" aria-label="{{#str}}totalrequiredtocomplete, tool_lp{{/str}}" class="form-control"></td>
                 <td> </td>
             </tr>
         </tfoot>
index b1bca28..1ce22b1 100644 (file)
@@ -1,3 +1,53 @@
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/competency_summary
+
+    Summary of a competency
+
+    Context variables required for this template:
+    * competency
+      * id
+      * shortname
+      * idnumber
+      * description
+    * framework
+      * shortname
+    * comppath array of ancestors
+    * showrelatedcompetencies boolean
+    * related
+    * showrule boolean
+    * rule
+      * outcome
+      * type
+
+    Example context (json):
+    {
+        "competency": {
+            "id": 1,
+            "shortname": "C1",
+            "idnumber": "PATH",
+            "description": "Can do something"
+        },
+        "framework": {
+            "shortname": "F1"
+        }
+    }
+}}
 <div class='competency-heading'>
     <h4 id="competency_link_{{competency.id}}">{{{competency.shortname}}}
         <small>{{competency.idnumber}}</small>
index 674eed6..39b061e 100644 (file)
 }}
 {{!
     Course competencies template.
+
+    For a full list of the context for this template see the course_competencies_page renderable.
 }}
 <div data-region="coursecompetenciespage">
     <div data-region="actions" class="clearfix">
-        <div class="pull-left">
+        <div class="pull-xs-left">
             {{#canmanagecoursecompetencies}}
-                <button disabled>{{#str}}addcoursecompetencies, tool_lp{{/str}}</button>
+                <button class="btn btn-secondary" disabled>{{#str}}addcoursecompetencies, tool_lp{{/str}}</button>
             {{/canmanagecoursecompetencies}}
         </div>
     </div>
     <tr class="drag-samenode" data-id="{{competency.id}}">
     <td>
         {{#canmanagecoursecompetencies}}
-        <span class="drag-handlecontainer pull-left"></span>
-        <div class="pull-right">
+        <span class="drag-handlecontainer pull-xs-left"></span>
+        <div class="pull-xs-right">
             <a href="#" data-action="delete-competency-link" data-id="{{competency.id}}">
                 {{#pix}}t/delete, core, {{#str}}delete{{/str}}{{/pix}}
             </a>
         </div>
+        <div class="clearfix"></div>
         {{/canmanagecoursecompetencies}}
         {{#competency}}
             <a href="{{pluginbaseurl}}user_competency_in_course.php?courseid={{courseid}}&competencyid={{competency.id}}&userid={{gradableuserid}}"
@@ -71,7 +74,7 @@
             <p>{{{competency.description}}}</p>
         {{/competency}}
         {{#comppath}}
-            <span class="pull-left">{{#str}}path, tool_lp{{/str}}&nbsp;</span>{{> tool_lp/competency_path }}
+            <span class="pull-xs-left">{{#str}}path, tool_lp{{/str}}&nbsp;</span>{{> tool_lp/competency_path }}
         {{/comppath}}
         {{#usercompetencycourse}}
             {{#grade}}
         {{/canmanagecoursecompetencies}}
         <div data-region="coursecompetencyactivities">
         <p>
-        <ul class="inline">
+        <ul class="inline list-inline">
         {{#coursemodules}}
-            <li><a href="{{url}}"><img src="{{iconurl}}"> {{name}} </a></li>
+            <li class="list-inline-item"><a href="{{url}}"><img src="{{iconurl}}"> {{name}} </a></li>
         {{/coursemodules}}
         {{^coursemodules}}
-            <li><span class="alert">{{#str}}noactivities, tool_lp{{/str}}</span></li>
+            <li class="list-inline-item"><span class="alert">{{#str}}noactivities, tool_lp{{/str}}</span></li>
         {{/coursemodules}}
         </ul>
         </p>
index bc1e361..6992f7d 100644 (file)
@@ -1,3 +1,40 @@
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/course_competency_settings
+
+    Select an action to execute.
+
+    Classes required for JS:
+    * none
+
+    Data attibutes required for JS:
+    * none
+
+    Context variables required for this template:
+    * courseid
+    * pushratingstouserplans
+
+    Example context (json):
+    {
+        "pushratingstouserplans": false,
+        "courseid": -1
+    }
+}}
 <form data-region="coursecompetencysettings">
     <input type="hidden" name="courseid" value="{{courseid}}"/>
     <fieldset>
         </label>
 
     </fieldset>
-    <fieldset>
-        <center>
-        <input type="button" data-action="save" value="{{#str}}savechanges{{/str}}"/>
-        <input type="button" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
-        </center>
+    <fieldset class="pull-xs-right">
+        <input type="button" class="btn btn-primary" data-action="save" value="{{#str}}savechanges{{/str}}"/>
+        <input type="button" class="btn btn-secondary" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
     </fieldset>
+    <div class="clearfix"></div>
 </form>
index bb4a267..9891b57 100644 (file)
     Example context (json):
     {
         "competencycount": 4,
+        "canbegradedincourse": true,
+        "canmanagecoursecompetencies": true,
         "proficientcompetencycount": 3,
         "proficientcompetencypercentage": 75,
-        "proficientcompetencypercentageformatted": 75.0
+        "proficientcompetencypercentageformatted": 75.0,
+        "leastproficientcount": 1,
+        "leastproficient": [
+            { "id": 1, "shortname": "Comp 1", "idnumber": "C1" }
+        ]
     }
 
 }}
index 64f1bc6..128fd9c 100644 (file)
@@ -46,7 +46,7 @@
 }}
 <div class="well well-small evidence" data-region="evidence" data-id="{{id}}">
     {{#candelete}}
-        <div class="pull-right">
+        <div class="pull-xs-right">
             <a href="#" data-action="delete-evidence">{{#pix}}t/delete{{/pix}}</a>
         </div>
     {{/candelete}}
@@ -57,7 +57,7 @@
 {{/actionuser}}
 <strong><time datetime="{{userdate}}">{{userdate}}</time></strong>
 {{#grade}}
-    <p><span class="label">{{gradename}}</span></p>
+    <p><span class="tag tag-info">{{gradename}}</span></p>
 {{/grade}}
 <p>{{description}}</p>
 {{#note}}
index 7208304..2e65cdb 100644 (file)
@@ -1,3 +1,48 @@
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/linked_courses_summary
+
+    Moodle template for the list of linked courses to a competency
+
+    Classes required for JS:
+    * none
+
+    Data attributes required for JS:
+    * none
+
+    Context variables required for this template:
+    * courses array
+      * viewurl
+      * fullname
+      * shortname
+
+    Example context (json):
+    { "courses":
+        [
+            {
+                "viewurl": "http://example.com",
+                "fullname": "Course 1",
+                "shortname": "C1"
+            }
+        ]
+    }
+}}
+
 <p>
 {{#str}}coursesusingthiscompetency, tool_lp{{/str}}
 </p>
index fce2b3d..8349d31 100644 (file)
     {{/canmanage}}
 </h2>
 <div>{{{framework.description}}}</div>
-<h3>{{#str}}competencies, core_competency{{/str}}</h3>
-<div class="row-fluid">
-<div class="span6">
-<p>
-<form data-region="filtercompetencies" data-frameworkid="{{framework.id}}">
-    <label class="accesshide" for="filter{{uniqid}}">{{#str}}search, tool_lp{{/str}}</label>
-    <input type="text" id="filter{{uniqid}}" placeholder="{{#str}}search, tool_lp{{/str}}" value="{{search}}">
-    <button>{{#pix}}a/search, , {{#str}}search{{/str}}{{/pix}}</button>
-</form>
-</p>
-<ul data-enhance="tree">
-    {{> tool_lp/loading }}
-</ul>
-</div>
-
-<div class="span6 well">
-<h4 data-region="selected-competency">{{#str}}selectedcompetency, tool_lp{{/str}}</h4>
-<p data-region="competencyinfo">
-{{#str}}nocompetencyselected, tool_lp{{/str}}
-</p>
-{{#canmanage}}
-<div data-region="competencyactions">
-<button class="btn" data-action="add">{{#pix}}t/add{{/pix}} <span data-region="term"></span></button>
-            <span data-region="competencyactionsmenu">
-            <ul title="{{#str}}edit{{/str}}" class="competencyactionsmenu">
-                <li>
-                    <a href="#">{{#str}}edit{{/str}}</a><b class="caret"></b>
-                    <ul class="dropdown-menu">
-                        <li>
-                            <a href="#" data-action="edit">
-                                {{#pix}}t/edit{{/pix}} {{#str}}edit{{/str}}
-                            </a>
-                        </li>
-                        <li>
-                            <a href="#" data-action="move">
-                                {{#pix}}t/move{{/pix}} {{#str}}movetonewparent, tool_lp{{/str}}
-                            </a>
-                        </li>
-                        <li>
-                            <a href="#" data-action="delete">
-                                {{#pix}}t/delete{{/pix}} {{#str}}delete{{/str}}
-                            </a>
-                        </li>
-                        <li>
-                            <a href="#" data-action="moveup">
-                                {{#pix}}t/up{{/pix}} {{#str}}moveup{{/str}}
-                            </a>
-                        </li>
-                        <li>
-                            <a href="#" data-action="movedown">
-                                {{#pix}}t/down{{/pix}} {{#str}}movedown{{/str}}
-                            </a>
-                        </li>
-                        <li>
-                            <a href="#" data-action="linkedcourses">
-                                {{#pix}}t/viewdetails{{/pix}} {{#str}}linkedcourses, tool_lp{{/str}}
-                            </a>
-                        </li>
-                        <li>
-                            <a href="#" data-action="relatedcompetencies">
-                                {{#pix}}t/add{{/pix}} {{#str}}addcrossreferencedcompetency, tool_lp{{/str}}
-                            </a>
-                        </li>
-                        <li>
-                            <a href="#" data-action="competencyrules">
-                                {{#pix}}t/edit{{/pix}} {{#str}}competencyrule, tool_lp{{/str}}
-                            </a>
-                        </li>
-                    </ul>
-                </li>
+    <h3>{{#str}}competencies, core_competency{{/str}}</h3>
+    <div class="row-fluid">
+        <div class="span6 col-lg-6">
+            <p>
+                <form data-region="filtercompetencies" data-frameworkid="{{framework.id}}" class="form-inline">
+                    <div class="form-group">
+                        <label class="accesshide" for="filter{{uniqid}}">{{#str}}search, tool_lp{{/str}}</label>
+                        <input class="form-control" type="text" id="filter{{uniqid}}" placeholder="{{#str}}search, tool_lp{{/str}}" value="{{search}}">
+                        <button class="btn btn-secondary">{{#pix}}a/search, , {{#str}}search{{/str}}{{/pix}}</button>
+                    </div>
+                </form>
+            </p>
+            <ul data-enhance="tree" class="competency-tree">
+                {{> tool_lp/loading }}
             </ul>
-            </span>
-</div>
-</div>
-{{/canmanage}}
+        </div>
+
+        <div class="span6 card col-lg-6">
+            <div class="card-block">
+                <div class="card-title">
+                    <h4 data-region="selected-competency">{{#str}}selectedcompetency, tool_lp{{/str}}</h4>
+                        <span data-region="competencyactionsmenu" class="pull-xs-right">
+                            <ul title="{{#str}}edit{{/str}}" class="competencyactionsmenu">
+                                <li>
+                                    <a href="#">{{#str}}edit{{/str}}</a><b class="caret"></b>
+                                    <ul class="dropdown-menu">
+                                    <li class="dropdown-item">
+                                        <a href="#" data-action="edit">
+                                            {{#pix}}t/edit{{/pix}} {{#str}}edit{{/str}}
+                                        </a>
+                                    </li>
+                                    <li class="dropdown-item">
+                                        <a href="#" data-action="move">
+                                            {{#pix}}t/move{{/pix}} {{#str}}movetonewparent, tool_lp{{/str}}
+                                        </a>
+                                    </li>
+                                    <li class="dropdown-item">
+                                        <a href="#" data-action="delete">
+                                            {{#pix}}t/delete{{/pix}} {{#str}}delete{{/str}}
+                                        </a>
+                                    </li>
+                                    <li class="dropdown-item">
+                                        <a href="#" data-action="moveup">
+                                            {{#pix}}t/up{{/pix}} {{#str}}moveup{{/str}}
+                                        </a>
+                                    </li>
+                                    <li class="dropdown-item">
+                                        <a href="#" data-action="movedown">
+                                            {{#pix}}t/down{{/pix}} {{#str}}movedown{{/str}}
+                                        </a>
+                                    </li>
+                                    <li class="dropdown-item">
+                                        <a href="#" data-action="linkedcourses">
+                                            {{#pix}}t/viewdetails{{/pix}} {{#str}}linkedcourses, tool_lp{{/str}}
+                                        </a>
+                                    </li>
+                                    <li class="dropdown-item">
+                                        <a href="#" data-action="relatedcompetencies">
+                                            {{#pix}}t/add{{/pix}} {{#str}}addcrossreferencedcompetency, tool_lp{{/str}}
+                                        </a>
+                                    </li>
+                                    <li class="dropdown-item">
+                                        <a href="#" data-action="competencyrules">
+                                            {{#pix}}t/edit{{/pix}} {{#str}}competencyrule, tool_lp{{/str}}
+                                        </a>
+                                    </li>
+                                </ul>
+                            </li>
+                        </ul>
+                    </span>
+                </div>
+                <p data-region="competencyinfo">
+                    {{#str}}nocompetencyselected, tool_lp{{/str}}
+                </p>
+                {{#canmanage}}
+                <div data-region="competencyactions">
+                    <button class="btn btn-secondary" data-action="add">{{#pix}}t/add{{/pix}} <span data-region="term"></span></button>
+                </div>
+                {{/canmanage}}
+            </div>
+        </div>
+    </div>
 </div>
 
 {{#js}}
@@ -131,4 +138,3 @@ require(['tool_lp/tree', 'tool_lp/competencytree', 'tool_lp/competencyactions',
 });
 {{/js}}
 
-</div>
index a901f4a..f3d6a3e 100644 (file)
                 <li>
                     <a href="#">{{#str}}edit{{/str}}</a><b class="caret"></b>
                     <ul class="dropdown-menu">
-                        <li>
+                        <li class="dropdown-item">
                             <a href="{{pluginbaseurl}}/editcompetencyframework.php?id={{id}}&amp;pagecontextid={{pagecontextid}}">
                                 {{#pix}}t/edit{{/pix}} {{#str}}edit{{/str}}
                             </a>
                         </li>
-                        <li>
+                        <li class="dropdown-item">
                             <a data-action="duplicatecompetencyframework" href="#" data-frameworkid="{{id}}">
                                 {{#pix}}t/copy{{/pix}} {{#str}}duplicate{{/str}}
                             </a>
                         </li>
-                        <li>
+                        <li class="dropdown-item">
                             <a data-action="deletecompetencyframework" href="#" data-frameworkid="{{id}}">
                                 {{#pix}}t/delete{{/pix}} {{#str}}delete{{/str}}
                             </a>
index fbe00d6..f0af972 100644 (file)
                 <li>
                     <a href="#">{{#str}}edit{{/str}}</a><b class="caret"></b>
                     <ul class="dropdown-menu">
-                        <li>
+                        <li class="dropdown-item">
                             <a href="{{pluginbaseurl}}/edittemplate.php?id={{id}}&amp;pagecontextid={{pagecontextid}}&amp;return=templates">
                                 {{#pix}}t/edit{{/pix}} {{#str}}edit{{/str}}
                             </a>
                         </li>
-                        <li>
+                        <li class="dropdown-item">
                             <a data-action="duplicatetemplate" data-templateid="{{id}}" href="#">
                                 {{#pix}}t/copy{{/pix}} {{#str}}duplicate{{/str}}
                             </a>
                         </li>
-                        <li>
+                        <li class="dropdown-item">
                             <a href="{{pluginbaseurl}}/template_plans.php?id={{id}}&amp;pagecontextid={{pagecontextid}}">
                                 {{#pix}}t/add{{/pix}} {{#str}}createlearningplans, tool_lp{{/str}}
                             </a>
                         </li>
-                        <li>
+                        <li class="dropdown-item">
                             <a href="{{pluginbaseurl}}/template_cohorts.php?id={{id}}&amp;pagecontextid={{pagecontextid}}">
                                 {{#pix}}t/add{{/pix}} {{#str}}addcohortstosync, tool_lp{{/str}}
                             </a>
                         </li>
-                        <li>
+                        <li class="dropdown-item">
                             <a data-action="deletetemplate" data-templateid="{{id}}" href="#">
                                 {{#pix}}t/delete{{/pix}} {{#str}}delete{{/str}}
                             </a>
index 40eced3..a606c48 100644 (file)
@@ -1,3 +1,33 @@
-<p class="alert alert-error">
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/no_frameworks_warning
+
+    No frameworks warning template.
+
+    Classes required for JS:
+      None
+
+    Context variables required for this template:
+      None
+    Example context (json):
+    {
+    }
+}}
+<p class="alert alert-danger">
     {{#str}}nocompetencyframeworks, tool_lp{{/str}}
 </p>
index 20eb2bb..d927eae 100644 (file)
     <div data-region="actions" class="clearfix">
         <div class="pull-left">
             <!-- Button to add competencies to the plan -->
-            <button class="btn" data-action="add">{{#pix}}t/add{{/pix}} {{#str}}addcompetency, tool_lp{{/str}}</button>
+            <button class="btn btn-secondary" data-action="add">{{#pix}}t/add{{/pix}} {{#str}}addcompetency, tool_lp{{/str}}</button>
         </div>
     </div>
     {{/plan.canbeedited}}
-    <div data-region="plan-summary">
+    <div data-region="plan-summary" class="m-t-1">
         {{{plan.description}}}
         <dl>
             <dt>{{#str}}status, tool_lp{{/str}}</dt>
     </div>
     {{#plan.commentarea}}
         {{#canpostorhascomments}}
-            <div data-region="comments">
+            <div data-region="comments" class="m-t-1">
                 {{>tool_lp/comment_area}}
             </div>
         {{/canpostorhascomments}}
     {{/plan.commentarea}}
-    <div data-region="plan-competencies">
+    <div data-region="plan-competencies" class="m-t-1">
         <h3>{{#str}}learningplancompetencies, tool_lp{{/str}}</h3>
         <table class="generaltable fullwidth managecompetencies">
             <thead>
                                     <a href="#">{{#str}}edit{{/str}}</a><b class="caret"></b>
                                     <ul class="dropdown-menu">
                                         {{#usercompetency.isrequestreviewallowed}}
-                                            <li>
+                                            <li class="dropdown-item">
                                                 <a href="#" data-action="request-review">{{#pix}}t/edit, core{{/pix}} {{#str}}requestreview, tool_lp{{/str}}</a>
                                             </li>
                                         {{/usercompetency.isrequestreviewallowed}}
                                         {{#usercompetency.iscancelreviewrequestallowed}}
-                                            <li>
+                                            <li class="dropdown-item">
                                                 <a href="#" data-action="cancel-review-request">{{#pix}}t/edit, core{{/pix}} {{#str}}cancelreviewrequest, tool_lp{{/str}}</a>
                                             </li>
                                         {{/usercompetency.iscancelreviewrequestallowed}}
                                         {{#plan.canbeedited}}
-                                            <li>
+                                            <li class="dropdown-item">
                                                 <a href="#" data-action="delete-competency-link" data-id="{{competency.id}}">{{#pix}}t/delete, core{{/pix}} {{#str}}delete{{/str}}</a>
                                             </li>
                                         {{/plan.canbeedited}}
-                                        <li>
+                                        <li class="dropdown-item">
                                             <a href="#" data-action="find-courses-link" data-id="{{competency.id}}">{{#pix}}t/preview, core{{/pix}} {{#str}}findcourses, tool_lp{{/str}}</a>
                                         </li>
                                     </ul>
index 94226c9..84a4b66 100644 (file)
@@ -71,7 +71,7 @@
                 <li>
                     <a href="#">{{#str}}edit{{/str}}</a><b class="caret"></b>
                     <ul class="dropdown-menu">
-                    <li {{^canbeedited}} class="disabled" {{/canbeedited}}>
+                    <li class="{{^canbeedited}} disabled {{/canbeedited}} dropdown-item">
                         <a href="{{#canbeedited}}
                                     {{pluginbaseurl}}/editplan.php?id={{id}}&amp;userid={{userid}}&amp;return=plans
                                  {{/canbeedited}}
                         </a>
                     </li>
                     {{#isreopenallowed}}
-                    <li>
+                    <li class="dropdown-item">
                         <a data-action="plan-reopen" href="#">
                             {{#pix}}t/edit{{/pix}} {{#str}}reopenplan, tool_lp{{/str}}
                         </a>
                     </li>
                     {{/isreopenallowed}}
                     {{#iscompleteallowed}}
-                    <li>
+                    <li class="dropdown-item">
                         <a data-action="plan-complete" href="#">
                             {{#pix}}t/edit{{/pix}} {{#str}}completeplan, tool_lp{{/str}}
                         </a>
                     </li>
                     {{/iscompleteallowed}}
                     {{#isrequestreviewallowed}}
-                    <li>
+                    <li class="dropdown-item">
                         <a data-action="plan-request-review" href="#">{{#pix}}t/edit{{/pix}} {{#str}}requestreview, tool_lp{{/str}}</a>
                     </li>
                     {{/isrequestreviewallowed}}
                     {{#iscancelreviewrequestallowed}}
-                    <li>
+                    <li class="dropdown-item">
                         <a data-action="plan-cancel-review-request" href="#">{{#pix}}t/edit{{/pix}} {{#str}}cancelreviewrequest, tool_lp{{/str}}</a>
                     </li>
                     {{/iscancelreviewrequestallowed}}
                     {{#isstartreviewallowed}}
-                    <li>
+                    <li class="dropdown-item">
                         <a data-action="plan-start-review" href="#">{{#pix}}t/edit{{/pix}} {{#str}}startreview, tool_lp{{/str}}</a>
                     </li>
                     {{/isstartreviewallowed}}
                     {{#isstopreviewallowed}}
-                    <li>
+                    <li class="dropdown-item">
                         <a data-action="plan-stop-review" href="#">{{#pix}}t/edit{{/pix}} {{#str}}stopreview, tool_lp{{/str}}</a>
                     </li>
                     {{/isstopreviewallowed}}
                     {{#isapproveallowed}}
-                    <li>
+                    <li class="dropdown-item">
                         <a data-action="plan-approve" href="#">{{#pix}}t/edit{{/pix}} {{#str}}planapprove, tool_lp{{/str}}</a>
                     </li>
                     {{/isapproveallowed}}
                     {{#isunapproveallowed}}
-                    <li>
+                    <li class="dropdown-item">
                         <a data-action="plan-unapprove" href="#">{{#pix}}t/edit{{/pix}} {{#str}}planunapprove, tool_lp{{/str}}</a>
                     </li>
                     {{/isunapproveallowed}}
                     {{#isunlinkallowed}}
-                    <li>
+                    <li class="dropdown-item">
                         <a data-action="plan-unlink" href="#">
                             {{#pix}}t/edit{{/pix}} {{#str}}unlinkplantemplate, tool_lp{{/str}}
                         </a>
                     </li>
                     {{/isunlinkallowed}}
-                    <li>
+                    <li class="dropdown-item">
                         <a data-action="plan-delete" href="#">
                             {{#pix}}t/delete{{/pix}} {{#str}}deletethisplan, tool_lp{{/str}}
                         </a>
 {{#js}}
 // Initialise the JS.
 require(['tool_lp/planactions'],
-        function(actionsMod) {
+        function(ActionsMod) {
 
-    var planActions = new actionsMod('plans');
+    var planActions = new ActionsMod('plans');
     planActions.enhanceMenubar('.planactions');
 });
 
index 71967d7..ab5d991 100644 (file)
@@ -1,3 +1,51 @@
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/related_competencies
+
+    List of related competencies.
+
+    Classes required for JS:
+    * none
+
+    Data attributes required for JS:
+    * none
+
+    Context variables required for this template:
+    * showdeleterelatedaction boolean
+    * relatedcompetencies array
+      * id int
+      * shortname string
+      * idnumber string
+
+    Example context (json):
+    {
+        "showdeleterelatedaction": false,
+        "relatedcompetencies":
+        [
+            {
+                "id": 1,
+                "shortname": "Competency",
+                "idnumber": "C1"
+            }
+        ]
+    }
+
+}}
 <div data-region="relatedcompetencies">
 <p>
     <strong>{{#str}}crossreferencedcompetencies, tool_lp{{/str}}:</strong>
@@ -6,7 +54,7 @@
     {{#relatedcompetencies}}
         <li>
             {{#showdeleterelatedaction}}
-                <div class="pull-right">
+                <div class="pull-xs-right">
                     <a href="#" data-action="deleterelation" id="id-related-{{id}}">{{#pix}}t/delete, core, {{#str}}delete{{/str}}{{/pix}}</a>
                 </div>
             {{/showdeleterelatedaction}}
index 6b98119..3412c2e 100644 (file)
@@ -15,6 +15,8 @@
     along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 }}
 {{!
+    @template tool_lp/scale_configuration_page
+
     Set scale configuration for the competency framework.
 
     Classes required for JS:
@@ -30,7 +32,7 @@
     {
         "scales": [
             { "id": 1, "name": "Competent" },
-            { "id": 2, "name": "Not competent"}
+            { "id": 2, "name": "Not competent" }
         ]
     }
  }}
@@ -56,7 +58,8 @@
 </table>
 </div>
 
-<div data-region="scale-buttons">
-    <input type="button" data-action="close" value="{{#str}}closebuttontitle{{/str}}"/>
-    <input type="button" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
-</div>
\ No newline at end of file
+<div data-region="scale-buttons" class="m-t-1 pull-xs-right">
+    <input type="button" class="btn btn-secondary" data-action="close" value="{{#str}}closebuttontitle{{/str}}"/>
+    <input type="button" class="btn btn-secondary" data-action="cancel" value="{{#str}}cancel{{/str}}"/>
+</div>
+<div class="clearfix"></div>
index a2ebaef..a380d29 100644 (file)
     {{#canmanagetemplatecompetencies}}
     <div data-region="actions" class="clearfix">
         <div class="pull-left">
-            <button disabled>{{#str}}addtemplatecompetencies, tool_lp{{/str}}</button>
+            <button disabled class="btn btn-secondary">{{#str}}addtemplatecompetencies, tool_lp{{/str}}</button>
         </div>
     </div>
     {{/canmanagetemplatecompetencies}}
-    <h3>{{#str}}templatecompetencies, tool_lp{{/str}}</h3>
+    <h3 class="m-t-1">{{#str}}templatecompetencies, tool_lp{{/str}}</h3>
     {{#statistics}}
         {{> tool_lp/template_statistics }}
     {{/statistics}}
@@ -44,7 +44,7 @@
                     <div class="well">
                         {{#canmanagetemplatecompetencies}}
                         <span class="drag-handlecontainer pull-left"></span>
-                        <div class="pull-right">
+                        <div class="pull-xs-right">
                             <a href="#" data-action="delete-competency-link" data-id="{{competency.id}}">{{#pix}}t/delete, core, {{#str}}delete{{/str}}{{/pix}}</a>
                         </div>
                         {{/canmanagetemplatecompetencies}}
@@ -53,9 +53,9 @@
                         {{/competency}}
                         <strong>{{#str}}linkedcourseslist, tool_lp{{/str}}</strong>
                         {{#hascourses}}
-                        <ul class="inline">
+                        <ul class="inline list-inline">
                         {{#linkedcourses}}
-                            <li><a href="{{viewurl}}?id={{id}}">{{{fullname}}} ({{{shortname}}})</a></li>
+                            <li class="list-inline-item"><a href="{{viewurl}}?id={{id}}">{{{fullname}}} ({{{shortname}}})</a></li>
                         {{/linkedcourses}}
                         </ul>
                         {{/hascourses}}
index 85b738f..9751cbd 100644 (file)
@@ -45,7 +45,8 @@
     Template statistics template.
 }}
 {{#competencycount}}
-<div data-region="templatestatistics" class="well">
+<div data-region="templatestatistics" class="card">
+    <div class="card-block">
     {{< tool_lp/progress_bar}}
         {{$progresstext}}
             {{#str}}xcompetencieslinkedoutofy, tool_lp, { "x": "{{linkedcompetencycount}}", "y": "{{competencycount}}" } {{/str}}
@@ -89,5 +90,6 @@
         </div>
     </div>
     {{/leastproficientcount}}
+    </div>
 </div>
 {{/competencycount}}
index a81c0f8..533d01f 100644 (file)
@@ -1,4 +1,41 @@
-<div class="pull-right well">
+{{!
+    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/>.
+}}
+{{!
+    @template tool_lp/user_competency_course_navigation
+
+    Show an auto-complete for jumping to competencies in a plan.
+
+    Context variables required for this template:
+    * groupselector - HTML
+    * hasusers
+    * users - array
+      * id
+      * selected
+      * fullname
+    * hascompetencies
+    * competencies - array
+      * id
+      * selected
+      * shortname
+      * idnumber
+
+    // No example context because the JS is connected to webservices
+}}
+<div class="pull-xs-right card card-block">
 <p>{{{groupselector}}}</p>
 <form class="user-competency-course-navigation">
 {{#hasusers}}
index 9097caa..0e280f6 100644 (file)
                 - {{reviewer.fullname}}
             {{/isstatusinreview}}
 
-            {{#isrequestreviewallowed}}<button data-action="request-review">{{#str}}requestreview, tool_lp{{/str}}</button>{{/isrequestreviewallowed}}
-            {{#iscancelreviewrequestallowed}}<button data-action="cancel-review-request">{{#str}}cancelreviewrequest, tool_lp{{/str}}</button>{{/iscancelreviewrequestallowed}}
-            {{#isstartreviewallowed}}<button data-action="start-review">{{#str}}startreview, tool_lp{{/str}}</button>{{/isstartreviewallowed}}
-            {{#isstopreviewallowed}}<button data-action="stop-review">{{#str}}stopreview, tool_lp{{/str}}</button>{{/isstopreviewallowed}}
+            {{#isrequestreviewallowed}}<button class="btn btn-secondary" data-action="request-review">{{#str}}requestreview, tool_lp{{/str}}</button>{{/isrequestreviewallowed}}
+            {{#iscancelreviewrequestallowed}}<button class="btn btn-secondary" data-action="cancel-review-request">{{#str}}cancelreviewrequest, tool_lp{{/str}}</button>{{/iscancelreviewrequestallowed}}
+            {{#isstartreviewallowed}}<button class="btn btn-secondary" data-action="start-review">{{#str}}startreview, tool_lp{{/str}}</button>{{/isstartreviewallowed}}
+            {{#isstopreviewallowed}}<button class="btn btn-secondary" data-action="stop-review">{{#str}}stopreview, tool_lp{{/str}}</button>{{/isstopreviewallowed}}
         </dd>
         <dt>{{#str}}proficient, tool_lp{{/str}}</dt>
         <dd>
@@ -64,7 +64,7 @@
         <dt>{{#str}}rating, tool_lp{{/str}}</dt>
         <dd>{{gradename}}
             {{#cangrade}}
-                <button class="btn" id="rate_{{uniqid}}">{{#str}}rate, tool_lp{{/str}}</button>
+                <button class="btn btn-secondary" id="rate_{{uniqid}}">{{#str}}rate, tool_lp{{/str}}</button>
             {{/cangrade}}
         </dd>
         {{#js}}
index 3a30f76..22cf96d 100644 (file)
         <dt>{{#str}}activities, tool_lp{{/str}}</dt>
         <dd data-region="coursecompetencyactivities">
         <p>
-        <ul class="inline">
+        <ul class="inline list-inline">
         {{#coursemodules}}
-            <li><a href="{{url}}"><img src="{{iconurl}}"> {{name}} </a></li>
+            <li class="list-inline-item"><a href="{{url}}"><img src="{{iconurl}}"> {{name}} </a></li>
         {{/coursemodules}}
         {{^coursemodules}}
-            <li><span class="alert">{{#str}}noactivities, tool_lp{{/str}}</span></li>
+            <li class="list-inline-item"><span class="alert">{{#str}}noactivities, tool_lp{{/str}}</span></li>
         {{/coursemodules}}
         </ul>
         </p>
@@ -75,7 +75,7 @@
         <dt>{{#str}}rating, tool_lp{{/str}}</dt>
         <dd>{{gradename}}
             {{#cangrade}}
-                <button class="btn" id="rate_{{uniqid}}">{{#str}}rate, tool_lp{{/str}}</button>
+                <button class="btn btn-secondary" id="rate_{{uniqid}}">{{#str}}rate, tool_lp{{/str}}</button>
             {{/cangrade}}
         </dd>
         {{/usercompetencycourse}}
index 7c81ad2..7253af1 100644 (file)
                 - {{reviewer.fullname}}
             {{/isstatusinreview}}
 
-            {{#isrequestreviewallowed}}<button data-action="request-review">{{#str}}requestreview, tool_lp{{/str}}</button>{{/isrequestreviewallowed}}
-            {{#iscancelreviewrequestallowed}}<button data-action="cancel-review-request">{{#str}}cancelreviewrequest, tool_lp{{/str}}</button>{{/iscancelreviewrequestallowed}}
-            {{#isstartreviewallowed}}<button data-action="start-review">{{#str}}startreview, tool_lp{{/str}}</button>{{/isstartreviewallowed}}
-            {{#isstopreviewallowed}}<button data-action="stop-review">{{#str}}stopreview, tool_lp{{/str}}</button>{{/isstopreviewallowed}}
+            {{#isrequestreviewallowed}}<button class="btn btn-secondary" data-action="request-review">{{#str}}requestreview, tool_lp{{/str}}</button>{{/isrequestreviewallowed}}
+            {{#iscancelreviewrequestallowed}}<button class="btn btn-secondary" data-action="cancel-review-request">{{#str}}cancelreviewrequest, tool_lp{{/str}}</button>{{/iscancelreviewrequestallowed}}
+            {{#isstartreviewallowed}}<button class="btn btn-secondary" data-action="start-review">{{#str}}startreview, tool_lp{{/str}}</button>{{/isstartreviewallowed}}
+            {{#isstopreviewallowed}}<button class="btn btn-secondary" data-action="stop-review">{{#str}}stopreview, tool_lp{{/str}}</button>{{/isstopreviewallowed}}
         </dd>
         <dt>{{#str}}proficient, tool_lp{{/str}}</dt>
         <dd>
@@ -75,7 +75,7 @@
         <dt>{{#str}}rating, tool_lp{{/str}}</dt>
         <dd>{{gradename}}
             {{#cangrade}}
-                <button class="btn" id="rate_{{uniqid}}">{{#str}}rate, tool_lp{{/str}}</button>
+                <button class="btn btn-secondary" id="rate_{{uniqid}}">{{#str}}rate, tool_lp{{/str}}</button>
             {{/cangrade}}
         </dd>
         {{#js}}
index a0e14bf..d24f138 100644 (file)
                 <li>
                     <a href="#">{{#str}}edit{{/str}}</a><b class="caret"></b>
                     <ul class="dropdown-menu">
-                        <li>
+                        <li class="dropdown-item">
                             <a href="{{pluginbaseurl}}/user_evidence_edit.php?id={{id}}&amp;userid={{userid}}&amp;return=list">
                                 {{#pix}}t/edit{{/pix}} {{#str}}editthisuserevidence, tool_lp{{/str}}
                             </a>
                         </li>
                         {{#userhasplan}}
-                        <li>
+                        <li class="dropdown-item">
                             <a href="#" data-action="link-competency">
                                 {{#pix}}t/add{{/pix}} {{#str}}linkcompetencies, tool_lp{{/str}}
                             </a>
                         </li>
                         {{/userhasplan}}
-                        <li>
+                        <li class="dropdown-item">
                             <a data-action="send-competencies-review" href="#">
                                 {{#pix}}t/edit{{/pix}} {{#str}}sendcompetenciestoreview, tool_lp{{/str}}
                             </a>
                         </li>
-                        <li>
+                        <li class="dropdown-item">
                             <a data-action="user-evidence-delete" href="#">
                                 {{#pix}}t/delete{{/pix}} {{#str}}deletethisuserevidence, tool_lp{{/str}}
                             </a>
 {{#js}}
 require(['tool_lp/user_evidence_actions'], function(UserEvidenceActions) {
     var uea = new UserEvidenceActions('list');
-    uea.enhanceMenubar('.user-evidence-actions')
+    uea.enhanceMenubar('.user-evidence-actions');
 });
 {{/js}}
index 29f28cf..fca3723 100644 (file)
@@ -40,7 +40,7 @@
     <div data-region="actions" class="clearfix">
         <div class="pull-left">
             {{#userhasplan}}
-                <button class="btn" data-action="link-competency">{{#pix}}t/add{{/pix}} {{#str}}linkcompetencies, tool_lp{{/str}}</button>
+                <button class="btn btn-secondary m-b-1" data-action="link-competency">{{#pix}}t/add{{/pix}} {{#str}}linkcompetencies, tool_lp{{/str}}</button>
             {{/userhasplan}}
         </div>
     </div>
index 813b096..9064eb2 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['competencyscale'] = 'Competency Scale: {$a}';
+$string['competencyscale'] = 'Competency scale: {$a}';
 $string['competencyscaledescription'] = 'Competency scale created by import';
-$string['confirmcolumnmappings'] = 'Confirm the columns mappings';
+$string['confirmcolumnmappings'] = 'Confirm the column mappings';
 $string['confirm'] = 'Confirm';
 $string['csvdelimiter'] = 'CSV delimiter';
-$string['csvdelimiter_help'] = 'CSV delimiter of the CSV file.';
+$string['csvdelimiter_help'] = 'The CSV delimiter is normally a comma.';
 $string['description'] = 'Description';
 $string['descriptionformat'] = 'Description format';
 $string['encoding'] = 'Encoding';
-$string['encoding_help'] = 'Encoding of the CSV file.';
+$string['encoding_help'] = 'The CSV file encoding is usually UTF-8.';
 $string['export'] = 'Export';
-$string['exportid'] = 'Exported id (optional)';
+$string['exportid'] = 'Exported ID (optional)';
 $string['exportnavlink'] = 'Export competency framework';
-$string['idnumber'] = 'Id number';
+$string['idnumber'] = 'ID number';
 $string['importfile'] = 'CSV framework description file';
 $string['import'] = 'Import';
 $string['invalidimportfile'] = 'File format is invalid.';
 $string['isframework'] = 'Is framework';
 $string['noframeworks'] = 'No competency frameworks have been created yet';
-$string['parentidnumber'] = 'Parent id number';
+$string['parentidnumber'] = 'Parent ID number';
 $string['pluginname'] = 'Import competency framework';
-$string['relatedidnumbers'] = 'Cross referenced competency id numbers';
+$string['relatedidnumbers'] = 'Cross-referenced competency ID numbers';
 $string['ruleconfig'] = 'Rule config (optional)';
 $string['ruleoutcome'] = 'Rule outcome (optional)';
 $string['ruletype'] = 'Rule type (optional)';
 $string['scaleconfiguration'] = 'Scale configuration';
 $string['scalevalues'] = 'Scale values';
-$string['shortname'] = 'Shortname';
+$string['shortname'] = 'Short name';
 $string['taxonomy'] = 'Taxonomy';
index a5edea4..f9bfc3b 100644 (file)
@@ -36,16 +36,16 @@ $PAGE->set_url($url);
 $PAGE->set_title($title);
 $PAGE->set_heading(get_string('pluginname', 'tool_lpmigrate'));
 
-$output = $PAGE->get_renderer('tool_lpmigrate');
-
-echo $output->header();
-echo $output->heading($title);
-
 $form = new \tool_lpmigrate\form\migrate_framework($context);
 if ($form->is_cancelled()) {
     redirect($url);
+}
+
+$output = $PAGE->get_renderer('tool_lpmigrate');
+echo $output->header();
+echo $output->heading($title);
 
-} else if ($data = $form->get_data()) {
+if ($data = $form->get_data()) {
 
     // Map competencies from both framework.
     $mapper = new \tool_lpmigrate\framework_mapper($data->from, $data->to);
index a352f7c..fe33923 100644 (file)
@@ -920,7 +920,7 @@ class manager {
         $addressmanager->set_handler('\tool_messageinbound\message\inbound\invalid_recipient_handler');
         $addressmanager->set_data($record->id);
 
-        $eventdata = new \stdClass();
+        $eventdata = new \core\message\message();
         $eventdata->component           = 'tool_messageinbound';
         $eventdata->name                = 'invalidrecipienthandler';
 
@@ -930,7 +930,8 @@ class manager {
         $userfrom->customheaders[] = 'In-Reply-To: ' . $messageid;
 
         // The message will be sent from the intended user.
-        $eventdata->userfrom            = \core_user::get_support_user();
+        $eventdata->courseid            = SITEID;
+        $eventdata->userfrom            = \core_user::get_noreply_user();
         $eventdata->userto              = $USER;
         $eventdata->subject             = $this->get_reply_subject($this->currentmessagedata->envelope->subject);
         $eventdata->fullmessage         = get_string('invalidrecipientdescription', 'tool_messageinbound', $this->currentmessagedata);
@@ -970,7 +971,8 @@ class manager {
         $messagedata->subject = $this->currentmessagedata->envelope->subject;
         $messagedata->error = $error;
 
-        $eventdata = new \stdClass();
+        $eventdata = new \core\message\message();
+        $eventdata->courseid            = SITEID;
         $eventdata->component           = 'tool_messageinbound';
         $eventdata->name                = 'messageprocessingerror';
         $eventdata->userfrom            = $userfrom;
@@ -1029,7 +1031,8 @@ class manager {
         $messagedata = new \stdClass();
         $messagedata->subject = $this->currentmessagedata->envelope->subject;
 
-        $eventdata = new \stdClass();
+        $eventdata = new \core\message\message();
+        $eventdata->courseid            = SITEID;
         $eventdata->component           = 'tool_messageinbound';
         $eventdata->name                = 'messageprocessingsuccess';
         $eventdata->userfrom            = $userfrom;
index bb562e0..7fe0f16 100644 (file)
 defined('MOODLE_INTERNAL') || die;
 
 if ($hassiteconfig) {
-    $category = new admin_category('messageinbound', new lang_string('incomingmailconfiguration', 'tool_messageinbound'));
-
     // Create a settings page for all of the mail server settings.
-    $settings = new admin_settingpage('messageinbound_mailsettings', new lang_string('mailsettings', 'tool_messageinbound'));
+    $settings = new admin_settingpage('messageinbound_mailsettings',
+            new lang_string('incomingmailconfiguration', 'tool_messageinbound'));
 
     $settings->add(new admin_setting_heading('messageinbound_generalconfiguration',
             new lang_string('messageinboundgeneralconfiguration', 'tool_messageinbound'),
@@ -75,13 +74,10 @@ if ($hassiteconfig) {
             new lang_string('messageinboundhostpass', 'tool_messageinbound'),
             new lang_string('messageinboundhostpass_desc', 'tool_messageinbound'), ''));
 
-    $category->add('messageinbound', $settings);
-
+    // Add the category to the admin tree.
+    $ADMIN->add('email', $settings);
     // Link to the external page for Inbound Message handler configuration.
-    $category->add('messageinbound', new admin_externalpage('messageinbound_handlers',
+    $ADMIN->add('email', new admin_externalpage('messageinbound_handlers',
             new lang_string('message_handlers', 'tool_messageinbound'),
             "$CFG->wwwroot/$CFG->admin/tool/messageinbound/index.php"));
-
-    // Add the category to the admin tree.
-    $ADMIN->add('server', $category);
 }
index f8c0347..441a19a 100644 (file)
@@ -27,12 +27,12 @@ $string['autologinnotallowedtoadmins'] = 'Auto-login is not allowed to site admi
 $string['clickheretolaunchtheapp'] = 'Click here if the app does not open automatically.';
 $string['enablesmartappbanners'] = 'Enable Smart App Banners';
 $string['enablesmartappbanners_desc'] = 'This will display a banner promoting the Moodle Mobile app when visiting the site in Mobile Safari.';
-$string['forcedurlscheme'] = 'The URL scheme allows to open the mobile app from other apps like the browser. Use this setting if you want to allow only your custom branded app to be opened by the browser.';
+$string['forcedurlscheme'] = 'If you want to allow only your custom branded app to be opened via a browser window, then specify its URL scheme here; otherwise leave the field empty.';
 $string['forcedurlscheme_key'] = 'URL scheme';
 $string['httpsrequired'] = 'HTTPS required';
 $string['invalidprivatetoken'] = 'Invalid private token. Token should not be empty or passed via GET parameter.';
 $string['iosappid'] = 'App\'s unique identifier';
-$string['iosappid_desc'] = 'You only need to change this value if you have a custom iOS app';
+$string['iosappid_desc'] = 'This setting may be left as default unless you have a custom iOS app.';
 $string['loginintheapp'] = 'Via the app';
 $string['logininthebrowser'] = 'Via a browser window (for SSO plugins)';
 $string['loginintheembeddedbrowser'] = 'Via an embedded browser (for SSO plugins)';
index 714bf42..030daba 100644 (file)
@@ -56,22 +56,27 @@ require_login(0, false);
 core_user::require_active_user($USER);
 
 // Get an existing token or create a new one.
+$timenow = time();
 $token = external_generate_token_for_current_user($service);
+$privatetoken = $token->privatetoken;
+external_log_token_request($token);
 
-// Log token access.
-$DB->set_field('external_tokens', 'lastaccess', time(), array('id' => $token->id));
+// Invalidate the private token if external_generate_token_for_current_user did not create a new token.
+if ($token->timecreated < $timenow) {
+    $privatetoken = null;
+}
 
-$params = array(
-    'objectid' => $token->id,
-);
-$event = \core\event\webservice_token_sent::create($params);
-$event->add_record_snapshot('external_tokens', $token);
-$event->trigger();
+$siteadmin = has_capability('moodle/site:config', context_system::instance(), $USER->id);
 
 // Passport is generated in the mobile app, so the app opening can be validated using that variable.
 // Passports are valid only one time, it's deleted in the app once used.
 $siteid = md5($CFG->wwwroot . $passport);
-$apptoken = base64_encode($siteid . ':::' . $token->token);
+$apptoken = $siteid . ':::' . $token->token;
+if ($privatetoken and is_https() and !$siteadmin) {
+    $apptoken .= ':::' . $privatetoken;
+}
+
+$apptoken = base64_encode($apptoken);
 
 // Redirect using the custom URL scheme checking first if a URL scheme is forced in the site settings.
 $forcedurlscheme = get_config('tool_mobile', 'forcedurlscheme');
index 6e36841..a65ef04 100644 (file)
@@ -83,7 +83,8 @@ class notification_task extends \core\task\adhoc_task {
         $template = $subscription->template;
         $template = $this->replace_placeholders($template, $subscription, $eventobj, $context);
         $htmlmessage = format_text($template, $subscription->templateformat, array('context' => $context));
-        $msgdata = new \stdClass();
+        $msgdata = new \core\message\message();
+        $msgdata->courseid          = empty($subscription->courseid) ? SITEID : $subscription->courseid;
         $msgdata->component         = 'tool_monitor'; // Your component name.
         $msgdata->name              = 'notification'; // This is the message name from messages.php.
         $msgdata->userfrom          = \core_user::get_noreply_user();
index ee2eb74..d4e748b 100644 (file)
@@ -152,6 +152,17 @@ function tool_recyclebin_pre_course_module_delete($cm) {
     }
 }
 
+/**
+ * Hook called to check whether async course module deletion should be performed or not.
+ *
+ * @return true if background deletion is required (is the recyclebin is enabled), false otherwise.
+ */
+function tool_recyclebin_course_module_background_deletion_recommended() {
+    if (\tool_recyclebin\course_bin::is_enabled()) {
+        return true;
+    }
+}
+
 /**
  * Hook called before we delete a course.
  *
index 500a273..c0bc961 100644 (file)
@@ -58,6 +58,7 @@ Feature: Backup user data
     And I follow "Course 1"
     And I turn editing mode on
     And I delete "Quiz 1" activity
+    And I run all adhoc tasks
     And I navigate to "Recycle bin" node in "Course administration"
     And I should see "Quiz 1"
     And I click on "Restore" "link" in the "region-main" "region"
index ded5e99..b10af91 100644 (file)
@@ -69,6 +69,7 @@ Feature: Basic recycle bin functionality
       | Assignment name | Test assign |
       | Description | Test |
     And I delete "Test assign" activity
+    And I run all adhoc tasks
     And I navigate to "Recycle bin" node in "Course administration"
     When I click on "Delete" "link"
     Then I should see "Are you sure you want to delete the selected item from the recycle bin?"
@@ -92,6 +93,7 @@ Feature: Basic recycle bin functionality
       | Description | Test 2 |
     And I delete "Test assign 1" activity
     And I delete "Test assign 2" activity
+    And I run all adhoc tasks
     And I navigate to "Recycle bin" node in "Course administration"
     And I should see "Test assign 1"
     And I should see "Test assign 2"
index 1f83de3..9a4e0c3 100644 (file)
@@ -71,6 +71,9 @@ class tool_recyclebin_course_bin_tests extends advanced_testcase {
         // Delete the course module.
         course_delete_module($this->quiz->cmid);
 
+        // Now, run the course module deletion adhoc task.
+        phpunit_util::run_all_adhoc_tasks();
+
         // Check the course module is now in the recycle bin.
         $this->assertEquals(1, $DB->count_records('tool_recyclebin_course'));
 
@@ -112,6 +115,9 @@ class tool_recyclebin_course_bin_tests extends advanced_testcase {
         // Delete the course module.
         course_delete_module($this->quiz->cmid);
 
+        // Now, run the course module deletion adhoc task.
+        phpunit_util::run_all_adhoc_tasks();
+
         // Try purging.
         $recyclebin = new \tool_recyclebin\course_bin($this->course->id);
         foreach ($recyclebin->get_items() as $item) {
@@ -134,6 +140,9 @@ class tool_recyclebin_course_bin_tests extends advanced_testcase {
         // Delete the quiz.
         course_delete_module($this->quiz->cmid);
 
+        // Now, run the course module deletion adhoc task.
+        phpunit_util::run_all_adhoc_tasks();
+
         // Set deleted date to the distant past.
         $recyclebin = new \tool_recyclebin\course_bin($this->course->id);
         foreach ($recyclebin->get_items() as $item) {
@@ -147,6 +156,9 @@ class tool_recyclebin_course_bin_tests extends advanced_testcase {
 
         course_delete_module($book->cmid);
 
+        // Now, run the course module deletion adhoc task.
+        phpunit_util::run_all_adhoc_tasks();
+
         // Should have 2 items now.
         $this->assertEquals(2, count($recyclebin->get_items()));
 
index ba7ea8c..4b5103c 100644 (file)
Binary files a/admin/tool/templatelibrary/amd/build/display.min.js and b/admin/tool/templatelibrary/amd/build/display.min.js differ
index b8458ae..01f2d04 100644 (file)
Binary files a/admin/tool/templatelibrary/amd/build/search.min.js and b/admin/tool/templatelibrary/amd/build/search.min.js differ
index 66b3fbc..1c2e4de 100644 (file)
@@ -33,6 +33,9 @@ define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates'
      */
     var findDocsSection = function(templateSource, templateName) {
 
+        if (!templateSource) {
+            return false;
+        }
         // Find the comment section marked with @template component/template.
         var marker = "@template " + templateName,
             i = 0,
index 8b115e6..04d27b0 100644 (file)
@@ -21,8 +21,8 @@
  * @copyright  2015 Damyon Wiese <damyon@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates'],
-       function($, ajax, log, notification, templates) {
+define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates', 'core/config'],
+       function($, ajax, log, notification, templates, config) {
 
     /**
      * The ajax call has returned with a new list of templates.
@@ -42,15 +42,16 @@ define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates'
      *
      * @method refreshSearch
      */
-    var refreshSearch = function() {
+    var refreshSearch = function(themename) {
         var componentStr = $('[data-field="component"]').val();
         var searchStr = $('[data-field="search"]').val();
 
         // Trigger the search.
+        document.location.hash = searchStr;
 
         ajax.call([
             {methodname: 'tool_templatelibrary_list_templates',
-              args: {component: componentStr, search: searchStr},
+              args: {component: componentStr, search: searchStr, themename: themename},
               done: reloadListTemplate,
               fail: notification.exception}
         ], true, false);
@@ -78,12 +79,13 @@ define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates'
     };
 
     var changeHandler = function() {
-        queueRefresh(refreshSearch, 400);
+        queueRefresh(refreshSearch.bind(this, config.theme), 400);
     };
     // Add change handlers to refresh the list.
     $('[data-region="list-templates"]').on('change', '[data-field="component"]', changeHandler);
     $('[data-region="list-templates"]').on('input', '[data-field="search"]', changeHandler);
 
-    refreshSearch();
+    $('[data-field="search"]').val(document.location.hash.replace('#', ''));
+    refreshSearch(config.theme);
     return {};
 });
index 23b7dcf..b760007 100644 (file)
@@ -47,7 +47,12 @@ class api {
      * @return array[string] Where each template is in the form "component/templatename".
      */
     public static function list_templates($component = '', $search = '', $themename = '') {
-        global $CFG;
+        global $CFG, $PAGE;
+
+        if (empty($themename)) {
+            $themename = $PAGE->theme->name;
+        }
+        $themeconfig = \theme_config::load($themename);
 
         $templatedirs = array();
         $results = array();
@@ -77,6 +82,9 @@ class api {
             foreach ($plugintypes as $type => $dir) {
                 $plugins = core_component::get_plugin_list_with_file($type, 'templates', false);
                 foreach ($plugins as $plugin => $dir) {
+                    if ($type == 'theme' && $plugin != $themename && !in_array($plugin, $themeconfig->parents)) {
+                        continue;
+                    }
                     if (!empty($dir) && is_dir($dir)) {
                         $pluginname = $type . '_' . $plugin;
                         $dirs = mustache_template_finder::get_template_directories_for_component($pluginname, $themename);
@@ -111,7 +119,7 @@ class api {
      *
      * @param string $component The component that holds the template.
      * @param string $template The name of the template.
-     * @return string the template
+     * @return string the template or false if template doesn't exist.
      */
     public static function load_canonical_template($component, $template) {
         // Get the list of possible template directories.
@@ -133,7 +141,8 @@ class api {
         }
 
         if ($filename === false) {
-            throw new moodle_exception('filenotfound', 'error');
+            // There are occasions where we don't have a core template.
+            return false;
         }
 
         $templatestr = file_get_contents($filename);
index be583a2..b92f608 100644 (file)
@@ -59,7 +59,13 @@ class external extends external_api {
             VALUE_DEFAULT,
             ''
         );
-        $params = array('component' => $component, 'search' => $search);
+        $themename = new external_value(
+            PARAM_COMPONENT,
+            'The current theme',
+            VALUE_DEFAULT,
+            ''
+        );
+        $params = array('component' => $component, 'search' => $search, 'themename' => $themename);
         return new external_function_parameters($params);
     }
 
@@ -67,16 +73,18 @@ class external extends external_api {
      * Loads the list of templates.
      * @param string $component Limit the search to a component.
      * @param string $search The search string.
+     * @param string $themename The name of theme
      * @return array[string]
      */
-    public static function list_templates($component, $search) {
+    public static function list_templates($component, $search, $themename = '') {
         $params = self::validate_parameters(self::list_templates_parameters(),
                                             array(
                                                 'component' => $component,
                                                 'search' => $search,
+                                                'themename' => $themename,
                                             ));
 
-        return api::list_templates($component, $search);
+        return api::list_templates($component, $search, $themename);
     }
 
     /**
@@ -107,7 +115,7 @@ class external extends external_api {
      *
      * @param string $component The component that holds the template.
      * @param string $template The name of the template.
-     * @return string the template
+     * @return string the template, false if template doesn't exist.
      */
     public static function load_canonical_template($component, $template) {
         $params = self::validate_parameters(self::load_canonical_template_parameters(),
index 96bc6ea..a64ee83 100644 (file)
@@ -36,6 +36,13 @@ use context;
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 class role extends base {
+    /**
+     * The Site Admin pseudo-role.
+     *
+     * @var ROLE_SITEADMIN int
+     */
+    const ROLE_SITEADMIN = -1;
+
     /**
      * The name of the filter.
      *
@@ -52,7 +59,24 @@ class role extends base {
      *                                  And whose values are the values to display
      */
     public static function get_filter_options() {
-        return role_get_names(null, ROLENAME_ALIAS, true);
+        $allroles = role_get_names(null, ROLENAME_ALIAS);
+
+        $roles = [];
+        foreach ($allroles as $role) {
+            if ($role->archetype === 'guest') {
+                // No point in including the 'guest' role as it isn't possible to show tours to a guest.
+                continue;
+            }
+            $roles[$role->shortname] = $role->localname;
+        }
+
+        // Add the Site Administrator pseudo-role.
+        $roles[self::ROLE_SITEADMIN] = get_string('administrator', 'core');
+
+        // Sort alphabetically too.
+        \core_collator::asort($roles);
+
+        return $roles;
     }
 
     /**
@@ -73,14 +97,19 @@ class role extends base {
             return true;
         }
 
-        if (is_siteadmin()) {
-            return true;
-        }
-
         // Presence within the array is sufficient. Ignore any value.
         $values = array_flip($values);
 
+        if (isset($values[self::ROLE_SITEADMIN]) && is_siteadmin()) {
+            // This tour has been restricted to a role including site admin, and this user is a site admin.
+            return true;
+        }
+
+        // Use a request cache to save on DB queries.
+        // We may be checking multiple tours and they'll all be for the same userid, and contextid
         $cache = \cache::make_from_params(\cache_store::MODE_REQUEST, 'tool_usertours', 'filter_role');
+
+        // Get all of the roles used in this context, including special roles such as user, and frontpageuser.
         $cachekey = "{$USER->id}_{$context->id}";
         $userroles = $cache->get($cachekey);
         if ($userroles === false) {
@@ -88,8 +117,20 @@ class role extends base {
             $cache->set($cachekey, $userroles);
         }
 
+        // Some special roles do not include the shortname.
+        // Therefore we must fetch all roles too. Thankfully these don't actually change based on context.
+        // They do require a DB call, so let's cache it.
+        $cachekey = "allroles";
+        $allroles = $cache->get($cachekey);
+        if ($allroles === false) {
+            $allroles = get_all_roles();
+            $cache->set($cachekey, $allroles);
+        }
+
+        // Now we can check whether any of the user roles are in the list of allowed roles for this filter.
         foreach ($userroles as $role) {
-            if (isset($values[$role->roleid])) {
+            $shortname = $allroles[$role->roleid]->shortname;
+            if (isset($values[$shortname])) {
                 return true;
             }
         }
index 90e72ee..31f74bf 100644 (file)
@@ -47,7 +47,7 @@ You can enter a content in the following formats:
     <dt>Moodle Translated string</dt>
     <dd>A value found in a standard Moodle language file in the format identifier,component</dd>
 </dl>';
-$string['cssselector'] = 'CSS Selector';
+$string['cssselector'] = 'CSS selector';
 $string['defaultvalue'] = 'Default ({$a})';
 $string['delay'] = 'Delay before showing the step';
 $string['done'] = 'Done';
@@ -60,12 +60,11 @@ $string['event_tour_ended'] = 'Tour ended';
 $string['event_step_shown'] = 'Step shown';
 $string['exporttour'] = 'Export tour';
 $string['filter_header'] = 'Tour filters';
-$string['filter_help'] = 'Your can choose which conditions your tour will be shown under.
-All of the filters must match for a tour to be shown to that user.';
+$string['filter_help'] = 'Select the conditions under which the tour will be shown. All of the filters must match for a tour to be shown to a user.';
 $string['filter_theme'] = 'Theme';
 $string['filter_theme_help'] = 'Show the tour when the user is using one of the selected themes.';
 $string['filter_role'] = 'Role';
-$string['filter_role_help'] = 'Only show the tour to users with one of the specified roles.';
+$string['filter_role_help'] = 'A tour may be restricted to users with selected roles in the context where the tour is shown. For example, restricting a Dashboard tour to users with the role of student won\'t work if users have the role of student in a course (as is generally the case). A Dashboard tour can only be restricted to users with a system role.';
 $string['importtour'] = 'Import tour';
 $string['left'] = 'Left';
 $string['movestepdown'] = 'Move step down';
@@ -89,7 +88,7 @@ Some example values include:
 * /mod/forum/view.php% - to match the forum discussion list
 * /user/profile.php% - to match the user profile page';
 $string['placement'] = 'Placement';
-$string['pluginname'] = 'User Tours';
+$string['pluginname'] = 'User tours';
 $string['resettouronpage'] = 'Reset user tour on this page';
 $string['right'] = 'Right';
 $string['select_block'] = 'Select a block';
@@ -149,7 +148,7 @@ $string['selecttype'] = 'Select step type';
 $string['sharedtourslink'] = 'Tour repository';
 $string['usertours'] = 'User tours';
 $string['usertours:managetours'] = 'Create, edit, and remove user tours';
-$string['target_selector_targetvalue'] = 'CSS Selectors';
+$string['target_selector_targetvalue'] = 'CSS selectors';
 $string['target_selector_targetvalue_help'] = 'You can use a "CSS Selector" to target almost any element on the page.
 
 CSS Selectors are very powerful and you can easily find parts of the page by building up the selector gradually.
index ade49dd..940e517 100644 (file)
@@ -102,7 +102,7 @@ class tool_usertours_role_filter_testcase extends advanced_testcase {
         $context = \context_course::instance($this->course->id);
 
         $roles = [
-            $this->roles['student'],
+            'student',
         ];
 
         // Note: No need to persist this tour.
@@ -119,9 +119,9 @@ class tool_usertours_role_filter_testcase extends advanced_testcase {
             }
         }
 
-        // The admin should always be able to view too.
+        // The admin can't view this one either.
         $this->setAdminUser();
-        $this->assertTrue(\tool_usertours\local\filter\role::filter_matches($tour, $context));
+        $this->assertFalse(\tool_usertours\local\filter\role::filter_matches($tour, $context));
     }
 
     /**
@@ -131,8 +131,8 @@ class tool_usertours_role_filter_testcase extends advanced_testcase {
         $context = \context_course::instance($this->course->id);
 
         $roles = [
-            $this->roles['teacher'],
-            $this->roles['editingteacher'],
+            'teacher',
+            'editingteacher',
         ];
 
         // Note: No need to persist this tour.
@@ -149,9 +149,9 @@ class tool_usertours_role_filter_testcase extends advanced_testcase {
             }
         }
 
-        // The admin should always be able to view too.
+        // The admin can't view this one either.
         $this->setAdminUser();
-        $this->assertTrue(\tool_usertours\local\filter\role::filter_matches($tour, $context));
+        $this->assertFalse(\tool_usertours\local\filter\role::filter_matches($tour, $context));
     }
 
     /**
@@ -161,7 +161,7 @@ class tool_usertours_role_filter_testcase extends advanced_testcase {
         $context = \context_course::instance($this->course->id);
 
         $roles = [
-            $this->roles['student'],
+            'student',
         ];
 
         $this->getDataGenerator()->enrol_user($this->student->id, $this->course->id, $this->roles['teacher']);
@@ -181,8 +181,109 @@ class tool_usertours_role_filter_testcase extends advanced_testcase {
             }
         }
 
-        // The admin should always be able to view too.
+        // The admin can't view this one either.
+        $this->setAdminUser();
+        $this->assertFalse(\tool_usertours\local\filter\role::filter_matches($tour, $context));
+    }
+
+    /**
+     * Test the filter_matches function when it is targetted at an admin.
+     */
+    public function test_filter_matches_multiple_role_only_admin() {
+        $context = \context_course::instance($this->course->id);
+
+        $roles = [
+            \tool_usertours\local\filter\role::ROLE_SITEADMIN,
+        ];
+
+        $this->getDataGenerator()->enrol_user($this->student->id, $this->course->id, $this->roles['teacher']);
+
+        // Note: No need to persist this tour.
+        $tour = new \tool_usertours\tour();
+        $tour->set_filter_values('role', $roles);
+
+
+        // Note: The role filter does not use the context.
+        foreach ($this->testroles as $role) {
+            $this->setUser($this->$role);
+            $this->assertFalse(\tool_usertours\local\filter\role::filter_matches($tour, $context));
+        }
+
+        // The admin can view this one because it's only aimed at them.
+        $this->setAdminUser();
+        $this->assertTrue(\tool_usertours\local\filter\role::filter_matches($tour, $context));
+    }
+
+    /**
+     * Test the filter_matches function when multiple roles are set, including an admin user.
+     */
+    public function test_filter_matches_multiple_role_including_admin() {
+        $context = \context_course::instance($this->course->id);
+
+        $roles = [
+            \tool_usertours\local\filter\role::ROLE_SITEADMIN,
+            'teacher',
+            'editingteacher',
+        ];
+
+        // Note: No need to persist this tour.
+        $tour = new \tool_usertours\tour();
+        $tour->set_filter_values('role', $roles);
+
+        // Note: The role filter does not use the context.
+        foreach ($this->testroles as $role) {
+            $this->setUser($this->$role);
+            if ($role === 'student') {
+                $this->assertFalse(\tool_usertours\local\filter\role::filter_matches($tour, $context));
+            } else {
+                $this->assertTrue(\tool_usertours\local\filter\role::filter_matches($tour, $context));
+            }
+        }
+
+        // The admin can view this one because it's only aimed at them.
         $this->setAdminUser();
         $this->assertTrue(\tool_usertours\local\filter\role::filter_matches($tour, $context));
     }
+
+    /**
+     * Test the filter_matches function when an admin user has multiple roles.
+     */
+    public function test_filter_matches_multiple_role_admin_user() {
+        global $USER;
+
+        $context = \context_course::instance($this->course->id);
+
+        $roles = [
+            \tool_usertours\local\filter\role::ROLE_SITEADMIN,
+        ];
+
+        $this->setAdminUser();
+        $this->getDataGenerator()->enrol_user($USER->id, $this->course->id, $this->roles['student']);
+
+        // Note: No need to persist this tour.
+        $tour = new \tool_usertours\tour();
+        $tour->set_filter_values('role', $roles);
+
+        // The admin can view this one because it's only aimed at them.
+        $this->assertTrue(\tool_usertours\local\filter\role::filter_matches($tour, $context));
+    }
+
+    /**
+     * Test that the get_filter_options function does not include the guest roles.
+     */
+    public function test_get_filter_options_no_guest_roles() {
+        create_role('Test Role', 'testrole', 'This is a test role', 'guest');
+
+        $allroles = role_get_names(null, ROLENAME_ALIAS);
+        $options = \tool_usertours\local\filter\role::get_filter_options();
+
+        foreach ($allroles as $role) {
+            $hasrole = isset($options[$role->shortname]);
+            if ($role->archetype === 'guest') {
+                $this->assertFalse($hasrole);
+            } else {
+                $this->assertTrue($hasrole);
+            }
+        }
+    }
 }
index dd410f4..ee71a22 100644 (file)
@@ -101,10 +101,12 @@ class user_bulk_form extends moodleform {
         $objs = array();
         $objs[] =& $mform->createElement('submit', 'addsel', get_string('addsel', 'bulkusers'));
         $objs[] =& $mform->createElement('submit', 'removesel', get_string('removesel', 'bulkusers'));
+        $grp =& $mform->addElement('group', 'buttonsgrp', get_string('selectedlist', 'bulkusers'), $objs, null, false);
+        $mform->addHelpButton('buttonsgrp', 'selectedlist', 'bulkusers');
+        $objs = array();
         $objs[] =& $mform->createElement('submit', 'addall', get_string('addall', 'bulkusers'));
         $objs[] =& $mform->createElement('submit', 'removeall', get_string('removeall', 'bulkusers'));
-        $grp =& $mform->addElement('group', 'buttonsgrp', get_string('selectedlist', 'bulkusers'), $objs, array(' ', '<br />'), false);
-        $mform->addHelpButton('buttonsgrp', 'selectedlist', 'bulkusers');
+        $grp =& $mform->addElement('group', 'buttonsgrp2', '', $objs, null, false);
 
         $renderer =& $mform->defaultRenderer();
         $template = '<label class="qflabel" style="vertical-align:top">{label}</label> {element}';
index 83161a7..008367b 100644 (file)
@@ -9,7 +9,7 @@ $confirm = optional_param('confirm', 0, PARAM_BOOL);
 
 require_login();
 admin_externalpage_setup('userbulk');
-require_capability('moodle/site:readallmessages', context_system::instance());
+require_capability('moodle/site:manageallmessaging', context_system::instance());
 
 $return = $CFG->wwwroot.'/'.$CFG->admin.'/user/user_bulk.php';
 
index 6a1b387..4ecff91 100644 (file)
@@ -169,7 +169,7 @@ class auth_email_external extends external_api {
                 ),
                 'recaptchapublickey' => new external_value(PARAM_RAW, 'Recaptcha public key', VALUE_OPTIONAL),
                 'recaptchachallengehash' => new external_value(PARAM_RAW, 'Recaptcha challenge hash', VALUE_OPTIONAL),
-                'recaptchachallengeimage' => new external_value(PARAM_URL, 'Recaptcha challenge <noscript> image', VALUE_OPTIONAL),
+                'recaptchachallengeimage' => new external_value(PARAM_URL, 'Recaptcha challenge noscript image', VALUE_OPTIONAL),
                 'recaptchachallengejs' => new external_value(PARAM_URL, 'Recaptcha challenge js url', VALUE_OPTIONAL),
                 'warnings'  => new external_warnings(),
             )
index 7ca3fb2..6f23523 100644 (file)
@@ -77,7 +77,7 @@ $string['auth_ldap_opt_deref'] = 'Determines how aliases are handled during sear
 $string['auth_ldap_opt_deref_key'] = 'Dereference aliases';
 $string['auth_ldap_passtype'] = 'Specify the format of new or changed passwords in LDAP server.';
 $string['auth_ldap_passtype_key'] = 'Password format';
-$string['auth_ldap_passwdexpire_settings'] = 'LDAP password expiration settings.';
+$string['auth_ldap_passwdexpire_settings'] = 'LDAP password expiration settings';
 $string['auth_ldap_preventpassindb'] = 'Select yes to prevent passwords from being stored in Moodle\'s DB.';
 $string['auth_ldap_preventpassindb_key'] = 'Don\'t cache passwords';
 $string['auth_ldap_search_sub'] = 'Search users from subcontexts.';
@@ -134,7 +134,7 @@ $string['ntlmsso_isdisabled'] = 'NTLM SSO is disabled.';
 $string['ntlmsso_unknowntype'] = 'Unknown ntlmsso type!';
 $string['pagedresultsnotsupp'] = 'LDAP paged results not supported (either your PHP version lacks support or you have configured Moodle to use LDAP protocol version 2)';
 $string['pagesize'] = 'Make sure this value is smaller than your LDAP server result set size limit (the maximum number of entries that can be returned in a single query)';
-$string['pagesize_key'] = 'Page Size';
+$string['pagesize_key'] = 'Page size';
 $string['pluginname'] = 'LDAP server';
 $string['pluginnotenabled'] = 'Plugin not enabled!';
 $string['renamingnotallowed'] = 'User renaming not allowed in LDAP';
diff --git a/auth/radius/auth.php b/auth/radius/auth.php
deleted file mode 100644 (file)
index 24ae5d3..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Authentication Plugin: RADIUS Authentication
- *
- * Authenticates against a RADIUS server.
- * Contributed by Clive Gould <clive@ce.bromley.ac.uk>
- * CHAP support contributed by Stanislav Tsymbalov http://www.tsymbalov.net/
- *
- * @package auth_radius
- * @author Martin Dougiamas
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->libdir.'/authlib.php');
-
-/**
- * RADIUS authentication plugin.
- */
-class auth_plugin_radius extends auth_plugin_base {
-
-    /**
-     * Constructor.
-     */
-    public function __construct() {
-        $this->authtype = 'radius';
-        $this->config = get_config('auth/radius');
-    }
-
-    /**
-     * Old syntax of class constructor. Deprecated in PHP7.
-     *
-     * @deprecated since Moodle 3.1
-     */
-    public function auth_plugin_radius() {
-        debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
-        self::__construct();
-    }
-
-    /**
-     * Returns true if the username and password work and false if they are
-     * wrong or don't exist.
-     *
-     * @param string $username The username
-     * @param string $password The password
-     * @return bool Authentication success or failure.
-     */
-    function user_login ($username, $password) {
-        require_once 'Auth/RADIUS.php';
-        require_once 'Crypt/CHAP.php';
-
-        // Added by Clive on 7th May for test purposes
-        // printf("Username: $username <br/>");
-        // printf("Password: $password <br/>");
-        // printf("host: $this->config->host <br/>");
-        // printf("nasport: $this->config->nasport <br/>");
-        // printf("secret: $this->config->secret <br/>");
-
-        // Added by Stanislav Tsymbalov on 12th March 2008 only for test purposes
-        //$type = 'PAP';
-        //$type = 'CHAP_MD5';
-        //$type = 'MSCHAPv1';
-        //$type = 'MSCHAPv2';
-        $type = $this->config->radiustype;
-        if (empty($type)) {
-            $type = 'PAP';
-        }
-
-        $classname = 'Auth_RADIUS_' . $type;
-        $rauth = new $classname($username, $password);
-        $rauth->addServer($this->config->host, $this->config->nasport, $this->config->secret);
-
-        $rauth->username = $username;
-
-        switch($type) {
-        case 'CHAP_MD5':
-        case 'MSCHAPv1':
-            $classname = $type == 'MSCHAPv1' ? 'Crypt_CHAP_MSv1' : 'Crypt_CHAP_MD5';
-            $crpt = new $classname;
-            $crpt->password = $password;
-            $rauth->challenge = $crpt->challenge;
-            $rauth->chapid = $crpt->chapid;
-            $rauth->response = $crpt->challengeResponse();
-            $rauth->flags = 1;
-            // If you must use deprecated and weak LAN-Manager-Responses use this:
-            // $rauth->lmResponse = $crpt->lmChallengeResponse();
-            // $rauth->flags = 0;
-            break;
-
-        case 'MSCHAPv2':
-            $crpt = new Crypt_CHAP_MSv2;
-            $crpt->username = $username;
-            $crpt->password = $password;
-            $rauth->challenge = $crpt->authChallenge;
-            $rauth->peerChallenge = $crpt->peerChallenge;
-            $rauth->chapid = $crpt->chapid;
-            $rauth->response = $crpt->challengeResponse();
-            break;
-
-        default:
-            $rauth->password = $password;
-            break;
-        }
-
-        if (!$rauth->start()) {
-            printf("Radius start: %s<br/>\n", $rauth->getError());
-            exit;
-        }
-
-        $result = $rauth->send();
-        if ($rauth->isError($result)) {
-            printf("Radius send failed: %s<br/>\n", $result->getMessage());
-            exit;
-        } else if ($result === true) {
-            // printf("Radius Auth succeeded<br/>\n");
-            return true;
-        } else {
-            // printf("Radius Auth rejected<br/>\n");
-            return false;
-        }
-
-        // get attributes, even if auth failed
-        if (!$rauth->getAttributes()) {
-            printf("Radius getAttributes: %s<br/>\n", $rauth->getError());
-        } else {
-            $rauth->dumpAttributes();
-        }
-
-        $rauth->close();
-    }
-
-    function prevent_local_passwords() {
-        return true;
-    }
-
-    /**
-     * Returns true if this authentication plugin is 'internal'.
-     *
-     * @return bool
-     */
-    function is_internal() {
-        return false;
-    }
-
-    /**
-     * Returns true if this authentication plugin can change the user's
-     * password.
-     *
-     * @return bool
-     */
-    function can_change_password() {
-        return false;
-    }
-
-    /**
-     * Prints a form for configuring this authentication plugin.
-     *
-     * This function is called from admin/auth.php, and outputs a full page with
-     * a form for configuring this plugin.
-     *
-     * @param array $page An object containing all the data for this page.
-     */
-    function config_form($config, $err, $user_fields) {
-        global $OUTPUT;
-
-        include "config.html";
-    }
-
-    /**
-     * Processes and stores configuration data for this authentication plugin.
-     */
-    function process_config($config) {
-        // set to defaults if undefined
-        if (!isset ($config->host)) {
-            $config->host = '127.0.0.1';
-        }
-        if (!isset ($config->nasport)) {
-            $config->nasport = '1812';
-        }
-        if (!isset($config->radiustype)) {
-            $config->radiustype = 'PAP';
-        }
-        if (!isset ($config->secret)) {
-            $config->secret = '';
-        }
-        if (!isset($config->changepasswordurl)) {
-            $config->changepasswordurl = '';
-        }
-
-        // save settings
-        set_config('host',    $config->host,    'auth/radius');
-        set_config('nasport', $config->nasport, 'auth/radius');
-        set_config('secret',  $config->secret,  'auth/radius');
-        set_config('changepasswordurl', $config->changepasswordurl, 'auth/radius');
-        set_config('radiustype', $config->radiustype, 'auth/radius');
-
-        return true;
-    }
-
-}
-
-
diff --git a/auth/radius/config.html b/auth/radius/config.html
deleted file mode 100644 (file)
index 3ae3f26..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-
-// Is Auth/RADIUS really there?
-if (!extension_loaded('radius')) {
-    print '<div class="box errorbox errorboxcontent"><p class="errormessage"><strong>Warning: The PHP RADIUS extension is not present. Please ensure it is installed and enabled.</strong></p></div>';
-}
-include_once 'Auth/RADIUS.php';
-if (!class_exists('Auth_RADIUS')) {
-    print '<div class="box errorbox errorboxcontent"><p class="errormessage"><strong>Warning: There is a problem with the PHP Pear Auth_RADIUS package. Please ensure it is installed correctly.</strong></p></div>';
-}
-
-// set to defaults if undefined
-if (!isset($config->host)) {
-    $config->host = '127.0.0.1';
-}
-if (!isset($config->nasport)) {
-    $config->nasport = '1812';
-}
-if (!isset($config->radiustype)) {
-    $config->radiustype = 'PAP';
-}
-if (!isset($config->secret)) {
-    $config->secret = '';
-}
-if (!isset($config->changepasswordurl)) {
-    $config->changepasswordurl = '';
-}
-
-?>
-<table cellspacing="0" cellpadding="5" border="0">
-
-<tr valign="top">
-    <td align="right"><label for="host"><?php print_string('auth_radiushost_key', 'auth_radius') ?>: </label></td>
-    <td>
-        <input name="host" id="host" type="text" size="30" value="<?php echo $config->host ?>" />
-        <?php
-
-        if (isset($err['host'])) {
-            echo $OUTPUT->error_text($err['host']);
-        }
-
-        ?>
-        </td>
-    <td><?php print_string('auth_radiushost', 'auth_radius') ?></td>
-</tr>
-
-<tr valign="top">
-    <td align="right"><label for="nasport"><?php print_string('auth_radiusnasport_key', 'auth_radius') ?>: </label></td>
-    <td>
-        <input name="nasport" id="nasport" type="text" size="6" value="<?php echo $config->nasport ?>" />
-        <?php
-
-        if (isset($err['nasport'])) {
-            echo $OUTPUT->error_text($err['nasport']);
-        }
-
-        ?>
-    </td>
-    <td><?php print_string('auth_radiusnasport', 'auth_radius') ?></td>
-</tr>
-
-<tr valign="top" >
-    <td align="right"><?php echo html_writer::label(get_string('auth_radiustype_key', 'auth_radius') . ':', 'menuradiustype'); ?> </td>
-    <td>
-<?php
-
-    $radiustype = array();
-    $radiustype['PAP']      = get_string('auth_radiustypepap', 'auth_radius');
-    $radiustype['CHAP_MD5'] = get_string('auth_radiustypechapmd5', 'auth_radius');
-    $radiustype['MSCHAPv1'] = get_string('auth_radiustypemschapv1', 'auth_radius');
-    $radiustype['MSCHAPv2'] = get_string('auth_radiustypemschapv2', 'auth_radius');
-    echo html_writer::select($radiustype, 'radiustype', $config->radiustype, false);
-
-    if (isset($err['radiustype'])) {
-        echo $OUTPUT->error_text($err['radiustype']);
-    }
-
-?>
-    </td>
-    <td><?php print_string('auth_radiustype', 'auth_radius') ?></td>
-</tr>
-
-
-<tr valign="top" >
-    <td align="right"><label for="secret"><?php print_string('auth_radiussecret_key', 'auth_radius') ?>: </label></td>
-    <td>
-        <input name="secret" id="secret" type="text" size="6" value="<?php echo $config->secret ?>" />
-        <?php
-
-        if (isset($err['secret'])) {
-            echo $OUTPUT->error_text($err['secret']);
-        }
-
-        ?>
-    </td>
-    <td><?php print_string('auth_radiussecret', 'auth_radius') ?></td>
-</tr>
-
-<tr valign="top">
-    <td align="right"><label for="changepasswordurl"><?php print_string('auth_radiuschangepasswordurl_ke