Merge branch 'MDL-54963_master' of git://github.com/dmonllao/moodle
authorDan Poltawski <dan@moodle.com>
Mon, 18 Jul 2016 12:38:36 +0000 (13:38 +0100)
committerDan Poltawski <dan@moodle.com>
Mon, 18 Jul 2016 12:38:36 +0000 (13:38 +0100)
314 files changed:
.csslintrc
.eslintrc
.travis.yml
Gruntfile.js
admin/cli/reset_password.php
admin/index.php
admin/searchareas.php [new file with mode: 0644]
admin/settings/plugins.php
admin/tool/lp/amd/build/actionselector.min.js
admin/tool/lp/amd/build/competencies.min.js
admin/tool/lp/amd/build/competency_rule_points.min.js
admin/tool/lp/amd/build/competencyactions.min.js
admin/tool/lp/amd/build/competencypicker.min.js
admin/tool/lp/amd/build/competencypicker_user_plans.min.js
admin/tool/lp/amd/build/competencyruleconfig.min.js
admin/tool/lp/amd/build/competencytree.min.js
admin/tool/lp/amd/build/grade_user_competency_inline.min.js
admin/tool/lp/amd/build/menubar.min.js
admin/tool/lp/amd/build/parentcompetency_form.min.js
admin/tool/lp/amd/build/planactions.min.js
admin/tool/lp/amd/build/scaleconfig.min.js
admin/tool/lp/amd/build/tree.min.js
admin/tool/lp/amd/build/user_competency_info.min.js
admin/tool/lp/amd/build/user_competency_plan_popup.min.js
admin/tool/lp/amd/build/user_evidence_actions.min.js
admin/tool/lp/amd/src/actionselector.js
admin/tool/lp/amd/src/competencies.js
admin/tool/lp/amd/src/competency_outcomes.js
admin/tool/lp/amd/src/competency_rule_points.js
admin/tool/lp/amd/src/competencyactions.js
admin/tool/lp/amd/src/competencydialogue.js
admin/tool/lp/amd/src/competencypicker.js
admin/tool/lp/amd/src/competencypicker_user_plans.js
admin/tool/lp/amd/src/competencyruleconfig.js
admin/tool/lp/amd/src/course_competency_settings.js
admin/tool/lp/amd/src/dragdrop-reorder.js
admin/tool/lp/amd/src/evidence_delete.js
admin/tool/lp/amd/src/form-cohort-selector.js
admin/tool/lp/amd/src/frameworkactions.js
admin/tool/lp/amd/src/grade_user_competency_inline.js
admin/tool/lp/amd/src/menubar.js
admin/tool/lp/amd/src/parentcompetency_form.js
admin/tool/lp/amd/src/planactions.js
admin/tool/lp/amd/src/scaleconfig.js
admin/tool/lp/amd/src/templateactions.js
admin/tool/lp/amd/src/tree.js
admin/tool/lp/amd/src/user_competency_info.js
admin/tool/lp/amd/src/user_competency_plan_popup.js
admin/tool/lp/amd/src/user_evidence_actions.js
admin/tool/recyclebin/lib.php
admin/tool/recyclebin/tests/category_bin_test.php
admin/tool/templatelibrary/amd/build/display.min.js
admin/tool/templatelibrary/amd/src/search.js
backup/util/ui/restore_ui.class.php
blocks/activity_results/block_activity_results.php
blocks/activity_results/edit_form.php
blocks/activity_results/lang/en/block_activity_results.php
blocks/activity_results/settings.php [new file with mode: 0644]
blocks/activity_results/tests/behat/defaultsettings.feature [new file with mode: 0644]
blocks/activity_results/version.php
blocks/navigation/amd/build/ajax_response_renderer.min.js
blocks/navigation/renderer.php
blocks/settings/renderer.php
calendar/lib.php
completion/data_object.php
course/classes/search/mycourse.php
course/view.php
course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop-debug.js
course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop.js
course/yui/build/moodle-course-management/moodle-course-management-debug.js
course/yui/build/moodle-course-management/moodle-course-management.js
course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes-debug.js
course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes.js
course/yui/src/dragdrop/js/dragdrop.js
course/yui/src/management/js/category.js
course/yui/src/management/js/console.js
course/yui/src/management/js/course.js
course/yui/src/management/js/dd.js
course/yui/src/toolboxes/js/resource.js
course/yui/src/toolboxes/js/section.js
course/yui/src/toolboxes/js/toolbox.js
enrol/yui/rolemanager/assets/skins/sam/rolemanager.css
filter/mathjaxloader/filter.php
grade/edit/tree/index.php
grade/grading/form/guide/amd/build/comment_chooser.min.js
grade/report/grader/yui/build/moodle-gradereport_grader-gradereporttable/moodle-gradereport_grader-gradereporttable-debug.js
grade/report/grader/yui/build/moodle-gradereport_grader-gradereporttable/moodle-gradereport_grader-gradereporttable.js
grade/report/grader/yui/src/gradereporttable/js/floatingheaders.js
grade/report/grader/yui/src/gradereporttable/js/gradereporttable.js
install/lang/ca/install.php
lang/en/admin.php
lib/adminlib.php
lib/amd/build/form-autocomplete.min.js
lib/amd/build/form-course-selector.min.js
lib/amd/build/fragment.min.js
lib/amd/build/inplace_editable.min.js
lib/amd/build/localstorage.min.js
lib/amd/build/loglevel.min.js
lib/amd/build/mustache.min.js
lib/amd/build/notification.min.js
lib/amd/build/search-input.min.js
lib/amd/build/tag.min.js
lib/amd/build/templates.min.js
lib/amd/build/tree.min.js
lib/amd/src/event.js
lib/amd/src/form-autocomplete.js
lib/amd/src/form-course-selector.js
lib/amd/src/fragment.js
lib/amd/src/localstorage.js
lib/amd/src/notification.js
lib/amd/src/tag.js
lib/amd/src/templates.js
lib/amd/src/tree.js
lib/classes/grades_external.php
lib/classes/plugin_manager.php
lib/classes/requirejs.php
lib/db/services.php
lib/db/upgrade.php
lib/db/upgradelib.php
lib/editor/atto/styles.css
lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-debug.js
lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor.js
lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin-debug.js
lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin.js
lib/editor/atto/yui/src/editor/js/autosave.js
lib/editor/atto/yui/src/editor/js/clean.js
lib/editor/atto/yui/src/editor/js/editor-plugin-buttons.js
lib/editor/atto/yui/src/editor/js/editor.js
lib/editor/atto/yui/src/editor/js/lintconfig.js [deleted file]
lib/editor/atto/yui/src/editor/js/selection.js
lib/editor/atto/yui/src/editor/js/styling.js
lib/editor/atto/yui/src/editor/js/toolbar-keyboardnav.js
lib/externallib.php
lib/form/yui/build/moodle-form-dateselector/moodle-form-dateselector-debug.js
lib/form/yui/build/moodle-form-dateselector/moodle-form-dateselector.js
lib/form/yui/src/dateselector/js/dateselector.js
lib/navigationlib.php
lib/tests/externallib_test.php
lib/tests/requirejs_test.php [new file with mode: 0644]
lib/tests/upgradelib_test.php
lib/tests/weblib_test.php
lib/upgrade.txt
lib/weblib.php
lib/yui/build/moodle-core-blocks/moodle-core-blocks-debug.js
lib/yui/build/moodle-core-blocks/moodle-core-blocks.js
lib/yui/build/moodle-core-dock/moodle-core-dock-debug.js
lib/yui/build/moodle-core-dock/moodle-core-dock.js
lib/yui/build/moodle-core-languninstallconfirm/moodle-core-languninstallconfirm-debug.js
lib/yui/build/moodle-core-languninstallconfirm/moodle-core-languninstallconfirm.js
lib/yui/build/moodle-core-notification-ajaxexception/moodle-core-notification-ajaxexception-debug.js
lib/yui/build/moodle-core-notification-ajaxexception/moodle-core-notification-ajaxexception.js
lib/yui/build/moodle-core-notification-alert/moodle-core-notification-alert-debug.js
lib/yui/build/moodle-core-notification-alert/moodle-core-notification-alert.js
lib/yui/build/moodle-core-notification-confirm/moodle-core-notification-confirm-debug.js
lib/yui/build/moodle-core-notification-confirm/moodle-core-notification-confirm.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-debug.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue.js
lib/yui/build/moodle-core-notification-exception/moodle-core-notification-exception-debug.js
lib/yui/build/moodle-core-notification-exception/moodle-core-notification-exception.js
lib/yui/src/blocks/js/blockregion.js
lib/yui/src/blocks/js/blocks.js
lib/yui/src/blocks/js/manager.js
lib/yui/src/dock/js/block.js
lib/yui/src/dock/js/dock.js
lib/yui/src/dock/js/dockeditem.js
lib/yui/src/dock/js/panel.js
lib/yui/src/dock/js/tabheightmanager.js
lib/yui/src/languninstallconfirm/js/languninstallconfirm.js
lib/yui/src/notification/js/ajaxexception.js
lib/yui/src/notification/js/alert.js
lib/yui/src/notification/js/confirm.js
lib/yui/src/notification/js/dialogue.js
lib/yui/src/notification/js/exception.js
lib/yui/src/notification/js/info.js
lib/yui/src/notification/js/shared.js
message/yui/build/moodle-core_message-messenger/moodle-core_message-messenger-debug.js
message/yui/build/moodle-core_message-messenger/moodle-core_message-messenger.js
message/yui/src/messenger/js/constants.js
message/yui/src/messenger/js/manager.js
message/yui/src/messenger/js/sendmessage.js
mod/assign/amd/build/grading_actions.min.js
mod/assign/amd/build/grading_form_change_checker.min.js
mod/assign/amd/build/grading_navigation.min.js
mod/assign/amd/build/grading_navigation_user_info.min.js
mod/assign/amd/build/grading_panel.min.js
mod/assign/amd/build/grading_review_panel.min.js
mod/assign/amd/src/grading_navigation.js
mod/assign/amd/src/grading_panel.js
mod/assign/amd/src/participant_selector.js
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-debug.js
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor-min.js
mod/assign/feedback/editpdf/yui/build/moodle-assignfeedback_editpdf-editor/moodle-assignfeedback_editpdf-editor.js
mod/assign/feedback/editpdf/yui/src/editor/js/annotation.js
mod/assign/feedback/editpdf/yui/src/editor/js/annotationhighlight.js
mod/assign/feedback/editpdf/yui/src/editor/js/annotationline.js
mod/assign/feedback/editpdf/yui/src/editor/js/annotationoval.js
mod/assign/feedback/editpdf/yui/src/editor/js/annotationpen.js
mod/assign/feedback/editpdf/yui/src/editor/js/annotationrectangle.js
mod/assign/feedback/editpdf/yui/src/editor/js/annotationstamp.js
mod/assign/feedback/editpdf/yui/src/editor/js/comment.js
mod/assign/feedback/editpdf/yui/src/editor/js/commentsearch.js
mod/assign/feedback/editpdf/yui/src/editor/js/drawable.js
mod/assign/feedback/editpdf/yui/src/editor/js/editor.js
mod/assign/feedback/editpdf/yui/src/editor/js/globals.js
mod/assign/feedback/editpdf/yui/src/editor/js/quickcommentlist.js
mod/book/locallib.php
mod/book/tests/search_test.php
mod/choice/db/access.php
mod/choice/lang/en/choice.php
mod/choice/lib.php
mod/choice/locallib.php [new file with mode: 0644]
mod/choice/tests/behat/remove_choice_options.feature [new file with mode: 0644]
mod/choice/version.php
mod/data/lib.php
mod/forum/externallib.php
mod/forum/lib.php
mod/forum/tests/lib_test.php
mod/forum/tests/search_test.php
mod/glossary/classes/search/entry.php
mod/glossary/tests/search_test.php
mod/lesson/pagetypes/numerical.php
mod/lesson/report.php
mod/lti/amd/build/cartridge_registration_form.min.js
mod/lti/amd/build/external_registration.min.js
mod/lti/amd/build/tool_card_controller.min.js
mod/lti/amd/build/tool_proxy_card_controller.min.js
mod/lti/amd/src/cartridge_registration_form.js
mod/lti/amd/src/tool_proxy.js
mod/lti/amd/src/tool_type.js
mod/quiz/yui/build/moodle-mod_quiz-dragdrop/moodle-mod_quiz-dragdrop-debug.js
mod/quiz/yui/build/moodle-mod_quiz-dragdrop/moodle-mod_quiz-dragdrop.js
mod/quiz/yui/build/moodle-mod_quiz-toolboxes/moodle-mod_quiz-toolboxes-debug.js
mod/quiz/yui/build/moodle-mod_quiz-toolboxes/moodle-mod_quiz-toolboxes-min.js
mod/quiz/yui/build/moodle-mod_quiz-toolboxes/moodle-mod_quiz-toolboxes.js
mod/quiz/yui/build/moodle-mod_quiz-util-page/moodle-mod_quiz-util-page-debug.js
mod/quiz/yui/build/moodle-mod_quiz-util-page/moodle-mod_quiz-util-page.js
mod/quiz/yui/src/dragdrop/js/dragdrop.js
mod/quiz/yui/src/dragdrop/js/resource.js
mod/quiz/yui/src/toolboxes/js/resource.js
mod/quiz/yui/src/toolboxes/js/section.js
mod/quiz/yui/src/toolboxes/js/toolbox.js
mod/quiz/yui/src/util/js/page.js
mod/survey/classes/search/activity.php
mod/wiki/tests/search_test.php
mod/workshop/lang/en/workshop.php
mod/workshop/renderer.php
npm-shrinkwrap.json
package.json
question/type/ddimageortext/yui/build/moodle-qtype_ddimageortext-form/moodle-qtype_ddimageortext-form-debug.js
question/type/ddimageortext/yui/build/moodle-qtype_ddimageortext-form/moodle-qtype_ddimageortext-form.js
question/type/ddimageortext/yui/src/form/js/form.js
question/type/ddmarker/yui/build/moodle-qtype_ddmarker-form/moodle-qtype_ddmarker-form-debug.js
question/type/ddmarker/yui/build/moodle-qtype_ddmarker-form/moodle-qtype_ddmarker-form.js
question/type/ddmarker/yui/src/form/js/form.js
report/competency/amd/build/grading_popup.min.js
report/competency/amd/src/grading_popup.js
report/progress/styles.css
report/search/classes/output/form.php [deleted file]
report/search/classes/output/renderer.php [deleted file]
report/search/index.php [deleted file]
report/search/lang/en/report_search.php [deleted file]
report/search/settings.php [deleted file]
search/classes/area/base.php
search/classes/area/base_activity.php
search/classes/document.php
search/classes/manager.php
search/templates/result.mustache
search/tests/document_test.php [new file with mode: 0644]
search/tests/fixtures/mock_search_area.php
search/tests/fixtures/mock_search_engine.php
search/tests/generator/lib.php
search/tests/manager_test.php
theme/base/style/admin.css
theme/base/style/autocomplete.css
theme/base/style/blocks.css
theme/base/style/calendar.css
theme/base/style/core.css
theme/base/style/course.css
theme/base/style/dock.css
theme/base/style/editor.css
theme/base/style/filemanager.css
theme/base/style/grade.css
theme/base/style/message.css
theme/base/style/pagelayout.css
theme/base/style/question.css
theme/base/style/tabs.css
theme/base/style/user.css
theme/bootstrapbase/amd/build/bootstrap.min.js
theme/bootstrapbase/less/moodle/bootstrapoverride.less
theme/bootstrapbase/less/moodle/core.less
theme/bootstrapbase/less/moodle/course.less
theme/bootstrapbase/less/moodle/expendable.less
theme/bootstrapbase/less/moodle/filemanager.less
theme/bootstrapbase/less/moodle/forms.less
theme/bootstrapbase/less/moodle/grade.less
theme/bootstrapbase/less/moodle/message.less
theme/bootstrapbase/less/moodle/modules.less
theme/bootstrapbase/less/moodle/question.less
theme/bootstrapbase/less/moodle/responsive.less
theme/bootstrapbase/less/moodle/search.less
theme/bootstrapbase/less/moodle/templates.less
theme/bootstrapbase/less/moodle/undo.less
theme/bootstrapbase/style/moodle.css
theme/canvas/style/admin.css
theme/canvas/style/blocks.css
theme/canvas/style/core.css
theme/canvas/style/course.css
theme/canvas/style/editor.css
theme/canvas/style/mods.css
theme/canvas/style/pagelayout.css
theme/canvas/style/popups.css
theme/canvas/style/text.css
version.php
webservice/upgrade.txt

index 5b01fd1..4203daa 100644 (file)
@@ -1,3 +1,3 @@
 --errors=errors,duplicate-properties
 --warnings=known-properties,display-property-grouping,empty-rules,important
---exclude-list=vendor/,lib/editor/tinymce/,lib/yuilib/,theme/bootstrapbase/style/
+--exclude-list=vendor/,node_modules/,lib/editor/tinymce/,lib/yuilib/,theme/bootstrapbase/style/,lib/jquery/,lib/htmlpurifier,theme/clean/style/custom.css,theme/more/style/custom.css,
index 03dc85a..c701962 100644 (file)
--- a/.eslintrc
+++ b/.eslintrc
@@ -9,10 +9,10 @@
   },
   'rules': {
     // See http://eslint.org/docs/rules/ for all rules and explanations of all
-    // rules. Commented out rules with 'DEFINE POLICY' are rules Dan P has flagged
-    // for discussion and possible enable soon.
+    // rules.
+
     // === Possible Errors ===
-    // DEFINE POLICY: 'comma-dangle': ['off', 'always'],
+    'comma-dangle': 'off',
     'no-cond-assign': 'error',
     'no-console': 'error',
     'no-constant-condition': 'error',
@@ -21,7 +21,7 @@
     'no-dupe-args': 'error',
     'no-dupe-keys': 'error',
     'no-duplicate-case': 'error',
-    // Disabled for YUI rollups, enabled by grunt for AMD: 'no-empty': 'error',
+    'no-empty': 'warn',
     'no-empty-character-class': 'error',
     'no-ex-assign': 'error',
     'no-extra-boolean-cast': 'error',
 
     // === Best Practices ===
     // (these mostly match our jshint config)
+    'array-callback-return': 'warn',
+    'block-scoped-var': 'warn',
+    'complexity': 'warn',
+    'consistent-return': 'warn',
     'curly': 'error',
     'dot-notation': 'warn',
     'no-alert': 'warn',
     'no-caller': 'error',
     'no-case-declarations': 'error',
+    'no-div-regex': 'error',
     'no-empty-pattern': 'error',
     'no-empty-function': 'warn',
-    //DEFINE POLICY: 'no-eq-null': 'warn',
+    'no-eq-null': 'error',
     'no-eval': 'error',
-    //DEFINE POLICY: 'no-extra-bind': 'warn',
+    'no-extend-native': 'error',
+    'no-extra-bind': 'warn',
     'no-fallthrough': 'error',
-    //DEFINE POLICY: 'no-implicit-globals': 'warn',
+    'no-floating-decimal': 'warn',
+    // Enabled by grunt for AMD modules: 'no-implicit-globals': 'error',
     'no-implied-eval': 'error',
     'no-invalid-this': 'error',
     'no-iterator': 'error',
     'no-native-reassign': 'warn',
     'no-new-func': 'error',
     'no-new-wrappers': 'error',
-    // DEFINE POLICY: no-octal: "error"
-    // DEFINE POLICY: no-octal-escape: "error"
+    'no-octal': 'error',
+    'no-octal-escape': 'error',
     'no-proto': 'error',
     'no-redeclare': 'warn',
     'no-return-assign': 'error',
     'no-script-url': 'error',
     'no-self-assign': 'error',
     'no-self-compare': 'error',
+    'no-sequences': 'warn',
+    'no-throw-literal': 'warn',
     'no-unmodified-loop-condition': 'error',
-    // Disabled for YUI rollups, enabled by grunt for AMD: 'no-unused-expressions': 'error',
+    'no-unused-expressions': 'error',
     'no-unused-labels': 'error',
-    //DEFINE POLICY: 'no-useless-call': 'error',
+    'no-useless-call': 'warn',
     'no-useless-escape': 'warn',
-    //DEFINE POLICY: 'no-with': 'error',
+    'no-with': 'error',
     'wrap-iife': ['error', 'any'],
 
     // === Variables ===
     'no-delete-var': 'error',
-    // Disabled for YUI rollups, enabled by grunt for AMD: 'no-undef': 'off',
-    //DEFINE POLICY: 'no-undef-init': 'error',
-    // Disabled for YUI rollups, enabled by grunt for AMD: 'no-unused-vars': 'error',
+    'no-undef': 'error',
+    'no-undef-init': 'error',
+    'no-unused-vars': ['error', { 'caughtErrors': 'none', 'argsIgnorePattern': "(e|event)" }],
 
     // === Stylistic Issues ===
     'array-bracket-spacing': 'warn',
     'lines-around-comment': 'off',
     'max-len': ['error', 132],
     'max-lines': 'off',
-    // DEFINE POLICY: turn on some of these max values?
-    'max-depth': 'off',
-    'max-nested-callbacks': 'off',
+    'max-depth': 'warn',
+    'max-nested-callbacks': ['warn', 5],
     'max-params': 'off',
     'max-statements': 'off',
-    'max-statements-per-line': 'off',
+    'max-statements-per-line': ['warn', { max: 2 }],
     'new-cap': ['warn', { 'properties': false }],
     'new-parens': 'warn',
     'newline-after-var': 'off',
     'newline-before-return': 'off',
-    // REVIST POLICY: 'newline-per-chained-call': 'warn',
+    'newline-per-chained-call': 'off',
     'no-array-constructor': 'off',
     'no-bitwise': 'error',
     'no-continue': 'off',
     'no-ternary': 'off',
     'no-trailing-spaces': 'error',
     'no-underscore-dangle': 'off',
-    // DEFINE POLICY: 'no-unneeded-ternary': 'off',
+    'no-unneeded-ternary': 'off',
     'no-whitespace-before-property': 'warn',
-    // DEFINE POLICY: 'object-curly-newline': 'off,
-    // DEFINE POLICY: 'object-curly-spacing': 'off',
-    // DEFINE POLICY: 'object-property-newline': 'off',
+    'object-curly-newline': 'off',
+    'object-curly-spacing': 'warn',
+    'object-property-newline': 'off',
     'one-var': 'off',
-    // DEFINE POLICY: 'one-var-declaration-per-line': 'off',
+    'one-var-declaration-per-line': ['warn', 'initializations'],
     'operator-assignment': 'off',
     'operator-linebreak': 'off',
     'padded-blocks': 'off',
-    // DEFINE POLICY: 'quote-props': 'off',
+    'quote-props': ['warn', 'as-needed', {'unnecessary': false, 'keywords': true, 'numbers': true}],
     'quotes': 'off',
     'require-jsdoc': 'warn',
     'semi': 'error',
index 5a32a60..da666ee 100644 (file)
@@ -36,15 +36,20 @@ env:
     # Perform an upgrade test too.
     - DB=pgsql    TASK=UPGRADE
 
-    # Run a check for unbuilt files with Grunt.
-    - DB=none     TASK=GRUNT
-
 matrix:
     # Enable fast finish.
     # This will fail the build if a single job fails (except those in allow_failures).
     # It will not stop the jobs from running.
     fast_finish: true
 
+    include:
+          # Run grunt/npm install on lowest supported npm version
+        - php: 7
+          env: DB=none     TASK=GRUNT   NVM_VERSION='4'
+          # Run grunt/npm install on highest version ('node' is an alias for the latest node.js version.)
+        - php: 7
+          env: DB=none     TASK=GRUNT   NVM_VERSION='node'
+
     exclude:
         # MySQL - it's just too slow.
         # Exclude it on all versions except for 7.0
@@ -52,10 +57,6 @@ matrix:
         - env: DB=mysqli   TASK=PHPUNIT
           php: 5.6
 
-       # One grunt execution is enough.
-        - env: DB=none     TASK=GRUNT
-          php: 5.6
-
         # Moodle 2.7 is not compatible with PHP 7 for the upgrade test.
         - env: DB=pgsql    TASK=UPGRADE
           php: 7.0
@@ -69,14 +70,26 @@ install:
     # Disable xdebug. We aren't generating code coverage, and it has a huge impact upon test performance.
     - rm /home/travis/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
 
-    # Set the encrypted GITHUB_TOKEN if it's available to raise the API limit.
-    - if [ -n "$GITHUB_APITOKEN" ]; then composer config github-oauth.github.com $GITHUB_APITOKEN; fi
-    - echo 'auth.json' >> .git/info/exclude
+    - >
+        if [ "$TASK" = 'PHPUNIT' ];
+        then
+            if [ -n "$GITHUB_APITOKEN" ]; then
+                composer config github-oauth.github.com $GITHUB_APITOKEN;
+                echo 'auth.json' >> .git/info/exclude
+            fi
+
+            # Install composer dependencies.
+            # We need --no-interaction in case we hit API limits for composer. This causes it to fall back to a standard clone.
+            # Typically it should be able to use the Composer cache if any other job has already completed before we started here.
+            travis_retry composer install --prefer-dist --no-interaction;
+        fi
 
-    # Install composer dependencies.
-    # We need --no-interaction in case we hit API limits for composer. This causes it to fall back to a standard clone.
-    # Typically it should be able to use the Composer cache if any other job has already completed before we started here.
-    - travis_retry composer install --prefer-dist --no-interaction
+    - >
+        if [ "$TASK" = 'GRUNT' ];
+        then
+            nvm install $NVM_VERSION ;
+            nvm use $NVM_VERSION ;
+        fi
 
 before_script:
     - >
@@ -143,9 +156,8 @@ before_script:
     - >
       if [ "$TASK" = 'GRUNT' ];
       then
-        npm install ;
-        npm install -g grunt ;
-        grunt ;
+        npm install --no-spin;
+        npm install --no-spin -g grunt ;
       fi
 
     ########################################################################
@@ -217,6 +229,7 @@ script:
     - >
       if [ "$TASK" = 'GRUNT' ];
       then
+        grunt ;
         # Add all files to the git index and then run diff --cached to see all changes.
         # This ensures that we get the status of all files, including new files.
         git add . ;
index 0b52cc8..467f13b 100644 (file)
@@ -104,18 +104,26 @@ module.exports = function(grunt) {
         eslint: {
             // Even though warnings dont stop the build we don't display warnings by default because
             // at this moment we've got too many core warnings.
-            options: { quiet: !grunt.option('show-lint-warnings') },
-            // Check AMD files. We add some stricter rules which we can't apply to the default configuration due
-            // to YUI rollups.
+            options: {quiet: !grunt.option('show-lint-warnings')},
             amd: {
               src: amdSrc,
-              options: {
-                  rules: {'no-undef': 'error', 'no-unused-vars': 'error', 'no-empty': 'error', 'no-unused-expressions': 'error'}
+              // Check AMD with some slightly stricter rules.
+              rules: {
+                'no-unused-vars': 'error',
+                'no-implicit-globals': 'error'
               }
             },
             // Check YUI module source files.
             yui: {
                src: ['**/yui/src/**/*.js', '!*/**/yui/src/*/meta/*.js'],
+               options: {
+                   // Disable some rules which we can't safely define for YUI rollups.
+                   rules: {
+                     'no-undef': 'off',
+                     'no-unused-vars': 'off',
+                     'no-unused-expressions': 'off'
+                   }
+               }
             }
         },
         uglify: {
@@ -124,7 +132,8 @@ module.exports = function(grunt) {
                     expand: true,
                     src: amdSrc,
                     rename: uglifyRename
-                }]
+                }],
+                options: {report: 'none'}
             }
         },
         less: {
index 27f4ca9..a1535d1 100644 (file)
@@ -29,10 +29,23 @@ define('CLI_SCRIPT', true);
 require(__DIR__.'/../../config.php');
 require_once($CFG->libdir.'/clilib.php');      // cli only functions
 
+// Define the input options.
+$longparams = array(
+        'help' => false,
+        'username' => '',
+        'password' => '',
+        'ignore-password-policy' => false
+);
+
+$shortparams = array(
+        'h' => 'help',
+        'u' => 'username',
+        'p' => 'password',
+        'i' => 'ignore-password-policy'
+);
 
 // now get cli options
-list($options, $unrecognized) = cli_get_params(array('help'=>false),
-                                               array('h'=>'help'));
+list($options, $unrecognized) = cli_get_params($longparams, $shortparams);
 
 if ($unrecognized) {
     $unrecognized = implode("\n  ", $unrecognized);
@@ -47,29 +60,43 @@ There are no security checks here because anybody who is able to
 execute this file may execute any PHP too.
 
 Options:
--h, --help            Print out this help
+-h, --help                    Print out this help
+-u, --username=username       Specify username to change
+-p, --password=newpassword    Specify new password
+--ignore-password-policy      Ignore password policy when setting password
 
 Example:
 \$sudo -u www-data /usr/bin/php admin/cli/reset_password.php
+\$sudo -u www-data /usr/bin/php admin/cli/reset_password.php --username=rosaura --password=jiu3jiu --ignore-password-policy
 "; //TODO: localize - to be translated later when everything is finished
 
     echo $help;
     die;
 }
-cli_heading('Password reset'); // TODO: localize
-$prompt = "enter username (manual authentication only)"; // TODO: localize
-$username = cli_input($prompt);
+if ($options['username'] == '' ) {
+    cli_heading('Password reset'); // TODO: localize.
+    $prompt = "enter username (manual authentication only)"; // TODO: localize.
+    $username = cli_input($prompt);
+} else {
+    $username = $options['username'];
+}
 
 if (!$user = $DB->get_record('user', array('auth'=>'manual', 'username'=>$username, 'mnethostid'=>$CFG->mnet_localhost_id))) {
     cli_error("Can not find user '$username'");
 }
 
-$prompt = "Enter new password"; // TODO: localize
-$password = cli_input($prompt);
+if ($options['password'] == '' ) {
+    $prompt = "Enter new password"; // TODO: localize.
+    $password = cli_input($prompt);
+} else {
+    $password = $options['password'];
+}
 
 $errmsg = '';//prevent eclipse warning
-if (!check_password_policy($password, $errmsg)) {
-    cli_error($errmsg);
+if (!$options['ignore-password-policy'] ) {
+    if (!check_password_policy($password, $errmsg)) {
+        cli_error($errmsg);
+    }
 }
 
 $hashedpassword = hash_internal_user_password($password);
@@ -78,4 +105,4 @@ $DB->set_field('user', 'password', $hashedpassword, array('id'=>$user->id));
 
 echo "Password changed\n";
 
-exit(0); // 0 means success
\ No newline at end of file
+exit(0); // 0 means success.
index 382c252..2cf9d1a 100644 (file)
@@ -52,6 +52,12 @@ if (!function_exists('json_encode') || !function_exists('json_decode')) {
     die();
 }
 
+// Make sure xml extension is available.
+if (!extension_loaded('xml')) {
+    echo 'Moodle requires the xml PHP extension. Please install or enable the xml extension.';
+    die();
+}
+
 define('NO_OUTPUT_BUFFERING', true);
 
 if (isset($_POST['upgradekey'])) {
diff --git a/admin/searchareas.php b/admin/searchareas.php
new file mode 100644 (file)
index 0000000..884d5b8
--- /dev/null
@@ -0,0 +1,180 @@
+<?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/>.
+
+/**
+ * Manage global search areas.
+ *
+ * @package   core_search
+ * @copyright 2016 Dan Poltawski <dan@moodle.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+require_once(__DIR__ . '/../config.php');
+require_once($CFG->libdir . '/adminlib.php');
+
+admin_externalpage_setup('searchareas');
+
+$areaid = optional_param('areaid', null, PARAM_ALPHAEXT);
+$action = optional_param('action', null, PARAM_ALPHA);
+
+try {
+    $searchmanager = \core_search\manager::instance();
+} catch (core_search\engine_exception $searchmanagererror) {
+    // Continue, we return an error later depending on the requested action.
+}
+
+echo $OUTPUT->header();
+
+if ($action) {
+    require_sesskey();
+
+    if ($areaid) {
+        // We need to check that the area exists.
+        $area = \core_search\manager::get_search_area($areaid);
+        if ($area === false) {
+            throw new moodle_exception('invalidrequest');
+        }
+    }
+
+    // All actions but enable/disable need the search engine to be ready.
+    if ($action !== 'enable' && $action !== 'disable') {
+        if (!empty($searchmanagererror)) {
+            throw $searchmanagererror;
+        }
+    }
+
+    switch ($action) {
+        case 'enable':
+            $area->set_enabled(true);
+            echo $OUTPUT->notification(get_string('searchareaenabled', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+            break;
+        case 'disable':
+            $area->set_enabled(false);
+            echo $OUTPUT->notification(get_string('searchareadisabled', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+            break;
+        case 'delete':
+            $search = \core_search\manager::instance();
+            $search->delete_index($areaid);
+            echo $OUTPUT->notification(get_string('searchindexdeleted', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+            break;
+        case 'indexall':
+            $searchmanager->index();
+            echo $OUTPUT->notification(get_string('searchindexupdated', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+            break;
+        case 'reindexall':
+            $searchmanager->index(true);
+            echo $OUTPUT->notification(get_string('searchreindexed', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+            break;
+        case 'deleteall':
+            $searchmanager->delete_index();
+            echo $OUTPUT->notification(get_string('searchalldeleted', 'admin'), \core\output\notification::NOTIFY_SUCCESS);
+            break;
+        default:
+            throw new moodle_exception('invalidaction');
+            break;
+    }
+}
+
+$searchareas = \core_search\manager::get_search_areas_list();
+if (empty($searchmanagererror)) {
+    $areasconfig = $searchmanager->get_areas_config($searchareas);
+} else {
+    $areasconfig = false;
+}
+
+if (!empty($searchmanagererror)) {
+    $errorstr = get_string($searchmanagererror->errorcode, $searchmanagererror->module);
+    echo $OUTPUT->notification($errorstr, \core\output\notification::NOTIFY_ERROR);
+} else {
+    echo $OUTPUT->notification(get_string('indexinginfo', 'admin'), \core\output\notification::NOTIFY_INFO);
+}
+
+$table = new html_table();
+$table->id = 'core-search-areas';
+
+$table->head = array(get_string('searcharea', 'search'), get_string('enable'), get_string('newestdocindexed', 'admin'),
+    get_string('searchlastrun', 'admin'), get_string('searchindexactions', 'admin'));
+
+foreach ($searchareas as $area) {
+    $areaid = $area->get_area_id();
+    $columns = array(new html_table_cell($area->get_visible_name()));
+
+    if ($area->is_enabled()) {
+        $columns[] = $OUTPUT->action_icon(admin_searcharea_action_url('disable', $areaid),
+            new pix_icon('t/hide', get_string('disable'), 'moodle', array('title' => '', 'class' => 'iconsmall')),
+            null, array('title' => get_string('disable')));
+
+        if ($areasconfig) {
+            $columns[] = $areasconfig[$areaid]->lastindexrun;
+
+            if ($areasconfig[$areaid]->indexingstart) {
+                $timediff = $areasconfig[$areaid]->indexingend - $areasconfig[$areaid]->indexingstart;
+                $laststatus = $timediff . ' , ' .
+                    $areasconfig[$areaid]->docsprocessed . ' , ' .
+                    $areasconfig[$areaid]->recordsprocessed . ' , ' .
+                    $areasconfig[$areaid]->docsignored;
+            } else {
+                $laststatus = '';
+            }
+            $columns[] = $laststatus;
+            $columns[] = html_writer::link(admin_searcharea_action_url('delete', $areaid), 'Delete index');
+
+        } else {
+            $blankrow = new html_table_cell(get_string('searchnotavailable', 'admin'));
+            $blankrow->colspan = 3;
+            $columns[] = $blankrow;
+        }
+
+    } else {
+        $columns[] = $OUTPUT->action_icon(admin_searcharea_action_url('enable', $areaid),
+            new pix_icon('t/show', get_string('enable'), 'moodle', array('title' => '', 'class' => 'iconsmall')),
+                null, array('title' => get_string('enable')));
+
+        $blankrow = new html_table_cell(get_string('searchareadisabled', 'admin'));
+        $blankrow->colspan = 3;
+        $columns[] = $blankrow;
+    }
+    $row = new html_table_row($columns);
+    $table->data[] = $row;
+}
+
+// Cross-search area tasks.
+$options = array();
+if (!empty($searchmanagererror)) {
+    $options['disabled'] = true;
+}
+echo $OUTPUT->box_start('search-areas-actions');
+echo $OUTPUT->single_button(admin_searcharea_action_url('indexall'), get_string('searchupdateindex', 'admin'), 'get', $options);
+echo $OUTPUT->single_button(admin_searcharea_action_url('reindexall'), get_string('searchreindexindex', 'admin'), 'get', $options);
+echo $OUTPUT->single_button(admin_searcharea_action_url('deleteall'), get_string('searchdeleteindex', 'admin'), 'get', $options);
+echo $OUTPUT->box_end();
+
+echo html_writer::table($table);
+echo $OUTPUT->footer();
+
+/**
+ * Helper for generating url for management actions.
+ *
+ * @param string $action
+ * @param string $areaid
+ * @return moodle_url
+ */
+function admin_searcharea_action_url($action, $areaid = false) {
+    $params = array('action' => $action, 'sesskey' => sesskey());
+    if ($areaid) {
+        $params['areaid'] = $areaid;
+    }
+    return new moodle_url('/admin/searchareas.php', $params);
+}
index 680bd3d..0711b23 100644 (file)
@@ -528,15 +528,9 @@ if ($hassiteconfig) {
     $temp->add(new admin_setting_configselect('searchengine',
                                 new lang_string('selectsearchengine', 'admin'), '', 'solr', $engines));
 
-    // Enable search areas.
-    $temp->add(new admin_setting_heading('searchareasheading', new lang_string('availablesearchareas', 'admin'), ''));
-    $searchareas = \core_search\manager::get_search_areas_list();
-    foreach ($searchareas as $areaid => $searcharea) {
-        list($componentname, $varname) = $searcharea->get_config_var_name();
-        $temp->add(new admin_setting_configcheckbox($componentname . '/' . $varname . '_enabled', $searcharea->get_visible_name(true),
-            '', 1, 1, 0));
-    }
     $ADMIN->add('searchplugins', $temp);
+    $ADMIN->add('searchplugins', new admin_externalpage('searchareas', new lang_string('searchareas', 'admin'),
+        new moodle_url('/admin/searchareas.php')));
 
     core_collator::asort_objects_by_property($pages, 'visiblename');
     foreach ($pages as $page) {
index 90062ca..0d03dea 100644 (file)
Binary files a/admin/tool/lp/amd/build/actionselector.min.js and b/admin/tool/lp/amd/build/actionselector.min.js differ
index c14f771..6177d34 100644 (file)
Binary files a/admin/tool/lp/amd/build/competencies.min.js and b/admin/tool/lp/amd/build/competencies.min.js differ
index 39eaef7..4afbdab 100644 (file)
Binary files a/admin/tool/lp/amd/build/competency_rule_points.min.js and b/admin/tool/lp/amd/build/competency_rule_points.min.js differ
index 2ca219d..594bc75 100644 (file)
Binary files a/admin/tool/lp/amd/build/competencyactions.min.js and b/admin/tool/lp/amd/build/competencyactions.min.js differ
index 61eec30..e4312d2 100644 (file)
Binary files a/admin/tool/lp/amd/build/competencypicker.min.js and b/admin/tool/lp/amd/build/competencypicker.min.js differ
index faf4bd4..bf54916 100644 (file)
Binary files a/admin/tool/lp/amd/build/competencypicker_user_plans.min.js and b/admin/tool/lp/amd/build/competencypicker_user_plans.min.js differ
index 8a0f0a2..f5f7f43 100644 (file)
Binary files a/admin/tool/lp/amd/build/competencyruleconfig.min.js and b/admin/tool/lp/amd/build/competencyruleconfig.min.js differ
index 4955f99..4de971d 100644 (file)
Binary files a/admin/tool/lp/amd/build/competencytree.min.js and b/admin/tool/lp/amd/build/competencytree.min.js differ
index ac0c28f..6ea9624 100644 (file)
Binary files a/admin/tool/lp/amd/build/grade_user_competency_inline.min.js and b/admin/tool/lp/amd/build/grade_user_competency_inline.min.js differ
index 7ab1169..f249b03 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 d7732ee..4212884 100644 (file)
Binary files a/admin/tool/lp/amd/build/parentcompetency_form.min.js and b/admin/tool/lp/amd/build/parentcompetency_form.min.js differ
index d590b7e..aeb8b9e 100644 (file)
Binary files a/admin/tool/lp/amd/build/planactions.min.js and b/admin/tool/lp/amd/build/planactions.min.js differ
index db0ffd8..4c5b700 100644 (file)
Binary files a/admin/tool/lp/amd/build/scaleconfig.min.js and b/admin/tool/lp/amd/build/scaleconfig.min.js differ
index 899e3ce..2113400 100644 (file)
Binary files a/admin/tool/lp/amd/build/tree.min.js and b/admin/tool/lp/amd/build/tree.min.js differ
index 8d95549..edd32c2 100644 (file)
Binary files a/admin/tool/lp/amd/build/user_competency_info.min.js and b/admin/tool/lp/amd/build/user_competency_info.min.js differ
index 1c320c8..610c935 100644 (file)
Binary files a/admin/tool/lp/amd/build/user_competency_plan_popup.min.js and b/admin/tool/lp/amd/build/user_competency_plan_popup.min.js differ
index e479a60..a69a9d8 100644 (file)
Binary files a/admin/tool/lp/amd/build/user_evidence_actions.min.js and b/admin/tool/lp/amd/build/user_evidence_actions.min.js differ
index 8b32a48..582478b 100644 (file)
@@ -87,13 +87,13 @@ define(['jquery',
             self._selectedValue = $("input[type='radio']:checked").val();
             self._find('[data-action="action-selector-confirm"]').removeAttr('disabled');
             self._refresh.bind(self);
-        }.bind(self));
+        });
 
         // Add listener for cancel.
         self._find('[data-action="action-selector-cancel"]').click(function(e) {
             e.preventDefault();
             self.close();
-        }.bind(self));
+        });
 
         // Add listener for confirm.
         self._find('[data-action="action-selector-confirm"]').click(function(e) {
@@ -101,9 +101,9 @@ define(['jquery',
             if (!self._selectedValue.length) {
                 return;
             }
-            self._trigger('save', { action: self._selectedValue });
+            self._trigger('save', {action: self._selectedValue});
             self.close();
-        }.bind(self));
+        });
     };
 
     /**
@@ -131,7 +131,7 @@ define(['jquery',
                 html,
                 self._afterRender.bind(self)
             );
-        }.bind(self)).fail(Notification.exception);
+        }).fail(Notification.exception);
     };
 
     /**
@@ -156,7 +156,7 @@ define(['jquery',
         return self._render().then(function(html) {
             self._find('[data-region="action-selector"]').replaceWith(html);
             self._afterRender();
-        }.bind(self));
+        });
     };
 
     /**
index 8b5ae2e..79e1aa9 100644 (file)
@@ -59,13 +59,13 @@ define(['jquery',
             function(movestring) {
                 dragdrop.dragdrop('movecompetency',
                                   movestring,
-                                  { identifier: 'movecompetency', component: 'tool_lp'},
-                                  { identifier: 'movecompetencyafter', component: 'tool_lp'},
+                                  {identifier: 'movecompetency', component: 'tool_lp'},
+                                  {identifier: 'movecompetencyafter', component: 'tool_lp'},
                                   'drag-samenode',
                                   'drag-parentnode',
                                   'drag-handlecontainer',
                                   function(drag, drop) {
-                                      localthis.handleDrop.call(localthis, drag, drop);
+                                      localthis.handleDrop(drag, drop);
                                   });
             }
         ).fail(notification.exception);
@@ -89,21 +89,21 @@ define(['jquery',
             requests = ajax.call([
                 {
                     methodname: 'core_competency_reorder_course_competency',
-                    args: { courseid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
+                    args: {courseid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid}
                 }
             ]);
         } else if (localthis.itemtype == 'template') {
             requests = ajax.call([
                 {
                     methodname: 'core_competency_reorder_template_competency',
-                    args: { templateid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
+                    args: {templateid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid}
                 }
             ]);
         } else if (localthis.itemtype == 'plan') {
             requests = ajax.call([
                 {
                     methodname: 'core_competency_reorder_plan_competency',
-                    args: { planid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid }
+                    args: {planid: localthis.itemid, competencyidfrom: fromid, competencyidto: toid}
                 }
             ]);
         } else {
@@ -139,12 +139,12 @@ define(['jquery',
                     $.each(compIds, function(index, compId) {
                         requests.push({
                             methodname: 'core_competency_add_competency_to_course',
-                            args: { courseid: self.itemid, competencyid: compId }
+                            args: {courseid: self.itemid, competencyid: compId}
                         });
                     });
                     requests.push({
                         methodname: 'tool_lp_data_for_course_competencies_page',
-                        args: { courseid: self.itemid }
+                        args: {courseid: self.itemid}
                     });
 
                     pagerender = 'tool_lp/course_competencies_page';
@@ -156,12 +156,12 @@ define(['jquery',
                     $.each(compIds, function(index, compId) {
                         requests.push({
                             methodname: 'core_competency_add_competency_to_template',
-                            args: { templateid: self.itemid, competencyid: compId }
+                            args: {templateid: self.itemid, competencyid: compId}
                         });
                     });
                     requests.push({
                         methodname: 'tool_lp_data_for_template_competencies_page',
-                        args: { templateid: self.itemid, pagecontext: { contextid: self.pageContextId }}
+                        args: {templateid: self.itemid, pagecontext: {contextid: self.pageContextId}}
                     });
                     pagerender = 'tool_lp/template_competencies_page';
                     pageregion = 'templatecompetenciespage';
@@ -171,12 +171,12 @@ define(['jquery',
                     $.each(compIds, function(index, compId) {
                         requests.push({
                             methodname: 'core_competency_add_competency_to_plan',
-                            args: { planid: self.itemid, competencyid: compId }
+                            args: {planid: self.itemid, competencyid: compId}
                         });
                     });
                     requests.push({
                          methodname: 'tool_lp_data_for_plan_page',
-                         args: { planid: self.itemid}
+                         args: {planid: self.itemid}
                     });
                     pagerender = 'tool_lp/plan_page';
                     pageregion = 'plan-page';
@@ -209,28 +209,28 @@ define(['jquery',
         // Delete the link and reload the page template.
         if (localthis.itemtype == 'course') {
             requests = ajax.call([
-                { methodname: 'core_competency_remove_competency_from_course',
-                    args: { courseid: localthis.itemid, competencyid: deleteid } },
-                { methodname: 'tool_lp_data_for_course_competencies_page',
-                    args: { courseid: localthis.itemid } }
+                {methodname: 'core_competency_remove_competency_from_course',
+                    args: {courseid: localthis.itemid, competencyid: deleteid}},
+                {methodname: 'tool_lp_data_for_course_competencies_page',
+                    args: {courseid: localthis.itemid}}
             ]);
             pagerender = 'tool_lp/course_competencies_page';
             pageregion = 'coursecompetenciespage';
         } else if (localthis.itemtype == 'template') {
             requests = ajax.call([
-                { methodname: 'core_competency_remove_competency_from_template',
-                    args: { templateid: localthis.itemid, competencyid: deleteid } },
-                { methodname: 'tool_lp_data_for_template_competencies_page',
-                    args: { templateid: localthis.itemid, pagecontext: { contextid: localthis.pageContextId } } }
+                {methodname: 'core_competency_remove_competency_from_template',
+                    args: {templateid: localthis.itemid, competencyid: deleteid}},
+                {methodname: 'tool_lp_data_for_template_competencies_page',
+                    args: {templateid: localthis.itemid, pagecontext: {contextid: localthis.pageContextId}}}
             ]);
             pagerender = 'tool_lp/template_competencies_page';
             pageregion = 'templatecompetenciespage';
         } else if (localthis.itemtype == 'plan') {
             requests = ajax.call([
-                { methodname: 'core_competency_remove_competency_from_plan',
-                    args: { planid: localthis.itemid, competencyid: deleteid } },
-                { methodname: 'tool_lp_data_for_plan_page',
-                    args: { planid: localthis.itemid } }
+                {methodname: 'core_competency_remove_competency_from_plan',
+                    args: {planid: localthis.itemid, competencyid: deleteid}},
+                {methodname: 'tool_lp_data_for_plan_page',
+                    args: {planid: localthis.itemid}}
             ]);
             pagerender = 'tool_lp/plan_page';
             pageregion = 'plan-page';
@@ -268,15 +268,15 @@ define(['jquery',
 
         requests = ajax.call([{
             methodname: 'core_competency_read_competency',
-            args: { id: deleteid }
+            args: {id: deleteid}
         }]);
 
         requests[0].done(function(competency) {
             str.get_strings([
-                { key: 'confirm', component: 'moodle' },
-                { key: message, component: 'tool_lp', param: competency.shortname },
-                { key: 'confirm', component: 'moodle' },
-                { key: 'cancel', component: 'moodle' }
+                {key: 'confirm', component: 'moodle'},
+                {key: message, component: 'tool_lp', param: competency.shortname},
+                {key: 'confirm', component: 'moodle'},
+                {key: 'cancel', component: 'moodle'}
             ]).done(function(strings) {
                 notification.confirm(
                     strings[0], // Confirm.
@@ -308,10 +308,10 @@ define(['jquery',
                 var coursecompetencyid = $(e.target).data('id');
                 var ruleoutcome = $(e.target).val();
                 requests = ajax.call([
-                    { methodname: 'core_competency_set_course_competency_ruleoutcome',
-                      args: { coursecompetencyid: coursecompetencyid, ruleoutcome: ruleoutcome } },
-                    { methodname: 'tool_lp_data_for_course_competencies_page',
-                      args: { courseid: localthis.itemid } }
+                    {methodname: 'core_competency_set_course_competency_ruleoutcome',
+                      args: {coursecompetencyid: coursecompetencyid, ruleoutcome: ruleoutcome}},
+                    {methodname: 'tool_lp_data_for_course_competencies_page',
+                      args: {courseid: localthis.itemid}}
                 ]);
 
                 requests[1].done(function(context) {
index 36b2a68..829b892 100644 (file)
@@ -46,16 +46,16 @@ define(['jquery',
         getAll: function() {
             var self = this;
             return Str.get_strings([
-                { key: 'competencyoutcome_none', component: 'tool_lp' },
-                { key: 'competencyoutcome_evidence', component: 'tool_lp' },
-                { key: 'competencyoutcome_recommend', component: 'tool_lp' },
-                { key: 'competencyoutcome_complete', component: 'tool_lp' },
+                {key: 'competencyoutcome_none', component: 'tool_lp'},
+                {key: 'competencyoutcome_evidence', component: 'tool_lp'},
+                {key: 'competencyoutcome_recommend', component: 'tool_lp'},
+                {key: 'competencyoutcome_complete', component: 'tool_lp'},
             ]).then(function(strings) {
                 var outcomes = {};
-                outcomes[self.NONE] = { code: self.NONE, name: strings[0] };
-                outcomes[self.EVIDENCE] = { code: self.EVIDENCE, name: strings[1] };
-                outcomes[self.RECOMMEND] = { code: self.RECOMMEND, name: strings[2] };
-                outcomes[self.COMPLETE] = { code: self.COMPLETE, name: strings[3] };
+                outcomes[self.NONE] = {code: self.NONE, name: strings[0]};
+                outcomes[self.EVIDENCE] = {code: self.EVIDENCE, name: strings[1]};
+                outcomes[self.RECOMMEND] = {code: self.RECOMMEND, name: strings[2]};
+                outcomes[self.COMPLETE] = {code: self.COMPLETE, name: strings[3]};
                 return outcomes;
             });
         },
index db4bfe4..5c4ec17 100644 (file)
@@ -115,7 +115,7 @@ define(['jquery',
             children = this._tree.getChildren(this._competency.id),
             context,
             config = {
-                base: { points: 2 },
+                base: {points: 2},
                 competencies: []
             };
 
index c9c37bc..522e827 100644 (file)
@@ -82,10 +82,10 @@ define(['jquery',
 
         if (parent !== null && treeModel.hasRule(parent.id)) {
             str.get_strings([
-                { key: 'confirm', component: 'moodle' },
-                { key: 'addingcompetencywillresetparentrule', component: 'tool_lp', param: parent.shortname },
-                { key: 'yes', component: 'core' },
-                { key: 'no', component: 'core' }
+                {key: 'confirm', component: 'moodle'},
+                {key: 'addingcompetencywillresetparentrule', component: 'tool_lp', param: parent.shortname},
+                {key: 'yes', component: 'core'},
+                {key: 'no', component: 'core'}
             ]).done(function(strings) {
                 notification.confirm(
                     strings[0],
@@ -108,11 +108,11 @@ define(['jquery',
         var frameworkid = $('[data-region="filtercompetencies"]').data('frameworkid');
         var requests = ajax.call([{
             methodname: 'core_competency_set_parent_competency',
-            args: { competencyid: moveSource, parentid: moveTarget }
+            args: {competencyid: moveSource, parentid: moveTarget}
         }, {
             methodname: 'tool_lp_data_for_competencies_manage_page',
-            args: { competencyframeworkid: frameworkid,
-                    search: $('[data-region="filtercompetencies"] input').val() }
+            args: {competencyframeworkid: frameworkid,
+                    search: $('[data-region="filtercompetencies"] input').val()}
         }]);
         requests[1].done(reloadPage).fail(notification.exception);
     };
@@ -153,10 +153,10 @@ define(['jquery',
         // Show confirm, and/or do the things.
         if (showConfirm) {
             str.get_strings([
-                { key: 'confirm', component: 'moodle' },
-                { key: confirmMessage, component: 'tool_lp' },
-                { key: 'yes', component: 'moodle' },
-                { key: 'no', component: 'moodle' }
+                {key: 'confirm', component: 'moodle'},
+                {key: confirmMessage, component: 'tool_lp'},
+                {key: 'yes', component: 'moodle'},
+                {key: 'no', component: 'moodle'}
             ]).done(function(strings) {
                 notification.confirm(
                     strings[0], // Confirm.
@@ -248,7 +248,8 @@ define(['jquery',
         $.when.apply(null, requests).done(function(competencies, framework) {
 
             // Expand the list of competencies into a tree.
-            var i, competenciestree = [];
+            var i;
+            var competenciestree = [];
             for (i = 0; i < competencies.length; i++) {
                 var onecompetency = competencies[i];
                 if (onecompetency.parentid == "0") {
@@ -260,9 +261,9 @@ define(['jquery',
             }
 
             str.get_strings([
-                { key: 'movecompetency', component: 'tool_lp', param: competency.shortname },
-                { key: 'move', component: 'tool_lp' },
-                { key: 'cancel', component: 'moodle' }
+                {key: 'movecompetency', component: 'tool_lp', param: competency.shortname},
+                {key: 'move', component: 'tool_lp'},
+                {key: 'cancel', component: 'moodle'}
             ]).done(function(strings) {
 
                 var context = {
@@ -330,8 +331,8 @@ define(['jquery',
 
         var requests = ajax.call([{
             methodname: 'tool_lp_data_for_competencies_manage_page',
-            args: { competencyframeworkid: frameworkid,
-                    search: $('[data-region="filtercompetencies"] input').val() }
+            args: {competencyframeworkid: frameworkid,
+                    search: $('[data-region="filtercompetencies"] input').val()}
         }]);
         requests[0].done(reloadPage).fail(notification.exception);
     };
@@ -345,11 +346,11 @@ define(['jquery',
         var competency = $('[data-region="competencyactions"]').data('competency');
         var requests = ajax.call([{
             methodname: 'core_competency_move_up_competency',
-            args: { id: competency.id }
+            args: {id: competency.id}
         }, {
             methodname: 'tool_lp_data_for_competencies_manage_page',
-            args: { competencyframeworkid: competency.competencyframeworkid,
-                    search: $('[data-region="filtercompetencies"] input').val() }
+            args: {competencyframeworkid: competency.competencyframeworkid,
+                    search: $('[data-region="filtercompetencies"] input').val()}
         }]);
         requests[1].done(reloadPage).fail(notification.exception);
     };
@@ -363,11 +364,11 @@ define(['jquery',
         var competency = $('[data-region="competencyactions"]').data('competency');
         var requests = ajax.call([{
             methodname: 'core_competency_move_down_competency',
-            args: { id: competency.id }
+            args: {id: competency.id}
         }, {
             methodname: 'tool_lp_data_for_competencies_manage_page',
-            args: { competencyframeworkid: competency.competencyframeworkid,
-                    search: $('[data-region="filtercompetencies"] input').val() }
+            args: {competencyframeworkid: competency.competencyframeworkid,
+                    search: $('[data-region="filtercompetencies"] input').val()}
         }]);
         requests[1].done(reloadPage).fail(notification.exception);
     };
@@ -381,7 +382,7 @@ define(['jquery',
 
         var requests = ajax.call([{
             methodname: 'tool_lp_list_courses_using_competency',
-            args: { id: competency.id }
+            args: {id: competency.id}
         }]);
 
         requests[0].done(function(courses) {
@@ -417,13 +418,13 @@ define(['jquery',
                 $.each(compIds, function(index, value) {
                     calls.push({
                         methodname: 'core_competency_add_related_competency',
-                        args: { competencyid: value, relatedcompetencyid: relatedTarget.id }
+                        args: {competencyid: value, relatedcompetencyid: relatedTarget.id}
                     });
                 });
 
                 calls.push({
                     methodname: 'tool_lp_data_for_related_competencies_section',
-                    args: { competencyid: relatedTarget.id }
+                    args: {competencyid: relatedTarget.id}
                 });
 
                 var promises = ajax.call(calls);
@@ -462,7 +463,7 @@ define(['jquery',
         };
         var promise = ajax.call([{
             methodname: 'core_competency_update_competency',
-            args: { competency: update }
+            args: {competency: update}
         }]);
         promise[0].then(function(result) {
             if (result) {
@@ -483,17 +484,17 @@ define(['jquery',
         var competency = $('[data-region="competencyactions"]').data('competency');
         var requests = ajax.call([{
             methodname: 'core_competency_delete_competency',
-            args: { id: competency.id }
+            args: {id: competency.id}
         }, {
             methodname: 'tool_lp_data_for_competencies_manage_page',
-            args: { competencyframeworkid: competency.competencyframeworkid,
-                    search: $('[data-region="filtercompetencies"] input').val() }
+            args: {competencyframeworkid: competency.competencyframeworkid,
+                    search: $('[data-region="filtercompetencies"] input').val()}
         }]);
         requests[0].done(function(success) {
             if (success === false) {
                 str.get_strings([
-                { key: 'competencycannotbedeleted', component: 'tool_lp', param: competency.shortname },
-                { key: 'cancel', component: 'moodle' }
+                {key: 'competencycannotbedeleted', component: 'tool_lp', param: competency.shortname},
+                {key: 'cancel', component: 'moodle'}
                 ]).done(function(strings) {
                     notification.alert(
                         null,
@@ -518,10 +519,10 @@ define(['jquery',
         }
 
         str.get_strings([
-            { key: 'confirm', component: 'moodle' },
-            { key: confirmMessage, component: 'tool_lp', param: competency.shortname },
-            { key: 'delete', component: 'moodle' },
-            { key: 'cancel', component: 'moodle' }
+            {key: 'confirm', component: 'moodle'},
+            {key: confirmMessage, component: 'tool_lp', param: competency.shortname},
+            {key: 'delete', component: 'moodle'},
+            {key: 'cancel', component: 'moodle'}
         ]).done(function(strings) {
             notification.confirm(
                 strings[0], // Confirm.
@@ -598,18 +599,18 @@ define(['jquery',
         var relatedid = this.id.substr(11);
         var competency = $('[data-region="competencyactions"]').data('competency');
         var removeRelated = ajax.call([
-            { methodname: 'core_competency_remove_related_competency',
-              args: { relatedcompetencyid: relatedid, competencyid: competency.id } },
-            { methodname: 'tool_lp_data_for_related_competencies_section',
-              args: { competencyid: competency.id } }
+            {methodname: 'core_competency_remove_related_competency',
+              args: {relatedcompetencyid: relatedid, competencyid: competency.id}},
+            {methodname: 'tool_lp_data_for_related_competencies_section',
+              args: {competencyid: competency.id}}
         ]);
 
         removeRelated[1].done(function(context) {
             templates.render('tool_lp/related_competencies', context).done(function(html) {
                 $('[data-region="relatedcompetencies"]').replaceWith(html);
                 updatedRelatedCompetencies();
-            }.bind(this)).fail(notification.exception);
-        }.bind(this)).fail(notification.exception);
+            }).fail(notification.exception);
+        }).fail(notification.exception);
     };
 
     /**
@@ -636,7 +637,7 @@ define(['jquery',
             selectedCompetencyId = competency.id;
             ajax.call([{
                     methodname: 'core_competency_competency_viewed',
-                    args: { id: competency.id }
+                    args: {id: competency.id}
             }]);
         }
     };
@@ -703,7 +704,7 @@ define(['jquery',
         }).done(function() {
             ajax.call([{
                 methodname: 'tool_lp_data_for_related_competencies_section',
-                args: { competencyid: competency.id },
+                args: {competencyid: competency.id},
                 done: function(context) {
                     return templates.render('tool_lp/related_competencies', context).done(function(html, js) {
                         $('[data-region="relatedcompetencies"]').replaceWith(html);
index 9902eed..012d70b 100644 (file)
@@ -55,7 +55,7 @@ define(['jquery',
     Competencydialogue.prototype.triggerCompetencyViewedEvent = function(competencyId) {
         ajax.call([{
                 methodname: 'core_competency_competency_viewed',
-                args: { id: competencyId }
+                args: {id: competencyId}
         }]);
     };
 
@@ -143,8 +143,8 @@ define(['jquery',
     Competencydialogue.prototype.getCompetencyDataPromise = function(competencyid, options) {
 
         var requests = ajax.call([
-            { methodname: 'tool_lp_data_for_competency_summary',
-              args: { competencyid: competencyid,
+            {methodname: 'tool_lp_data_for_competency_summary',
+              args: {competencyid: competencyid,
                       includerelated: options.includerelated || false,
                       includecourses: options.includecourses || false
                     }
@@ -170,7 +170,7 @@ define(['jquery',
 
             // Instantiate the one instance and delegate event on the body.
             instance = new Competencydialogue();
-            $('body').delegate('[data-action="competency-dialogue"]', 'click', { compdialogue: instance },
+            $('body').delegate('[data-action="competency-dialogue"]', 'click', {compdialogue: instance},
                 instance.clickEventHandler.bind(instance));
         }
     };
index 272d3e0..1aebe05 100644 (file)
@@ -118,7 +118,7 @@ define(['jquery',
                 if (valid) {
                     validIds.push(compId);
                 }
-            }.bind(self));
+            });
 
             self._selectedCompetencies = validIds;
 
@@ -128,14 +128,14 @@ define(['jquery',
             } else {
                 self._find('[data-region="competencylinktree"] [data-action="add"]').removeAttr('disabled');
             }
-        }.bind(self));
+        });
 
         // Add listener for framework change.
         if (!self._singleFramework) {
             self._find('[data-action="chooseframework"]').change(function(e) {
                 self._frameworkId = $(e.target).val();
                 self._loadCompetencies().then(self._refresh.bind(self));
-            }.bind(self));
+            });
         }
 
         // Add listener for search.
@@ -146,13 +146,13 @@ define(['jquery',
             return self._refresh().always(function() {
                 $(e.target).removeAttr('disabled');
             });
-        }.bind(self));
+        });
 
         // Add listener for cancel.
         self._find('[data-region="competencylinktree"] [data-action="cancel"]').click(function(e) {
             e.preventDefault();
             self.close();
-        }.bind(self));
+        });
 
         // Add listener for add.
         self._find('[data-region="competencylinktree"] [data-action="add"]').click(function(e) {
@@ -162,14 +162,14 @@ define(['jquery',
             }
 
             if (self._multiSelect) {
-                self._trigger('save', { competencyIds: self._selectedCompetencies });
+                self._trigger('save', {competencyIds: self._selectedCompetencies});
             } else {
                 // We checked above that the array has at least one value.
-                self._trigger('save', { competencyId: self._selectedCompetencies[0] });
+                self._trigger('save', {competencyId: self._selectedCompetencies[0]});
             }
 
             self.close();
-        }.bind(self));
+        });
 
         // The list of selected competencies will be modified while looping (because of the listeners above).
         var currentItems = self._selectedCompetencies.slice(0);
@@ -180,7 +180,7 @@ define(['jquery',
                 tree.toggleItem(node);
                 tree.updateFocus(node);
             }
-        }.bind(self));
+        });
 
     };
 
@@ -210,8 +210,8 @@ define(['jquery',
                     html,
                     self._afterRender.bind(self)
                 );
-            }.bind(self));
-        }.bind(self)).fail(Notification.exception);
+            });
+        }).fail(Notification.exception);
     };
 
     /**
@@ -226,7 +226,7 @@ define(['jquery',
         var self = this;
 
         return Ajax.call([
-            { methodname: 'core_competency_search_competencies', args: {
+            {methodname: 'core_competency_search_competencies', args: {
                 searchtext: searchText,
                 competencyframeworkid: frameworkId
             }}
@@ -248,7 +248,8 @@ define(['jquery',
             }
 
             // Expand the list of competencies into a tree.
-            var i, tree = [], comp;
+            var i, comp;
+            var tree = [];
             for (i = 0; i < competencies.length; i++) {
                 comp = competencies[i];
                 if (comp.parentid == "0") { // Loose check for now, because WS returns a string.
@@ -261,7 +262,7 @@ define(['jquery',
 
             self._competencies = tree;
 
-        }.bind(self)).fail(Notification.exception);
+        }).fail(Notification.exception);
     };
 
     /**
@@ -287,7 +288,7 @@ define(['jquery',
         $.each(this._frameworks, function(i, f) {
             if (f.id == fid) {
                 frm = f;
-                return false;
+                return;
             }
         });
         return frm;
@@ -320,7 +321,7 @@ define(['jquery',
 
         if (self._singleFramework) {
             promise = Ajax.call([
-                { methodname: 'core_competency_read_competency_framework', args: {
+                {methodname: 'core_competency_read_competency_framework', args: {
                     id: this._frameworkId
                 }}
             ])[0].then(function(framework) {
@@ -328,9 +329,9 @@ define(['jquery',
             });
         } else {
             promise = Ajax.call([
-                { methodname: 'core_competency_list_competency_frameworks', args: {
+                {methodname: 'core_competency_list_competency_frameworks', args: {
                     sort: 'shortname',
-                    context: { contextid: self._pageContextId },
+                    context: {contextid: self._pageContextId},
                     includes: self._pageContextIncludes,
                     onlyvisible: self._onlyVisible
                 }}
@@ -373,7 +374,7 @@ define(['jquery',
             }
 
             return self._loadCompetencies();
-        }.bind(self));
+        });
     };
 
     /**
@@ -387,7 +388,7 @@ define(['jquery',
         return self._render().then(function(html) {
             self._find('[data-region="competencylinktree"]').replaceWith(html);
             self._afterRender();
-        }.bind(self));
+        });
     };
 
     /**
@@ -419,7 +420,7 @@ define(['jquery',
             };
 
             return Templates.render('tool_lp/competency_picker', context);
-        }.bind(self));
+        });
     };
 
     /**
index b417b67..8d5b536 100644 (file)
@@ -78,7 +78,7 @@ define(['jquery',
             self._find('[data-action="chooseplan"]').change(function(e) {
                 self._planId = $(e.target).val();
                 self._loadCompetencies().then(self._refresh.bind(self));
-            }.bind(self));
+            });
         }
     };
 
@@ -94,13 +94,14 @@ define(['jquery',
         var self = this;
 
         return Ajax.call([
-            { methodname: 'core_competency_list_plan_competencies', args: {
+            {methodname: 'core_competency_list_plan_competencies', args: {
                 id: planId
             }}
         ])[0].done(function(competencies) {
 
             // Expand the list of competencies into a fake tree.
-            var i, tree = [], comp;
+            var i, comp;
+            var tree = [];
             for (i = 0; i < competencies.length; i++) {
                 comp = competencies[i].competency;
                 if (comp.shortname.toLowerCase().indexOf(searchText.toLowerCase()) < 0) {
@@ -128,7 +129,7 @@ define(['jquery',
         $.each(this._plans, function(i, f) {
             if (f.id == id) {
                 plan = f;
-                return false;
+                return;
             }
         });
         return plan;
@@ -161,7 +162,7 @@ define(['jquery',
 
         if (self._singlePlan) {
             promise = Ajax.call([
-                { methodname: 'core_competency_read_plan', args: {
+                {methodname: 'core_competency_read_plan', args: {
                     id: this._planId
                 }}
             ])[0].then(function(plan) {
@@ -169,7 +170,7 @@ define(['jquery',
             });
         } else {
             promise = Ajax.call([
-                { methodname: 'core_competency_list_user_plans', args: {
+                {methodname: 'core_competency_list_user_plans', args: {
                     userid: self._userId
                 }}
             ])[0];
@@ -200,7 +201,7 @@ define(['jquery',
             }
 
             return self._loadCompetencies();
-        }.bind(self));
+        });
     };
 
     /**
@@ -232,7 +233,7 @@ define(['jquery',
             };
 
             return Templates.render('tool_lp/competency_picker_user_plans', context);
-        }.bind(self));
+        });
     };
 
     return /** @alias module:tool_lp/competencypicker_user_plans */ Picker;
index f207939..3a956cb 100644 (file)
@@ -137,7 +137,7 @@ define(['jquery',
         $.each(this._rules, function(index, rule) {
             if (rule.canConfig()) {
                 can = true;
-                return false;
+                return;
             }
         });
         return can;
@@ -163,7 +163,7 @@ define(['jquery',
     RuleConfig.prototype.display = function() {
         var self = this;
         if (!self._competency) {
-            return;
+            return false;
         }
         return self._render().then(function(html) {
             return Str.get_string('competencyrule', 'tool_lp').then(function(title) {
@@ -276,7 +276,7 @@ define(['jquery',
         $.each(this._rules, function(index, rule) {
             if (rule.getType() == type) {
                 result = rule;
-                return false;
+                return;
             }
         });
 
@@ -297,7 +297,7 @@ define(['jquery',
         $.each(self._rulesModules, function(index, modInfo) {
             if (modInfo.type == type) {
                 name = modInfo.name;
-                return false;
+                return;
             }
         });
         return name;
index 1cc3933..06af055 100644 (file)
@@ -52,7 +52,7 @@ define(['jquery',
         var currentValue = $(e.target).closest('a').data('pushratingstouserplans');
         var context = {
             courseid: courseid,
-            settings: { pushratingstouserplans: currentValue }
+            settings: {pushratingstouserplans: currentValue}
         };
         e.preventDefault();
 
@@ -112,11 +112,11 @@ define(['jquery',
 
         var newValue = this._find('input[name="pushratingstouserplans"]:checked').val();
         var courseId = this._find('input[name="courseid"]').val();
-        var settings = { pushratingstouserplans: newValue };
+        var settings = {pushratingstouserplans: newValue};
 
         ajax.call([
-            { methodname: 'core_competency_update_course_competency_settings',
-              args: { courseid: courseId, settings: settings } }
+            {methodname: 'core_competency_update_course_competency_settings',
+              args: {courseid: courseId, settings: settings}}
         ])[0].done(function() {
             this.refreshCourseCompetenciesPage();
         }.bind(this)).fail(notification.exception);
@@ -133,8 +133,8 @@ define(['jquery',
         var courseId = this._find('input[name="courseid"]').val();
 
         ajax.call([
-            { methodname: 'tool_lp_data_for_course_competencies_page',
-              args: { courseid: courseId } }
+            {methodname: 'tool_lp_data_for_course_competencies_page',
+              args: {courseid: courseId}}
         ])[0].done(function(context) {
             templates.render('tool_lp/course_competencies_page', context).done(function(html, js) {
                 $('[data-region="coursecompetenciespage"]').replaceWith(html);
index a94eb30..367cb00 100644 (file)
@@ -67,9 +67,9 @@ define(['core/str', 'core/yui'], function(str, Y) {
             // Here we are wrapping YUI. This allows us to start transitioning, but
             // wait for a good alternative without having inconsistent UIs.
             str.get_strings([
-                { key: 'emptydragdropregion', component: 'moodle' },
-                { key: 'movecontent', component: 'moodle' },
-                { key: 'tocontent', component: 'moodle' },
+                {key: 'emptydragdropregion', component: 'moodle'},
+                {key: 'movecontent', component: 'moodle'},
+                {key: 'tocontent', component: 'moodle'},
             ]).done(function() {
                 Y.use('moodle-tool_lp-dragdrop-reorder', function() {
 
index 44698d1..ac59ad9 100644 (file)
@@ -57,10 +57,10 @@ define(['jquery',
             e.stopPropagation();
 
             Str.get_strings([
-                { key: 'confirm', component: 'moodle' },
-                { key: 'areyousure', component: 'moodle' },
-                { key: 'delete', component: 'moodle' },
-                { key: 'cancel', component: 'moodle' }
+                {key: 'confirm', component: 'moodle'},
+                {key: 'areyousure', component: 'moodle'},
+                {key: 'delete', component: 'moodle'},
+                {key: 'cancel', component: 'moodle'}
             ]).done(function(strings) {
                 Notification.confirm(
                     strings[0], // Confirm.
index 9172c19..486c25c 100644 (file)
@@ -47,7 +47,7 @@ define(['jquery', 'core/ajax', 'core/templates'], function($, Ajax, Templates) {
                 methodname: 'tool_lp_search_cohorts',
                 args: {
                     query: query,
-                    context: { contextid: contextid },
+                    context: {contextid: contextid},
                     includes: includes
                 }
             }]);
index b554495..cb9685f 100644 (file)
@@ -65,7 +65,7 @@ define(['jquery', 'core/templates', 'core/ajax', 'core/notification', 'core/str'
         // We are chaining ajax requests here.
         var requests = ajax.call([{
             methodname: 'core_competency_duplicate_competency_framework',
-            args: { id: frameworkid }
+            args: {id: frameworkid}
         }, {
             methodname: 'tool_lp_data_for_competency_frameworks_manage_page',
             args: {
@@ -84,7 +84,7 @@ define(['jquery', 'core/templates', 'core/ajax', 'core/notification', 'core/str'
         // We are chaining ajax requests here.
         var requests = ajax.call([{
             methodname: 'core_competency_delete_competency_framework',
-            args: { id: frameworkid }
+            args: {id: frameworkid}
         }, {
             methodname: 'tool_lp_data_for_competency_frameworks_manage_page',
             args: {
@@ -97,12 +97,12 @@ define(['jquery', 'core/templates', 'core/ajax', 'core/notification', 'core/str'
             if (success === false) {
                 var req = ajax.call([{
                     methodname: 'core_competency_read_competency_framework',
-                    args: { id: frameworkid }
+                    args: {id: frameworkid}
                 }]);
                 req[0].done(function(framework) {
                     str.get_strings([
-                        { key: 'frameworkcannotbedeleted', component: 'tool_lp', param: framework.shortname },
-                        { key: 'cancel', component: 'moodle' }
+                        {key: 'frameworkcannotbedeleted', component: 'tool_lp', param: framework.shortname},
+                        {key: 'cancel', component: 'moodle'}
                     ]).done(function(strings) {
                         notification.alert(
                             null,
@@ -127,15 +127,15 @@ define(['jquery', 'core/templates', 'core/ajax', 'core/notification', 'core/str'
 
         var requests = ajax.call([{
             methodname: 'core_competency_read_competency_framework',
-            args: { id: frameworkid }
+            args: {id: frameworkid}
         }]);
 
         requests[0].done(function(framework) {
             str.get_strings([
-                { key: 'confirm', component: 'moodle' },
-                { key: 'deletecompetencyframework', component: 'tool_lp', param: framework.shortname },
-                { key: 'delete', component: 'moodle' },
-                { key: 'cancel', component: 'moodle' }
+                {key: 'confirm', component: 'moodle'},
+                {key: 'deletecompetencyframework', component: 'tool_lp', param: framework.shortname},
+                {key: 'delete', component: 'moodle'},
+                {key: 'cancel', component: 'moodle'}
             ]).done(function(strings) {
                 notification.confirm(
                     strings[0], // Confirm.
index 3558b9f..7a030b6 100644 (file)
@@ -118,11 +118,11 @@ define(['jquery',
                     methodname: self._methodName,
                     args: args,
                     done: function(evidence) {
-                        self._trigger('competencyupdated', { args: args, evidence: evidence });
-                    }.bind(self),
+                        self._trigger('competencyupdated', {args: args, evidence: evidence});
+                    },
                     fail: notification.exception
                 }]);
-            }.bind(self));
+            });
         }).fail(notification.exception);
     };
 
index 6889936..0434b56 100644 (file)
@@ -175,7 +175,7 @@ define(['jquery'], function($) {
             if (this.handlers) {
                 $.each(this.handlers, function(selector, handler) {
                     if (eventHandled) {
-                        return false;
+                        return;
                     }
                     if (item.find(selector).length > 0) {
                         var callable = $.proxy(handler, anchor);
index 5a2648b..705ab29 100644 (file)
@@ -69,7 +69,7 @@ define(['jquery', 'core/ajax', 'core/str', 'tool_lp/competencypicker', 'core/tem
 
         if (data.competencyId !== 0) {
             ajax.call([
-                { methodname: 'core_competency_read_competency', args: {
+                {methodname: 'core_competency_read_competency', args: {
                     id: data.competencyId
                 }}
             ])[0].done(function(competency) {
@@ -112,13 +112,13 @@ define(['jquery', 'core/ajax', 'core/str', 'tool_lp/competencypicker', 'core/tem
                     };
 
                     return Templates.render('tool_lp/competency_picker_competencyform', context);
-                }.bind(self));
+                });
             };
 
             // On selected competency.
             picker.on('save', function(e, data) {
                 self.setParent(data);
-            }.bind(self));
+            });
 
             picker.display();
         });
index 39efd98..932318f 100644 (file)
@@ -117,7 +117,7 @@ define(['jquery',
             .done(function(newhtml, newjs) {
                 $(self._region).replaceWith(newhtml);
                 templates.runTemplateJS(newjs);
-            }.bind(self))
+            })
             .fail(notification.exception);
     };
 
@@ -139,7 +139,7 @@ define(['jquery',
         // Apply all the promises, and refresh when the last one is resolved.
         return $.when.apply($.when, ajax.call(calls))
             .then(function() {
-                self._renderView.call(self, arguments[arguments.length - 1]);
+                self._renderView(arguments[arguments.length - 1]);
             })
             .fail(notification.exception);
     };
@@ -153,7 +153,7 @@ define(['jquery',
         var self = this,
             calls = [{
                 methodname: 'core_competency_delete_plan',
-                args: { id: planData.id }
+                args: {id: planData.id}
             }];
         self._callAndRefresh(calls, planData);
     };
@@ -169,15 +169,15 @@ define(['jquery',
 
         requests = ajax.call([{
             methodname: 'core_competency_read_plan',
-            args: { id: planData.id }
+            args: {id: planData.id}
         }]);
 
         requests[0].done(function(plan) {
             str.get_strings([
-                { key: 'confirm', component: 'moodle' },
-                { key: 'deleteplan', component: 'tool_lp', param: plan.name },
-                { key: 'delete', component: 'moodle' },
-                { key: 'cancel', component: 'moodle' }
+                {key: 'confirm', component: 'moodle'},
+                {key: 'deleteplan', component: 'tool_lp', param: plan.name},
+                {key: 'delete', component: 'moodle'},
+                {key: 'cancel', component: 'moodle'}
             ]).done(function(strings) {
                 notification.confirm(
                     strings[0], // Confirm.
@@ -186,7 +186,7 @@ define(['jquery',
                     strings[3], // Cancel.
                     function() {
                         self._doDelete(planData);
-                    }.bind(self)
+                    }
                 );
             }).fail(notification.exception);
         }).fail(notification.exception);
@@ -202,7 +202,7 @@ define(['jquery',
         var self = this,
             calls = [{
                 methodname: 'core_competency_reopen_plan',
-                args: { planid: planData.id}
+                args: {planid: planData.id}
             }];
         self._callAndRefresh(calls, planData);
     };
@@ -216,15 +216,15 @@ define(['jquery',
         var self = this,
             requests = ajax.call([{
                 methodname: 'core_competency_read_plan',
-                args: { id: planData.id }
+                args: {id: planData.id}
             }]);
 
         requests[0].done(function(plan) {
             str.get_strings([
-                { key: 'confirm', component: 'moodle' },
-                { key: 'reopenplanconfirm', component: 'tool_lp', param: plan.name },
-                { key: 'reopenplan', component: 'tool_lp' },
-                { key: 'cancel', component: 'moodle' }
+                {key: 'confirm', component: 'moodle'},
+                {key: 'reopenplanconfirm', component: 'tool_lp', param: plan.name},
+                {key: 'reopenplan', component: 'tool_lp'},
+                {key: 'cancel', component: 'moodle'}
             ]).done(function(strings) {
                 notification.confirm(
                     strings[0], // Confirm.
@@ -233,7 +233,7 @@ define(['jquery',
                     strings[3], // Cancel.
                     function() {
                         self._doReopenPlan(planData);
-                    }.bind(self)
+                    }
                 );
             }).fail(notification.exception);
         }).fail(notification.exception);
@@ -249,7 +249,7 @@ define(['jquery',
         var self = this,
             calls = [{
                 methodname: 'core_competency_complete_plan',
-                args: { planid: planData.id}
+                args: {planid: planData.id}
             }];
         self._callAndRefresh(calls, planData);
     };
@@ -263,15 +263,15 @@ define(['jquery',
         var self = this,
             requests = ajax.call([{
                 methodname: 'core_competency_read_plan',
-                args: { id: planData.id }
+                args: {id: planData.id}
             }]);
 
         requests[0].done(function(plan) {
             str.get_strings([
-                { key: 'confirm', component: 'moodle' },
-                { key: 'completeplanconfirm', component: 'tool_lp', param: plan.name },
-                { key: 'completeplan', component: 'tool_lp' },
-                { key: 'cancel', component: 'moodle' }
+                {key: 'confirm', component: 'moodle'},
+                {key: 'completeplanconfirm', component: 'tool_lp', param: plan.name},
+                {key: 'completeplan', component: 'tool_lp'},
+                {key: 'cancel', component: 'moodle'}
             ]).done(function(strings) {
                 notification.confirm(
                     strings[0], // Confirm.
@@ -280,7 +280,7 @@ define(['jquery',
                     strings[3], // Cancel.
                     function() {
                         self._doCompletePlan(planData);
-                    }.bind(self)
+                    }
                 );
             }).fail(notification.exception);
         }).fail(notification.exception);
@@ -295,7 +295,7 @@ define(['jquery',
         var self = this,
             calls = [{
                 methodname: 'core_competency_unlink_plan_from_template',
-                args: { planid: planData.id}
+                args: {planid: planData.id}
             }];
         self._callAndRefresh(calls, planData);
     };
@@ -309,15 +309,15 @@ define(['jquery',
         var self = this,
             requests = ajax.call([{
                 methodname: 'core_competency_read_plan',
-                args: { id: planData.id }
+                args: {id: planData.id}
             }]);
 
         requests[0].done(function(plan) {
             str.get_strings([
-                { key: 'confirm', component: 'moodle' },
-                { key: 'unlinkplantemplateconfirm', component: 'tool_lp', param: plan.name },
-                { key: 'unlinkplantemplate', component: 'tool_lp' },
-                { key: 'cancel', component: 'moodle' }
+                {key: 'confirm', component: 'moodle'},
+                {key: 'unlinkplantemplateconfirm', component: 'tool_lp', param: plan.name},
+                {key: 'unlinkplantemplate', component: 'tool_lp'},
+                {key: 'cancel', component: 'moodle'}
             ]).done(function(strings) {
                 notification.confirm(
                     strings[0], // Confirm.
@@ -326,7 +326,7 @@ define(['jquery',
                     strings[3], // Cancel.
                     function() {
                         self._doUnlinkPlan(planData);
-                    }.bind(self)
+                    }
                 );
             }).fail(notification.exception);
         }).fail(notification.exception);
@@ -499,7 +499,7 @@ define(['jquery',
         var competencyid = $(e.target).data('id');
         var requests = ajax.call([{
             methodname: 'tool_lp_list_courses_using_competency',
-            args: { id: competencyid }
+            args: {id: competencyid}
         }]);
 
         requests[0].done(function(courses) {
index 9ba1fd4..67c41ee 100644 (file)
@@ -140,7 +140,7 @@ define(['jquery', 'core/notification', 'core/templates', 'core/ajax', 'tool_lp/d
         }.bind(this));
         body.on('click', '[data-action="cancel"]', function() {
             popup.close();
-        }.bind(this));
+        });
     };
 
     /**
@@ -151,7 +151,7 @@ define(['jquery', 'core/notification', 'core/templates', 'core/ajax', 'tool_lp/d
     ScaleConfig.prototype.setScaleConfig = function() {
         var body = $(this.popup.getContent());
         // Get the data.
-        var data = [{ scaleid: this.scaleid}];
+        var data = [{scaleid: this.scaleid}];
         this.scalevalues.forEach(function(value) {
             var scaledefault = 0;
             var proficient = 0;
index e0ceecb..02fb4c5 100644 (file)
@@ -67,8 +67,8 @@ define(['jquery', 'core/templates', 'core/ajax', 'core/notification', 'core/str'
         // We are chaining ajax requests here.
         var requests = ajax.call([{
             methodname: 'core_competency_delete_template',
-            args: { id: templateid,
-                    deleteplans: deleteplans }
+            args: {id: templateid,
+                    deleteplans: deleteplans}
         }, {
             methodname: 'tool_lp_data_for_templates_manage_page',
             args: {
@@ -93,7 +93,7 @@ define(['jquery', 'core/templates', 'core/ajax', 'core/notification', 'core/str'
         // We are chaining ajax requests here.
         var requests = ajax.call([{
             methodname: 'core_competency_duplicate_template',
-            args: { id: templateid }
+            args: {id: templateid}
         }, {
             methodname: 'tool_lp_data_for_templates_manage_page',
             args: {
@@ -119,22 +119,22 @@ define(['jquery', 'core/templates', 'core/ajax', 'core/notification', 'core/str'
 
         var requests = ajax.call([{
             methodname: 'core_competency_read_template',
-            args: { id: templateid }
+            args: {id: templateid}
         }, {
             methodname: 'core_competency_template_has_related_data',
-            args: { id: templateid }
+            args: {id: templateid}
         }]);
 
         requests[0].done(function(template) {
             requests[1].done(function(templatehasrelateddata) {
                 if (templatehasrelateddata) {
                     str.get_strings([
-                        { key: 'deletetemplate', component: 'tool_lp', param: template.shortname },
-                        { key: 'deletetemplatewithplans', component: 'tool_lp' },
-                        { key: 'deleteplans', component: 'tool_lp' },
-                        { key: 'unlinkplanstemplate', component: 'tool_lp' },
-                        { key: 'confirm', component: 'moodle' },
-                        { key: 'cancel', component: 'moodle' }
+                        {key: 'deletetemplate', component: 'tool_lp', param: template.shortname},
+                        {key: 'deletetemplatewithplans', component: 'tool_lp'},
+                        {key: 'deleteplans', component: 'tool_lp'},
+                        {key: 'unlinkplanstemplate', component: 'tool_lp'},
+                        {key: 'confirm', component: 'moodle'},
+                        {key: 'cancel', component: 'moodle'}
                     ]).done(function(strings) {
                         var actions = [{'text': strings[2], 'value': 'delete'},
                                        {'text': strings[3], 'value': 'unlink'}];
@@ -154,10 +154,10 @@ define(['jquery', 'core/templates', 'core/ajax', 'core/notification', 'core/str'
                     }).fail(notification.exception);
                 } else {
                     str.get_strings([
-                        { key: 'confirm', component: 'moodle' },
-                        { key: 'deletetemplate', component: 'tool_lp', param: template.shortname },
-                        { key: 'delete', component: 'moodle' },
-                        { key: 'cancel', component: 'moodle' }
+                        {key: 'confirm', component: 'moodle'},
+                        {key: 'deletetemplate', component: 'tool_lp', param: template.shortname},
+                        {key: 'delete', component: 'moodle'},
+                        {key: 'cancel', component: 'moodle'}
                     ]).done(function(strings) {
                         notification.confirm(
                         strings[0], // Confirm.
index 179dcf6..8d784f2 100644 (file)
@@ -168,7 +168,7 @@ define(['jquery', 'core/url', 'core/log'], function($, url, log) {
         if (!this.multiSelect) {
             allSelected = allSelected.first();
         }
-        this.treeRoot.trigger('selectionchanged', { selected: allSelected });
+        this.treeRoot.trigger('selectionchanged', {selected: allSelected});
     };
 
     /**
@@ -274,6 +274,8 @@ define(['jquery', 'core/url', 'core/log'], function($, url, log) {
      * @param {Event} e The event.
      * @return {Boolean}
      */
+     // This function should be simplified. In the meantime..
+    // eslint-disable-next-line complexity
     Tree.prototype.handleKeyDown = function(item, e) {
         var currentIndex = this.visibleItems.index(item);
         var newItem = null;
index 334e8ff..0e6df71 100644 (file)
@@ -44,15 +44,15 @@ define(['jquery', 'core/notification', 'core/ajax', 'core/templates'], function(
 
         if (this._planId) {
             this._methodName = 'tool_lp_data_for_user_competency_summary_in_plan';
-            this._args = { competencyid: this._competencyId, planid: this._planId };
+            this._args = {competencyid: this._competencyId, planid: this._planId};
             this._templateName = 'tool_lp/user_competency_summary_in_plan';
         } else if (this._courseId) {
             this._methodName = 'tool_lp_data_for_user_competency_summary_in_course';
-            this._args = { userid: this._userId, competencyid: this._competencyId, courseid: this._courseId };
+            this._args = {userid: this._userId, competencyid: this._competencyId, courseid: this._courseId};
             this._templateName = 'tool_lp/user_competency_summary_in_course';
         } else {
             this._methodName = 'tool_lp_data_for_user_competency_summary';
-            this._args = { userid: this._userId, competencyid: this._competencyId };
+            this._args = {userid: this._userId, competencyid: this._competencyId};
             this._templateName = 'tool_lp/user_competency_summary';
         }
     };
index 5001991..6600b1f 100644 (file)
@@ -54,7 +54,7 @@ define(['jquery', 'core/notification', 'core/str', 'core/ajax', 'core/templates'
 
         var requests = ajax.call([{
             methodname: 'tool_lp_data_for_user_competency_summary_in_plan',
-            args: { competencyid: competencyId, planid: planId },
+            args: {competencyid: competencyId, planid: planId},
             done: this._contextLoaded.bind(this),
             fail: notification.exception
         }]);
@@ -99,7 +99,7 @@ define(['jquery', 'core/notification', 'core/str', 'core/ajax', 'core/templates'
 
         ajax.call([{
             methodname: 'tool_lp_data_for_plan_page',
-            args: { planid: planId},
+            args: {planid: planId},
             done: this._pageContextLoaded.bind(this),
             fail: notification.exception
         }]);
index f1f5cd3..b9ef686 100644 (file)
@@ -104,7 +104,7 @@ define(['jquery',
         templates.render(self._template, context)
             .done(function(newhtml, newjs) {
                 templates.replaceNode($(self._region), newhtml, newjs);
-            }.bind(self))
+            })
             .fail(notification.exception);
     };
 
@@ -126,7 +126,7 @@ define(['jquery',
         // Apply all the promises, and refresh when the last one is resolved.
         return $.when.apply($.when, ajax.call(calls))
             .then(function() {
-                self._renderView.call(self, arguments[arguments.length - 1]);
+                self._renderView(arguments[arguments.length - 1]);
             })
             .fail(notification.exception);
     };
@@ -140,7 +140,7 @@ define(['jquery',
         var self = this,
             calls = [{
                 methodname: 'core_competency_delete_user_evidence',
-                args: { id: evidenceData.id }
+                args: {id: evidenceData.id}
             }];
         self._callAndRefresh(calls, evidenceData);
     };
@@ -156,15 +156,15 @@ define(['jquery',
 
         requests = ajax.call([{
             methodname: 'core_competency_read_user_evidence',
-            args: { id: evidenceData.id }
+            args: {id: evidenceData.id}
         }]);
 
         requests[0].done(function(evidence) {
             str.get_strings([
-                { key: 'confirm', component: 'moodle' },
-                { key: 'deleteuserevidence', component: 'tool_lp', param: evidence.name },
-                { key: 'delete', component: 'moodle' },
-                { key: 'cancel', component: 'moodle' }
+                {key: 'confirm', component: 'moodle'},
+                {key: 'deleteuserevidence', component: 'tool_lp', param: evidence.name},
+                {key: 'delete', component: 'moodle'},
+                {key: 'cancel', component: 'moodle'}
             ]).done(function(strings) {
                 notification.confirm(
                     strings[0], // Confirm.
@@ -173,7 +173,7 @@ define(['jquery',
                     strings[3], // Cancel.
                     function() {
                         self._doDelete(evidenceData);
-                    }.bind(self)
+                    }
                 );
             }).fail(notification.exception);
         }).fail(notification.exception);
@@ -227,7 +227,7 @@ define(['jquery',
         picker.on('save', function(e, data) {
             var competencyIds = data.competencyIds;
             self._doCreateUserEvidenceCompetency(evidenceData, competencyIds, data.requestReview);
-        }.bind(self));
+        });
 
         picker.display();
     };
@@ -295,7 +295,7 @@ define(['jquery',
         var self = this,
             calls = [{
                 methodname: 'core_competency_request_review_of_user_evidence_linked_competencies',
-                args: { id: evidenceData.id }
+                args: {id: evidenceData.id}
             }];
         self._callAndRefresh(calls, evidenceData);
     };
@@ -311,15 +311,15 @@ define(['jquery',
 
         requests = ajax.call([{
             methodname: 'core_competency_read_user_evidence',
-            args: { id: evidenceData.id }
+            args: {id: evidenceData.id}
         }]);
 
         requests[0].done(function(evidence) {
             str.get_strings([
-                { key: 'confirm', component: 'moodle' },
-                { key: 'sendallcompetenciestoreview', component: 'tool_lp', param: evidence.name },
-                { key: 'confirm', component: 'moodle' },
-                { key: 'cancel', component: 'moodle' }
+                {key: 'confirm', component: 'moodle'},
+                {key: 'sendallcompetenciestoreview', component: 'tool_lp', param: evidence.name},
+                {key: 'confirm', component: 'moodle'},
+                {key: 'cancel', component: 'moodle'}
             ]).done(function(strings) {
                 notification.confirm(
                     strings[0], // Confirm.
@@ -328,7 +328,7 @@ define(['jquery',
                     strings[3], // Cancel.
                     function() {
                         self._doReviewUserEvidenceCompetencies(evidenceData);
-                    }.bind(self)
+                    }
                 );
             }).fail(notification.exception);
         }).fail(notification.exception);
index 39d451b..ee2eb74 100644 (file)
@@ -158,6 +158,12 @@ function tool_recyclebin_pre_course_module_delete($cm) {
  * @param \stdClass $course The course record.
  */
 function tool_recyclebin_pre_course_delete($course) {
+    // It is possible that the course deletion which triggered this hook
+    // was from an in progress course restore. In that case we do not want
+    // it in the recycle bin.
+    if (isset($course->deletesource) && $course->deletesource == 'restore') {
+        return;
+    }
     // Delete all the items in the course recycle bin, regardless if it enabled or not.
     // It may have been enabled, then disabled later on, so may still have content.
     $coursebin = new \tool_recyclebin\course_bin($course->id);
index 5e3f85d..22c7f21 100644 (file)
@@ -38,6 +38,11 @@ class tool_recyclebin_category_bin_tests extends advanced_testcase {
      */
     protected $course;
 
+    /**
+     * @var stdClass $coursebeingrestored
+     */
+    protected $coursebeingrestored;
+
     /**
      * Setup for each test.
      */
@@ -57,10 +62,16 @@ class tool_recyclebin_category_bin_tests extends advanced_testcase {
     public function test_pre_course_delete_hook() {
         global $DB;
 
+        // This simulates a temporary course being cleaned up by a course restore.
+        $this->coursebeingrestored = $this->getDataGenerator()->create_course();
+        $this->coursebeingrestored->deletesource = 'restore';
+
         // Should have nothing in the recycle bin.
         $this->assertEquals(0, $DB->count_records('tool_recyclebin_category'));
 
         delete_course($this->course, false);
+        // This should not be added to the recycle bin.
+        delete_course($this->coursebeingrestored, false);
 
         // Check the course is now in the recycle bin.
         $this->assertEquals(1, $DB->count_records('tool_recyclebin_category'));
index 503f280..ba7ea8c 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 2fabeb2..8b115e6 100644 (file)
@@ -31,7 +31,7 @@ define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates'
      * @param {String[]} templateList List of template ids.
      */
     var reloadListTemplate = function(templateList) {
-        templates.render('tool_templatelibrary/search_results', { templates: templateList })
+        templates.render('tool_templatelibrary/search_results', {templates: templateList})
             .done(function(result, js) {
                 templates.replaceNode($('[data-region="searchresults"]'), result, js);
             }).fail(notification.exception);
@@ -49,10 +49,10 @@ define(['jquery', 'core/ajax', 'core/log', 'core/notification', 'core/templates'
         // Trigger the search.
 
         ajax.call([
-            { methodname: 'tool_templatelibrary_list_templates',
-              args: { component: componentStr, search: searchStr },
+            {methodname: 'tool_templatelibrary_list_templates',
+              args: {component: componentStr, search: searchStr},
               done: reloadListTemplate,
-              fail: notification.exception }
+              fail: notification.exception}
         ], true, false);
     };
 
index d0e2237..7c0de1b 100644 (file)
@@ -231,9 +231,11 @@ class restore_ui extends base_ui {
      * Delete course which is created by restore process
      */
     public function cleanup() {
+        global $DB;
         $courseid = $this->controller->get_courseid();
-        if ($this->is_temporary_course_created($courseid)) {
-            delete_course($courseid, false);
+        if ($this->is_temporary_course_created($courseid) && $course = $DB->get_record('course', array('id' => $courseid))) {
+            $course->deletesource = 'restore';
+            delete_course($course, false);
         }
     }
 
index 796304e..a38f289 100644 (file)
@@ -55,6 +55,15 @@ class block_activity_results extends block_base {
         $this->title = get_string('pluginname', 'block_activity_results');
     }
 
+    /**
+     * Allow the block to have a configuration page
+     *
+     * @return boolean
+     */
+    public function has_config() {
+        return true;
+    }
+
     /**
      * Core function, specifies where the block can be used.
      * @return array
index 0a07151..aa3f0b0 100644 (file)
@@ -42,6 +42,9 @@ class block_activity_results_edit_form extends block_edit_form {
     protected function specific_definition($mform) {
         global $DB;
 
+        // Load defaults.
+        $blockconfig = get_config('block_activity_results');
+
         // Fields for editing activity_results block title and contents.
         $mform->addElement('header', 'configheader', get_string('blocksettings', 'block'));
 
@@ -64,15 +67,25 @@ class block_activity_results_edit_form extends block_edit_form {
 
         $mform->addElement('text', 'config_showbest',
                 get_string('config_show_best', 'block_activity_results'), array('size' => 3));
-        $mform->setDefault('config_showbest', 3);
+        $mform->setDefault('config_showbest', $blockconfig->config_showbest);
         $mform->setType('config_showbest', PARAM_INT);
+        if ($blockconfig->config_showbest_locked) {
+            $mform->freeze('config_showbest');
+        }
 
         $mform->addElement('text', 'config_showworst',
                 get_string('config_show_worst', 'block_activity_results'), array('size' => 3));
-        $mform->setDefault('config_showworst', 0);
+        $mform->setDefault('config_showworst', $blockconfig->config_showworst);
         $mform->setType('config_showworst', PARAM_INT);
+        if ($blockconfig->config_showworst_locked) {
+            $mform->freeze('config_showworst');
+        }
 
         $mform->addElement('selectyesno', 'config_usegroups', get_string('config_use_groups', 'block_activity_results'));
+        $mform->setDefault('config_usegroups', $blockconfig->config_usegroups);
+        if ($blockconfig->config_usegroups_locked) {
+            $mform->freeze('config_usegroups');
+        }
 
         $nameoptions = array(
             B_ACTIVITYRESULTS_NAME_FORMAT_FULL => get_string('config_names_full', 'block_activity_results'),
@@ -81,7 +94,10 @@ class block_activity_results_edit_form extends block_edit_form {
         );
         $mform->addElement('select', 'config_nameformat',
                 get_string('config_name_format', 'block_activity_results'), $nameoptions);
-        $mform->setDefault('config_nameformat', B_ACTIVITYRESULTS_NAME_FORMAT_FULL);
+        $mform->setDefault('config_nameformat', $blockconfig->config_nameformat);
+        if ($blockconfig->config_nameformat_locked) {
+            $mform->freeze('config_nameformat');
+        }
 
         $gradeeoptions = array(
             B_ACTIVITYRESULTS_GRADE_FORMAT_PCT => get_string('config_format_percentage', 'block_activity_results'),
@@ -90,7 +106,10 @@ class block_activity_results_edit_form extends block_edit_form {
         );
         $mform->addElement('select', 'config_gradeformat',
                 get_string('config_grade_format', 'block_activity_results'), $gradeeoptions);
-        $mform->setDefault('config_gradeformat', B_ACTIVITYRESULTS_GRADE_FORMAT_PCT);
+        $mform->setDefault('config_gradeformat', $blockconfig->config_gradeformat);
+        if ($blockconfig->config_gradeformat_locked) {
+            $mform->freeze('config_gradeformat');
+        }
 
         $options = array();
         for ($i = 0; $i <= 5; $i++) {
@@ -98,7 +117,10 @@ class block_activity_results_edit_form extends block_edit_form {
         }
         $mform->addElement('select', 'config_decimalpoints', get_string('config_decimalplaces', 'block_activity_results'),
                 $options);
-        $mform->setDefault('config_decimalpoints', 2);
+        $mform->setDefault('config_decimalpoints', $blockconfig->config_decimalpoints);
         $mform->setType('config_decimalpoints', PARAM_INT);
+        if ($blockconfig->config_decimalpoints_locked) {
+            $mform->freeze('config_decimalpoints');
+        }
     }
 }
\ No newline at end of file
index 97ed95e..8a9b631 100644 (file)
@@ -42,6 +42,18 @@ $string['config_show_best'] = 'How many of the highest grades should be shown (0
 $string['config_show_worst'] = 'How many of the lowest grades should be shown (0 to disable)?';
 $string['configuredtoshownothing'] = 'This block\'s configuration currently does not allow it to show any results.';
 $string['config_use_groups'] = 'Show groups instead of students (only if the activity supports groups)?';
+$string['defaulthighestgrades'] = 'Default highest grades shown';
+$string['defaulthighestgrades_desc'] = 'How many of the highest grades should be shown by default?';
+$string['defaultlowestgrades'] = 'Default lowest grades shown';
+$string['defaultlowestgrades_desc'] = 'How many of the lowest grades should be shown by default?';
+$string['defaultshowgroups'] = 'Default show groups';
+$string['defaultnameoptions'] = 'Privacy of results';
+$string['defaultnameoptions_desc'] = 'How should the students be identified by default?';
+$string['defaultshowgroups_desc'] = 'Show groups instead of students by default (only if the activity supports groups)';
+$string['defaultgradedisplay'] = 'Display grades as';
+$string['defaultgradedisplay_desc'] = 'How should the grades be displayed by default?';
+$string['defaultdecimalplaces'] = 'Decimal places';
+$string['defaultdecimalplaces_desc'] = 'Number of decimal places to display by default';
 $string['error_emptyactivityid'] = 'Please configure this block and select which activity it should display results from.';
 $string['error_emptyactivityrecord'] = 'Error: the selected activity does not exist in the database.';
 $string['error_nogroupsexist'] = 'Error: the block is set to display grades in group mode, but there are no groups defined.';
diff --git a/blocks/activity_results/settings.php b/blocks/activity_results/settings.php
new file mode 100644 (file)
index 0000000..da08088
--- /dev/null
@@ -0,0 +1,86 @@
+<?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/>.
+
+/**
+ * Defines the form for editing activity results block instances.
+ *
+ * @package    block_activity_results
+ * @copyright  2016 Stephen Bourget
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die;
+
+if ($ADMIN->fulltree) {
+
+    // Default high scores.
+    $setting = new admin_setting_configtext('block_activity_results/config_showbest',
+        new lang_string('defaulthighestgrades', 'block_activity_results'),
+        new lang_string('defaulthighestgrades_desc', 'block_activity_results'), 3, PARAM_INT);
+    $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+    $settings->add($setting);
+
+    // Default low scores.
+    $setting = new admin_setting_configtext('block_activity_results/config_showworst',
+        new lang_string('defaultlowestgrades', 'block_activity_results'),
+        new lang_string('defaultlowestgrades_desc', 'block_activity_results'), 0, PARAM_INT);
+    $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+    $settings->add($setting);
+
+    // Default group display.
+    $yesno = array(0 => get_string('no'), 1 => get_string('yes'));
+    $setting = new admin_setting_configselect('block_activity_results/config_usegroups',
+        new lang_string('defaultshowgroups', 'block_activity_results'),
+        new lang_string('defaultshowgroups_desc', 'block_activity_results'), 0, $yesno);
+    $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+    $settings->add($setting);
+
+    // Default privacy settings.
+    $nameoptions = array(
+        B_ACTIVITYRESULTS_NAME_FORMAT_FULL => get_string('config_names_full', 'block_activity_results'),
+        B_ACTIVITYRESULTS_NAME_FORMAT_ID => get_string('config_names_id', 'block_activity_results'),
+        B_ACTIVITYRESULTS_NAME_FORMAT_ANON => get_string('config_names_anon', 'block_activity_results')
+    );
+    $setting = new admin_setting_configselect('block_activity_results/config_nameformat',
+        new lang_string('defaultnameoptions', 'block_activity_results'),
+        new lang_string('defaultnameoptions_desc', 'block_activity_results'), B_ACTIVITYRESULTS_NAME_FORMAT_FULL, $nameoptions);
+    $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+    $settings->add($setting);
+
+    // Default grade display settings.
+    $gradeoptions = array(
+        B_ACTIVITYRESULTS_GRADE_FORMAT_PCT => get_string('config_format_percentage', 'block_activity_results'),
+        B_ACTIVITYRESULTS_GRADE_FORMAT_FRA => get_string('config_format_fraction', 'block_activity_results'),
+        B_ACTIVITYRESULTS_GRADE_FORMAT_ABS => get_string('config_format_absolute', 'block_activity_results')
+    );
+    $setting = new admin_setting_configselect('block_activity_results/config_gradeformat',
+        new lang_string('defaultgradedisplay', 'block_activity_results'),
+        new lang_string('defaultgradedisplay_desc', 'block_activity_results'), B_ACTIVITYRESULTS_GRADE_FORMAT_PCT, $gradeoptions);
+    $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+    $settings->add($setting);
+
+    // Default decimal places.
+    $places = array();
+    for ($i = 0; $i <= 5; $i++) {
+        $places[$i] = $i;
+    }
+    $setting = new admin_setting_configselect('block_activity_results/config_decimalpoints',
+        new lang_string('defaultdecimalplaces', 'block_activity_results'),
+        new lang_string('defaultdecimalplaces_desc', 'block_activity_results'), 2, $places);
+    $setting->set_locked_flag_options(admin_setting_flag::ENABLED, false);
+    $settings->add($setting);
+
+}
diff --git a/blocks/activity_results/tests/behat/defaultsettings.feature b/blocks/activity_results/tests/behat/defaultsettings.feature
new file mode 100644 (file)
index 0000000..ca45c84
--- /dev/null
@@ -0,0 +1,66 @@
+@block @block_activity_results
+Feature: The activity results block can have administrator set defaults
+  In order to be customize the activity results block
+  As an admin
+  I need can assign some site wide defaults
+
+  Background:
+    Given the following "users" exist:
+      | username | firstname | lastname | email | idnumber |
+      | teacher1 | Teacher | 1 | teacher1@example.com | T1 |
+      | student1 | Student | 1 | student1@example.com | S1 |
+    And the following "courses" exist:
+      | fullname | shortname | category |
+      | Course 1 | C1 | 0 |
+    And the following "course enrolments" exist:
+      | user | course | role |
+      | teacher1 | C1 | editingteacher |
+      | student1 | C1 | student |
+
+  Scenario: Assign some site-wide defaults to the block.
+    Given the following config values are set as admin:
+      | config_showbest    | 0 | block_activity_results |
+      | config_showworst   | 0 | block_activity_results |
+      | config_gradeformat | 2 | block_activity_results |
+      | config_nameformat  | 2 | block_activity_results |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name | Test assignment |
+      | Description | Offline text |
+      | assignsubmission_file_enabled | 0 |
+    And I follow "Course 1"
+    And I add the "Activity results" block
+    When I configure the "Activity results" block
+    And the following fields match these values:
+      | id_config_showbest    | 0 |
+      | id_config_showworst   | 0 |
+      | id_config_gradeformat | Fractions |
+      | id_config_nameformat  | Display only ID numbers |
+    And I press "Save changes"
+    Then I should see "This block's configuration currently does not allow it to show any results." in the "Activity results" "block"
+
+  Scenario: Assign some site-wide defaults to the block and lock them.
+    Given the following config values are set as admin:
+      | config_showbest         | 0 | block_activity_results |
+      | config_showbest_locked  | 1 | block_activity_results |
+      | config_showworst        | 0 | block_activity_results |
+      | config_showworst_locked | 1 | block_activity_results |
+    And I log in as "teacher1"
+    And I follow "Course 1"
+    And I turn editing mode on
+    And I add a "Assignment" to section "1" and I fill the form with:
+      | Assignment name | Test assignment |
+      | Description | Offline text |
+      | assignsubmission_file_enabled | 0 |
+    And I follow "Course 1"
+    And I add the "Activity results" block
+    When I configure the "Activity results" block
+    And the following fields match these values:
+      | id_config_showbest    | 0 |
+      | id_config_showworst   | 0 |
+    And the "id_config_showbest" "field" should be readonly
+    And the "id_config_showworst" "field" should be readonly
+    And I press "Save changes"
+    Then I should see "This block's configuration currently does not allow it to show any results." in the "Activity results" "block"
index f893026..cd1ded7 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2016052300;               // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version   = 2016070400;               // The current plugin version (Date: YYYYMMDDXX).
 $plugin->requires  = 2016051900;               // Requires this Moodle version.
 $plugin->component = 'block_activity_results'; // Full name of the plugin (used for diagnostics).
\ No newline at end of file
index 98bf2b6..4c69492 100644 (file)
Binary files a/blocks/navigation/amd/build/ajax_response_renderer.min.js and b/blocks/navigation/amd/build/ajax_response_renderer.min.js differ
index 8ead8fe..c64e55d 100644 (file)
@@ -86,7 +86,7 @@ class block_navigation_renderer extends plugin_renderer_base {
                 continue;
             }
 
-            $id = $item->id ? $item->id : uniqid();
+            $id = $item->id ? $item->id : html_writer::random_id();
             $content = $item->get_content();
             $title = $item->get_title();
             $ulattr = ['id' => $id . '_group', 'role' => 'group'];
index 10afa75..34e99ef 100644 (file)
@@ -75,7 +75,7 @@ class block_settings_renderer extends plugin_renderer_base {
             }
 
             $content = $this->output->render($item);
-            $id = $item->id ? $item->id : uniqid();
+            $id = $item->id ? $item->id : html_writer::random_id();
             $ulattr = ['id' => $id . '_group', 'role' => 'group'];
             $liattr = ['class' => [$item->get_css_type(), 'depth_'.$depth], 'tabindex' => '-1'];
             $pattr = ['class' => ['tree_item'], 'role' => 'treeitem'];
index d93396d..5376d8f 100644 (file)
@@ -2722,7 +2722,7 @@ class calendar_event {
             if ($this->properties->eventtype != 'user' && $this->properties->eventtype != 'course'
                     && $this->properties->eventtype != 'site' && $this->properties->eventtype != 'group') {
                 // We don't have a context here, do a normal format_text.
-                return array(format_text($this->properties->description, $this->properties->format), $this->properties->format);
+                return external_format_text($this->properties->description, $this->properties->format, $this->editorcontext->id);
             }
         }
 
index 9d862ba..73837ad 100644 (file)
@@ -213,6 +213,7 @@ abstract class data_object {
 
         $wheresql = array();
 
+        $dbparams = array();
         foreach ($params as $var=>$value) {
             if (!in_array($var, $instance->required_fields) and !array_key_exists($var, $instance->optional_fields)) {
                 continue;
@@ -221,7 +222,7 @@ abstract class data_object {
                 $wheresql[] = " $var IS NULL ";
             } else {
                 $wheresql[] = " $var = ? ";
-                $params[] = $value;
+                $dbparams[] = $value;
             }
         }
 
@@ -232,7 +233,7 @@ abstract class data_object {
         }
 
         global $DB;
-        if ($datas = $DB->get_records_select($table, $wheresql, $params)) {
+        if ($datas = $DB->get_records_select($table, $wheresql, $dbparams)) {
 
             $result = array();
             foreach($datas as $data) {
index 7a5f30b..b75defd 100644 (file)
@@ -49,7 +49,7 @@ class mycourse extends \core_search\area\base {
      */
     public function get_recordset_by_timestamp($modifiedfrom = 0) {
         global $DB;
-        return $DB->get_recordset_select('course', 'timemodified >= ?', array($modifiedfrom));
+        return $DB->get_recordset_select('course', 'timemodified >= ?', array($modifiedfrom), 'timemodified ASC');
     }
 
     /**
index 2bd50f0..6bb4865 100644 (file)
@@ -7,7 +7,7 @@
     require_once($CFG->libdir.'/completionlib.php');
 
     $id          = optional_param('id', 0, PARAM_INT);
-    $name        = optional_param('name', '', PARAM_RAW);
+    $name        = optional_param('name', '', PARAM_TEXT);
     $edit        = optional_param('edit', -1, PARAM_BOOL);
     $hide        = optional_param('hide', 0, PARAM_INT);
     $show        = optional_param('show', 0, PARAM_INT);
index fe94ff0..d10c10e 100644 (file)
Binary files a/course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop-debug.js and b/course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop-debug.js differ
index 7befde3..76a249b 100644 (file)
Binary files a/course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop.js and b/course/yui/build/moodle-course-dragdrop/moodle-course-dragdrop.js differ
index 0b3587a..57e0b16 100644 (file)
Binary files a/course/yui/build/moodle-course-management/moodle-course-management-debug.js and b/course/yui/build/moodle-course-management/moodle-course-management-debug.js differ
index 883b964..35520d1 100644 (file)
Binary files a/course/yui/build/moodle-course-management/moodle-course-management.js and b/course/yui/build/moodle-course-management/moodle-course-management.js differ
index 212e98d..4d7656b 100644 (file)
Binary files a/course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes-debug.js and b/course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes-debug.js differ
index 212e98d..4d7656b 100644 (file)
Binary files a/course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes.js and b/course/yui/build/moodle-course-toolboxes/moodle-course-toolboxes.js differ
index 00b30d4..b1e3ef5 100644 (file)
@@ -1,3 +1,4 @@
+/* eslint-disable no-unused-vars */
 /**
  * Drag and Drop for course sections and course modules.
  *
index b7fac22..889ccec 100644 (file)
@@ -1,3 +1,5 @@
+/* global Item */
+
 /**
  * A managed category.
  *
index 0a00ab1..12ca9be 100644 (file)
@@ -1,3 +1,5 @@
+/* global DragDrop, Category, Course */
+
 /**
  * Provides drop down menus for list of action links.
  *
index 474180a..893b21c 100644 (file)
@@ -1,3 +1,5 @@
+/* global Item */
+
 /**
  * A managed course.
  *
index 3ad3e0f..f622d29 100644 (file)
@@ -1,3 +1,5 @@
+/* global Console */
+
 /**
  * Drag and Drop handler
  *
index f475b89..4d87574 100644 (file)
@@ -1,3 +1,5 @@
+/* global TOOLBOX, BODY, SELECTOR, INDENTLIMITS */
+
 /**
  * Resource and activity toolbox class.
  *
index fe9b84e..a28ca9a 100644 (file)
@@ -1,3 +1,5 @@
+/* global SELECTOR, TOOLBOX */
+
 /**
  * Resource and activity toolbox class.
  *
index e3f6c8a..019b359 100644 (file)
@@ -1,3 +1,4 @@
+/* eslint-disable no-unused-vars */
 /**
  * Resource and activity toolbox class.
  *
@@ -196,4 +197,3 @@ Y.extend(TOOLBOX, Y.Base, {
     }
 }
 );
-
index af37580..ea01272 100644 (file)
@@ -4,6 +4,5 @@
 .enrolpanel .container .header {border-bottom:1px solid #999;}
 .enrolpanel .container .header h2 {font-size:90%;text-align:center;margin:5px;}
 .enrolpanel .container .header .close {width:25px;height:15px;position:absolute;top:5px;right:1em;cursor:pointer;background:url("sprite.png") no-repeat scroll 0 0 transparent;}
-.enrolpanel .container .content {}
 .enrolpanel .container .content input {margin:5px;font-size:10px;}
 .enrolpanel.roleassign.visible .container {width:auto;}
index 3726c95..c5428c8 100644 (file)
@@ -163,7 +163,22 @@ class filter_mathjaxloader extends moodle_text_filter {
         }
         if ($hasinline || $hasdisplay || $hasextra) {
             $PAGE->requires->yui_module('moodle-filter_mathjaxloader-loader', 'M.filter_mathjaxloader.typeset');
-            return '<span class="nolink"><span class="filter_mathjaxloader_equation">' . $text . '</span></span>';
+            if ($hasextra) {
+                // If custom dilimeters are used, wrap whole text to prevent autolinking.
+                $text = '<span class="nolink">' + $text + '</span>';
+            } else {
+                if ($hasinline) {
+                    // If the default inline TeX delimiters \( \) are present, wrap each pair in nolink.
+                    $text = preg_replace('/\\\\\\([\S\s]*?\\\\\\)/u',
+                        '<span class="nolink">\0</span>', $text);
+                }
+                if ($hasdisplay) {
+                    // If default display TeX is used, wrap $$ $$ or \[ \] individually.
+                    $text = preg_replace('/\$\$[\S\s]*?\$\$|\\\\\\[[\S\s]*?\\\\\\]/u',
+                        '<span class="nolink">\0</span>', $text);
+                }
+            }
+            return '<span class="filter_mathjaxloader_equation">' . $text . '</span>';
         }
         return $text;
     }
index 0257798..ac912f7 100644 (file)
@@ -45,7 +45,7 @@ require_login($course);
 $context = context_course::instance($course->id);
 require_capability('moodle/grade:manage', $context);
 
-$PAGE->requires->js_call_amd('grades/edittree_index', 'enhance');
+$PAGE->requires->js_call_amd('core_grades/edittree_index', 'enhance');
 
 /// return tracking object
 $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid));
index abeda37..0a44d20 100644 (file)
Binary files a/grade/grading/form/guide/amd/build/comment_chooser.min.js and b/grade/grading/form/guide/amd/build/comment_chooser.min.js differ
index c185c23..e3a184c 100644 (file)
Binary files a/grade/report/grader/yui/build/moodle-gradereport_grader-gradereporttable/moodle-gradereport_grader-gradereporttable-debug.js and b/grade/report/grader/yui/build/moodle-gradereport_grader-gradereporttable/moodle-gradereport_grader-gradereporttable-debug.js differ
index ac36953..f9fa8f6 100644 (file)
Binary files a/grade/report/grader/yui/build/moodle-gradereport_grader-gradereporttable/moodle-gradereport_grader-gradereporttable.js and b/grade/report/grader/yui/build/moodle-gradereport_grader-gradereporttable/moodle-gradereport_grader-gradereporttable.js differ
index a57aed8..4343ba7 100644 (file)
@@ -12,6 +12,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/* global SELECTORS */
 
 /**
  * @module moodle-gradereport_grader-gradereporttable
index bbdbd8f..8cc3e10 100644 (file)
@@ -12,6 +12,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/* eslint-disable no-unused-vars */
 
 /**
  * Grader Report Functionality.
index 02b3354..1ef0f2e 100644 (file)
@@ -34,7 +34,7 @@ $string['admindirname'] = 'Directori d\'administració';
 $string['availablelangs'] = 'Llista d\'idiomes disponibles';
 $string['chooselanguagehead'] = 'Trieu un idioma';
 $string['chooselanguagesub'] = 'Trieu un idioma per a la instal·lació. S\'utilitzarà també com a idioma per defecte del lloc, tot i que després podeu canviar-lo.';
-$string['clialreadyconfigured'] = 'El fitxer config.php ja existeix, feu servir dmin/cli/install_database.php si voleu instal·lar aquest lloc web.';
+$string['clialreadyconfigured'] = 'El fitxer config.php ja existeix, feu servir admin/cli/install_database.php si voleu instal·lar el Moodle en aquest lloc web.';
 $string['clialreadyinstalled'] = 'El fitxer de configuració config.php ja existeix. Feu servir admin/cli/upgrade.php si voleu actualitzar Moodle per a aquest lloc web.';
 $string['cliinstallheader'] = 'Programa d\'instal·lació de línia d\'ordres de Moodle {$a}';
 $string['databasehost'] = 'Servidor de base de dades:';
@@ -68,7 +68,10 @@ $string['pathshead'] = 'Confirmeu els camins';
 $string['pathsrodataroot'] = 'No es pot escriure en el directori dataroot.';
 $string['pathsroparentdataroot'] = 'No es pot escriure en el directori pare ({$a->parent}). L\'instal·lador no pot crear el directori ({$a->dataroot}).';
 $string['pathssubadmindir'] = 'Alguns serveis d\'allotjament web (pocs) utilitzen /admin com a URL especial perquè accediu a un tauler de control o quelcom semblant. Malauradament, això entra en conflicte amb la ubicació estàndard de les pàgines d\'administració de Moodle. Podeu arreglar aquest problema canviant el nom del directori d\'administració de Moodle en la vostra instal·lació i posant el nou nom aquí. Per exemple: <em>moodleadmin</em>. Això arreglarà els enllaços d\'administració de Moodle.';
-$string['pathssubdataroot'] = 'Necessiteu un espai on Moodle pugui desar els fitxers penjats. Aquest directori hauria de tenir permisos de lectura I ESCRIPTURA per a l\'usuari del servidor web (normalment \'nobody\' o \'apache\'), però no cal que sigui accessible directament via web. L\'instal·lador provarà de crear-lo si no existeix.';
+$string['pathssubdataroot'] = '<p>Directori on el Moodle emmagatzemarà els materials pujats pels usuaris.</p>
+<p>Aquest directori hauria de tenir permisos de lectura i escriptura per a l\'usuari del servidor web (normalment \'www-data\', \'nobody\', or \'apache\').</p>
+<p>No ha de ser accessible directament via web.</p>
+<p>L\'instal·lador provarà de crear-lo si no existeix.</p>';
 $string['pathssubdirroot'] = 'Camí complet del directori d\'instal·lació de Moodle.';
 $string['pathssubwwwroot'] = '<p>L\'adreça web completa on s\'accedirà a Moodle; per exemple, l\'adreça que els usuaris introduiran a la barra d\'adreces del navegador per accedir a Moodle.</p> <p> No és possible accedir a Moodle utilitzant diferents adreces. Si el vostre lloc és accessible a través de diferents adreces, trieu-ne la més fàcil i configureu una redirecció permanent per a cadascuna de les altres adreces.</p> <p>
 Si el vostre lloc és accessible tant des d\'Internet com des d\'una xarxa interna (anomenada de vegades intranet), utilitzeu l\'adreça pública aquí.</p> <p>Si l\'adreça actual no és correcta, canvieu l\'URL a la barra d\'adreces del navegador i reinicieu la instal·lació.';
index e4398be..eafa560 100644 (file)
@@ -65,7 +65,7 @@ $string['authpreventaccountcreation_help'] = 'When a user authenticates, an acco
 $string['authsettings'] = 'Manage authentication';
 $string['autolang'] = 'Language autodetect';
 $string['autologinguests'] = 'Auto-login guests';
-$string['availablesearchareas'] = 'Available areas for search';
+$string['searchareas'] = 'Search areas';
 $string['availableto'] = 'Available to';
 $string['availablelicenses'] = 'Available licences';
 $string['backgroundcolour'] = 'Transparent colour';
@@ -586,6 +586,7 @@ $string['ignore'] = 'Ignore';
 $string['includemoduleuserdata'] = 'Include module user data';
 $string['incompatibleblocks'] = 'Incompatible blocks';
 $string['indexdata'] = 'Index data';
+$string['indexinginfo'] = 'The recommended way to index your site\'s contents is using "Global search indexing" scheduled task which runs automatically by Cron.';
 $string['installhijacked'] = 'Installation must be finished from the original IP address, sorry.';
 $string['installsessionerror'] = 'Can not initialise PHP session, please verify that your browser accepts cookies.';
 $string['intlrecommended'] = 'Intl extension is used to improve internationalization support, such as locale aware sorting.';
@@ -750,6 +751,7 @@ $string['navshowmycoursecategories_help'] = 'If enabled courses in the users my
 $string['navsortmycoursessort'] = 'Sort my courses';
 $string['navsortmycoursessort_help'] = 'This determines whether courses are listed under My courses according to the sort order (i.e. the order set in Site administration > Courses > Manage courses and categories) or alphabetically by course setting.';
 $string['neverdeleteruns'] = 'Never delete runs';
+$string['newestdocindexed'] = 'Newest document indexed';
 $string['nobookmarksforuser'] = 'You do not have any bookmarks.';
 $string['nodatabase'] = 'No database';
 $string['nohttpsformobilewarning'] = 'It is recommended to enable HTTPS with a valid certificate. The Moodle app will always try to use a secured connection first.';
@@ -937,10 +939,22 @@ $string['rssglobaldisabled'] = 'Disabled at server level';
 $string['save'] = 'Save';
 $string['savechanges'] = 'Save changes';
 $string['search'] = 'Search';
+$string['searchalldeleted'] = 'All indexed contents have been deleted';
+$string['searchareaenabled'] = 'Search area enabled';
+$string['searchareadisabled'] = 'Search area disabled';
+$string['searchdeleteindex'] = 'Delete all indexed contents';
 $string['searchengine'] = 'Search engine';
+$string['searchindexactions'] = 'Index actions';
+$string['searchindexdeleted'] = 'Index deleted';
+$string['searchindexupdated'] = 'Search engine contents have been updated';
 $string['searchinsettings'] = 'Search in settings';
+$string['searchlastrun'] = 'Last run (time, # docs, # records, # ignores)';
+$string['searchnotavailable'] = 'Search is not available';
+$string['searchreindexed'] = 'All site\'s contents have been reindexed';
+$string['searchreindexindex'] = 'Reindex all site contents';
 $string['searchresults'] = 'Search results';
 $string['searchsetupinfo'] = 'Search setup';
+$string['searchupdateindex'] = 'Update indexed contents';
 $string['sectionerror'] = 'Section error!';
 $string['secureforms'] = 'Use additional form security';
 $string['security'] = 'Security';
index c8f24f6..b5217e5 100644 (file)
@@ -199,14 +199,14 @@ function uninstall_plugin($type, $name) {
     $DB->delete_records('event', array('modulename' => $pluginname));
 
     // Delete scheduled tasks.
-    $DB->delete_records('task_scheduled', array('component' => $pluginname));
+    $DB->delete_records('task_scheduled', array('component' => $component));
 
     // Delete Inbound Message datakeys.
     $DB->delete_records_select('messageinbound_datakeys',
-            'handler IN (SELECT id FROM {messageinbound_handlers} WHERE component = ?)', array($pluginname));
+            'handler IN (SELECT id FROM {messageinbound_handlers} WHERE component = ?)', array($component));
 
     // Delete Inbound Message handlers.
-    $DB->delete_records('messageinbound_handlers', array('component' => $pluginname));
+    $DB->delete_records('messageinbound_handlers', array('component' => $component));
 
     // delete all the logs
     $DB->delete_records('log', array('module' => $pluginname));
@@ -9715,7 +9715,7 @@ class admin_setting_searchsetupinfo extends admin_setting {
 
         // Available areas.
         $row = array();
-        $url = new moodle_url('/admin/settings.php?section=manageglobalsearch#admin-searchengine');
+        $url = new moodle_url('/admin/searchareas.php');
         $row[0] = '2. ' . html_writer::tag('a', get_string('enablesearchareas', 'admin'),
                         array('href' => $url));
 
@@ -9750,7 +9750,7 @@ class admin_setting_searchsetupinfo extends admin_setting {
 
         // Indexed data.
         $row = array();
-        $url = new moodle_url('/report/search/index.php#searchindexform');
+        $url = new moodle_url('/admin/searchareas.php');
         $row[0] = '4. ' . html_writer::tag('a', get_string('indexdata', 'admin'), array('href' => $url));
         if ($anyindexed) {
             $status = html_writer::tag('span', get_string('yes'), array('class' => 'statusok'));
index 43fb119..a29e064 100644 (file)
Binary files a/lib/amd/build/form-autocomplete.min.js and b/lib/amd/build/form-autocomplete.min.js differ
index be46978..d664f70 100644 (file)
Binary files a/lib/amd/build/form-course-selector.min.js and b/lib/amd/build/form-course-selector.min.js differ
index 0a9a0d8..907a905 100644 (file)
Binary files a/lib/amd/build/fragment.min.js and b/lib/amd/build/fragment.min.js differ
index 6d130bb..2225cbc 100644 (file)
Binary files a/lib/amd/build/inplace_editable.min.js and b/lib/amd/build/inplace_editable.min.js differ
index 372e525..1ef0f78 100644 (file)
Binary files a/lib/amd/build/localstorage.min.js and b/lib/amd/build/localstorage.min.js differ
index 5d86f16..a369521 100644 (file)
Binary files a/lib/amd/build/loglevel.min.js and b/lib/amd/build/loglevel.min.js differ
index 24bb9a8..3380287 100644 (file)
Binary files a/lib/amd/build/mustache.min.js and b/lib/amd/build/mustache.min.js differ
index cf10e4f..272be32 100644 (file)
Binary files a/lib/amd/build/notification.min.js and b/lib/amd/build/notification.min.js differ
index 3a10548..4d62d7b 100644 (file)
Binary files a/lib/amd/build/search-input.min.js and b/lib/amd/build/search-input.min.js differ
index fdb2a95..aed3712 100644 (file)
Binary files a/lib/amd/build/tag.min.js and b/lib/amd/build/tag.min.js differ
index 0ffe642..fd310dd 100644 (file)
Binary files a/lib/amd/build/templates.min.js and b/lib/amd/build/templates.min.js differ
index 20acb6b..8d52c61 100644 (file)
Binary files a/lib/amd/build/tree.min.js and b/lib/amd/build/tree.min.js differ
index b440364..b43c704 100644 (file)
@@ -44,7 +44,7 @@ define(['jquery', 'core/yui'],
                 var yuiNodes = new Y.NodeList(nodes.get());
 
                 // And again for YUI.
-                Y.fire(M.core.event.FILTER_CONTENT_UPDATED, { nodes: yuiNodes });
+                Y.fire(M.core.event.FILTER_CONTENT_UPDATED, {nodes: yuiNodes});
             });
         },
 
index 3467c48..ca7f034 100644 (file)
@@ -90,10 +90,10 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
         }
         originalSelect.children('option').each(function(index, ele) {
             if ($(ele).prop('selected')) {
-                items.push({ label: $(ele).html(), value: $(ele).attr('value') });
+                items.push({label: $(ele).html(), value: $(ele).attr('value')});
             }
         });
-        var context = $.extend({ items: items }, options, state);
+        var context = $.extend({items: items}, options, state);
 
         // Render the template.
         templates.render('core/form_autocomplete_selection', context).done(function(newHTML) {
@@ -317,13 +317,13 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
         var suggestions = [];
         originalSelect.children('option').each(function(index, option) {
             if ($(option).prop('selected') !== true) {
-                suggestions[suggestions.length] = { label: option.innerHTML, value: $(option).attr('value') };
+                suggestions[suggestions.length] = {label: option.innerHTML, value: $(option).attr('value')};
             }
         });
 
         // Re-render the list of suggestions.
         var searchquery = state.caseSensitive ? query : query.toLocaleLowerCase();
-        var context = $.extend({ options: suggestions}, options, state);
+        var context = $.extend({options: suggestions}, options, state);
         templates.render(
             'core/form_autocomplete_suggestions',
             context
@@ -752,7 +752,7 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
             // Create the new markup and insert it after the select.
             var suggestions = [];
             originalSelect.children('option').each(function(index, option) {
-                suggestions[index] = { label: option.innerHTML, value: $(option).attr('value') };
+                suggestions[index] = {label: option.innerHTML, value: $(option).attr('value')};
             });
 
             // Render all the parts of our UI.
index 4e1b8c7..0914918 100644 (file)
@@ -29,12 +29,13 @@ define(['core/ajax', 'jquery'], function(ajax, $) {
         // Public variables and functions.
         processResults: function(selector, data) {
             // Mangle the results into an array of objects.
-            var results = [], i = 0;
+            var results = [];
+            var i = 0;
             var excludelist = String($(selector).data('exclude')).split(',');
 
             for (i = 0; i < data.courses.length; i++) {
                 if (excludelist.indexOf(String(data.courses[i].id)) === -1) {
-                    results.push({ value: data.courses[i].id, label: data.courses[i].displayname });
+                    results.push({value: data.courses[i].id, label: data.courses[i].displayname});
                 }
             }
             return results;
index f12e49a..28627fc 100644 (file)
@@ -109,7 +109,7 @@ define(['jquery', 'core/ajax'], function($, ajax) {
                             allScript += ' ' + scriptNode.text();
                         }
                     }
-                }.bind(this));
+                });
                 promise.resolve(data.html, allScript);
             }).fail(function(ex) {
                 promise.reject(ex);
index 27da8e4..adb2c80 100644 (file)
@@ -106,7 +106,8 @@ define(['core/config'], function(config) {
         // From http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery.
         /* jshint bitwise: false */
         /* eslint no-bitwise: "off" */
-        var hash = 0, i, chr, len;
+        var hash = 0;
+        var i, chr, len;
         if (source.length === 0) {
             return hash;
         }
index 1bf0e6c..f7880a6 100644 (file)
@@ -66,7 +66,7 @@ function(Y, $, log) {
         setupTargetRegion: function() {
             var targetRegion = $('#' + notificationModule.fieldName);
             if (targetRegion.length) {
-                return;
+                return false;
             }
 
             var newRegion = $('<span>').attr('id', notificationModule.fieldName);
index 3076d4b..c65122f 100644 (file)
@@ -46,7 +46,7 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
 
                 var promises = ajax.call([{
                     methodname: 'core_tag_get_tagindex',
-                    args: { tagindex: args }
+                    args: {tagindex: args}
                 }], true);
 
                 $.when.apply($, promises)
@@ -102,7 +102,7 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
                 var form = $(this).closest('form').get(0),
                     cnt = $(form).find("input[type=checkbox]:checked").length;
                 if (!cnt) {
-                    return false;
+                    return;
                 }
                 var tempElement = $("<input type='hidden'/>").attr('name', this.name);
                 e.preventDefault();
@@ -134,7 +134,7 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
                             notification.alert(s[0], s[1], s[2]);
                         }
                     );
-                    return false;
+                    return;
                 }
                 var tempElement = $("<input type='hidden'/>").attr('name', this.name);
                 str.get_strings([
@@ -323,7 +323,7 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/notification', 'core/str'
                 var href = $(this).attr('data-url') + '&sesskey=' + M.cfg.sesskey;
                 str.get_strings([
                         {key: 'delete'},
-                        {key: 'suredeletecoll', component: 'tag', param: $(this).attr('data-collname') },
+                        {key: 'suredeletecoll', component: 'tag', param: $(this).attr('data-collname')},
                         {key: 'yes'},
                         {key: 'no'},
                     ]).done(function(s) {
index 75f7d9d..d009703 100644 (file)
@@ -45,9 +45,6 @@ define(['core/mustache',
     /** @var {string[]} requiredStrings - Collection of strings found during the rendering of one template */
     var requiredStrings = [];
 
-    /** @var {string[]} requiredJS - Collection of js blocks found during the rendering of one template */
-    var requiredJS = [];
-
     /** @var {Number} uniqid Incrementing value that is changed for every call to render */
     var uniqid = 1;
 
@@ -161,9 +158,9 @@ define(['core/mustache',
 
         var templatecontext = {
             attributes: [
-                { name: 'src', value: url},
-                { name: 'alt', value: helper(text)},
-                { name: 'class', value: 'smallicon'}
+                {name: 'src', value: url},
+                {name: 'alt', value: helper(text)},
+                {name: 'class', value: 'smallicon'}
             ]
         };
         // We forced loading of this early, so it will be in the cache.
@@ -182,7 +179,7 @@ define(['core/mustache',
      * @return {string}
      */
     var jsHelper = function(sectionText, helper) {
-        requiredJS.push(helper(sectionText, this));
+        this.jsBlocks.push(helper(sectionText, this));
         return '';
     };
 
@@ -258,7 +255,6 @@ define(['core/mustache',
     var addHelpers = function(context, themeName) {
         currentThemeName = themeName;
         requiredStrings = [];
-        requiredJS = [];
         context.uniqid = uniqid++;
         context.str = function() {
           return stringHelper;
@@ -272,7 +268,8 @@ define(['core/mustache',
         context.quote = function() {
           return quoteHelper;
         };
-        context.globals = { config: config };
+        context.globals = {config: config};
+        context.jsBlocks = [];
         context.currentTheme = themeName;
     };
 
@@ -286,8 +283,8 @@ define(['core/mustache',
      */
     var getJS = function(strings) {
         var js = '';
-        if (requiredJS.length > 0) {
-            js = requiredJS.join(";\n");
+        if (this.jsBlocks.length > 0) {
+            js = this.jsBlocks.join(";\n");
         }
 
         // Re-render to get the final strings.
@@ -403,11 +400,11 @@ define(['core/mustache',
                         // and cause the template to die on the second pass (unbalanced).
 
                         result = treatStringsInContent(result, strings);
-                        deferred.resolve(result, getJS(strings));
+                        deferred.resolve(result, getJS.bind(context)(strings));
                     })
                     .fail(deferred.reject);
                 } else {
-                    deferred.resolve(result.trim(), getJS([]));
+                    deferred.resolve(result.trim(), getJS.bind(context)([]));
                 }
             }
         ).fail(deferred.reject);
index c3fff8b..0938056 100644 (file)
@@ -343,6 +343,8 @@ define(['jquery'], function($) {
      * @param {Event} e The event.
      * @return {Boolean}
      */
+     // This function should be simplified. In the meantime..
+     // eslint-disable-next-line complexity
     Tree.prototype.handleKeyDown = function(item, e) {
         var currentIndex = this.getVisibleItems().index(item);
 
index 565f268..f2a0e6d 100644 (file)
@@ -38,6 +38,8 @@ class core_grades_external extends external_api {
      *
      * @return external_function_parameters
      * @since Moodle 2.7
+     * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more.
+     * @see gradereport_user_external::get_grades_table for a similar function
      */
     public static function get_grades_parameters() {
         return new external_function_parameters(
@@ -65,6 +67,8 @@ class core_grades_external extends external_api {
      * @param  array  $userids      Array of user ids
      * @return array                Array of grades
      * @since Moodle 2.7
+     * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more.
+     * @see gradereport_user_external::get_grades_table for a similar function
      */
     public static function get_grades($courseid, $component = null, $activityid = null, $userids = array()) {
         global $CFG, $USER, $DB;
@@ -293,6 +297,8 @@ class core_grades_external extends external_api {
      * @param  int $iteminstance    Item instance
      * @param  int $itemnumber      Item number
      * @return grade_item           A grade_item instance
+     * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more.
+     * @see gradereport_user_external::get_grades_table for a similar function
      */
     private static function get_grade_item($courseid, $itemtype, $itemmodule = null, $iteminstance = null, $itemnumber = null) {
         $gradeiteminstance = null;
@@ -311,6 +317,8 @@ class core_grades_external extends external_api {
      *
      * @return external_description
      * @since Moodle 2.7
+     * @deprecated Moodle 3.2 MDL-51373 - Please do not call this function any more.
+     * @see gradereport_user_external::get_grades_table for a similar function
      */
     public static function get_grades_returns() {
         return new external_single_structure(
@@ -405,6 +413,15 @@ class core_grades_external extends external_api {
 
     }
 
+    /**
+     * Marking the method as deprecated.
+     *
+     * @return bool
+     */
+    public static function get_grades_is_deprecated() {
+        return true;
+    }
+
     /**
      * Returns description of method parameters
      *
index 6a978eb..0b983f3 100644 (file)
@@ -1660,6 +1660,7 @@ class core_plugin_manager {
         $plugins = array(
             'qformat' => array('blackboard', 'learnwise'),
             'enrol' => array('authorize'),
+            'report' => array('search'),
             'tinymce' => array('dragmath'),
             'tool' => array('bloglevelupgrade', 'qeupgradehelper', 'timezoneimport'),
             'theme' => array('mymobile', 'afterburner', 'anomaly', 'arialist', 'binarius', 'boxxie', 'brick', 'formal_white',
@@ -1870,7 +1871,7 @@ class core_plugin_manager {
 
             'report' => array(
                 'backups', 'competency', 'completion', 'configlog', 'courseoverview', 'eventlist',
-                'log', 'loglive', 'outline', 'participation', 'progress', 'questioninstances', 'search',
+                'log', 'loglive', 'outline', 'participation', 'progress', 'questioninstances',
                 'security', 'stats', 'performance', 'usersessions'
             ),
 
index 9894dc5..ebe4e6f 100644 (file)
@@ -90,7 +90,7 @@ class core_requirejs {
         $subsystems = core_component::get_core_subsystems();
         foreach ($subsystems as $subsystem => $dir) {
             if (!empty($dir) && is_dir($dir . '/amd')) {
-                $jsdirs[$subsystem] = $dir . '/amd';
+                $jsdirs['core_' . $subsystem] = $dir . '/amd';
             }
         }
         $plugintypes = core_component::get_plugin_types();
index 0cc9443..3148646 100644 (file)
@@ -393,7 +393,8 @@ $functions = array(
     'core_grades_get_grades' => array(
         'classname' => 'core_grades_external',
         'methodname' => 'get_grades',
-        'description' => 'Returns student course total grade and grades for activities.
+        'description' => '** DEPRECATED ** Please do not call this function any more.
+                                     Returns student course total grade and grades for activities.
                                      This function does not return category or manual items.
                                      This function is suitable for managers or teachers not students.',
         'type' => 'read',
index ee468b6..629ab19 100644 (file)
@@ -2072,5 +2072,16 @@ function xmldb_main_upgrade($oldversion) {
     // Moodle v3.1.0 release upgrade line.
     // Put any upgrade step following this.
 
+    if ($oldversion < 2016070700.01) {
+
+        // If someone is emotionally attached to it let's leave the config (basically the version) there.
+        if (!file_exists($CFG->dirroot . '/report/search/classes/output/form.php')) {
+            unset_all_config_for_plugin('report_search');
+        }
+
+        // Savepoint reached.
+        upgrade_main_savepoint(true, 2016070700.01);
+    }
+
     return true;
 }
index 6de6d84..5e429a8 100644 (file)
@@ -383,8 +383,23 @@ function upgrade_course_letter_boundary($courseid = null) {
     $systemcontext = context_system::instance();
     $systemneedsfreeze = upgrade_letter_boundary_needs_freeze($systemcontext);
 
+    // Check the setting for showing the letter grade in a column (default is false).
+    $usergradelettercolumnsetting = 0;
+    if (isset($CFG->grade_report_user_showlettergrade)) {
+        $usergradelettercolumnsetting = (int)$CFG->grade_report_user_showlettergrade;
+    }
+    $lettercolumnsql = '';
+    if ($usergradelettercolumnsetting) {
+        // the system default is to show a column with letters (and the course uses the defaults).
+        $lettercolumnsql = '(gss.value is NULL OR ' . $DB->sql_compare_text('gss.value') .  ' <> \'0\')';
+    } else {
+        // the course displays a column with letters.
+        $lettercolumnsql = $DB->sql_compare_text('gss.value') .  ' = \'1\'';
+    }
+
     // 3, 13, 23, 31, and 32 are the grade display types that incorporate showing letters. See lib/grade/constants/php.
-    $systemletters = (isset($CFG->grade_displaytype) && in_array($CFG->grade_displaytype, array(3, 13, 23, 31, 32)));
+    $systemusesletters = (int) (isset($CFG->grade_displaytype) && in_array($CFG->grade_displaytype, array(3, 13, 23, 31, 32)));
+    $systemletters = $systemusesletters || $usergradelettercolumnsetting;
 
     $contextselect = context_helper::get_preload_record_columns_sql('ctx');
 
@@ -397,40 +412,39 @@ function upgrade_course_letter_boundary($courseid = null) {
                   JOIN {grade_items} gi ON c.id = gi.courseid
                   JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
              LEFT JOIN {grade_settings} gs ON gs.courseid = c.id AND gs.name = 'displaytype'
+             LEFT JOIN {grade_settings} gss ON gss.courseid = c.id AND gss.name = 'report_user_showlettergrade'
              LEFT JOIN {grade_letters} gl ON gl.contextid = ctx.id
-                 WHERE gi.display = 0 AND (gs.value is NULL)
+                 WHERE gi.display = 0
+                 AND ((gs.value is NULL)
+                      AND ($lettercolumnsql))
                  AND gl.id is NULL $coursesql";
         $affectedcourseids = $DB->get_recordset_sql($sql, $params);
         foreach ($affectedcourseids as $courseid) {
             set_config('gradebook_calculations_freeze_' . $courseid->courseid, 20160518);
         }
         $affectedcourseids->close();
-
     }
 
-    if ($systemletters || $systemneedsfreeze) {
-
-        // If the system letter boundary is okay proceed to check grade item and course grade display settings.
-        $sql = "SELECT DISTINCT c.id AS courseid, $contextselect
-                  FROM {course} c
-                  JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
-                  JOIN {grade_items} gi ON c.id = gi.courseid
-             LEFT JOIN {grade_settings} gs ON c.id = gs.courseid AND gs.name = 'displaytype'
-             LEFT JOIN {grade_letters} gl ON gl.contextid = ctx.id
-                 WHERE gi.display IN (3, 13, 23, 31, 32)
-                    OR (" . $DB->sql_compare_text('gs.value') . " IN ('3', '13', '23', '31', '32'))
-                    OR gl.id is NOT NULL
-                       $coursesql";
-    } else {
-
-        // There is no site setting for letter grades. Just check the modified letter boundaries.
-        $sql = "SELECT DISTINCT c.id AS courseid, $contextselect
-                  FROM {grade_letters} l, {course} c
-                  JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
-                 WHERE l.contextid = ctx.id
-                   AND ctx.instanceid = c.id
-                   $coursesql";
-    }
+    // If the system letter boundary is okay proceed to check grade item and course grade display settings.
+    $sql = "SELECT DISTINCT c.id AS courseid, $contextselect
+              FROM {course} c
+              JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
+              JOIN {grade_items} gi ON c.id = gi.courseid
+         LEFT JOIN {grade_settings} gs ON c.id = gs.courseid AND gs.name = 'displaytype'
+         LEFT JOIN {grade_settings} gss ON gss.courseid = c.id AND gss.name = 'report_user_showlettergrade'
+             WHERE
+                (
+                    -- A grade item is using letters
+                    (gi.display IN (3, 13, 23, 31, 32))
+                    -- OR the course is using letters
+                    OR (" . $DB->sql_compare_text('gs.value') . " IN ('3', '13', '23', '31', '32')
+                        -- OR the course using the system default which is letters
+                        OR (gs.value IS NULL AND $systemusesletters = 1)
+                    )
+                    OR ($lettercolumnsql)
+                )
+                -- AND the course matches
+                $coursesql";
 
     $potentialcourses = $DB->get_recordset_sql($sql, $params);
 
@@ -475,7 +489,7 @@ function upgrade_letter_boundary_needs_freeze($context) {
         if (!empty($letters)) {
             foreach ($letters as $boundary => $notused) {
                 $standardisedboundary = upgrade_standardise_score($boundary, 0, 100, 0, 100);
-                if ($boundary != $standardisedboundary) {
+                if ($standardisedboundary < $boundary) {
                     return true;
                 }
             }
index 5c942e2..434b3e5 100644 (file)
@@ -38,7 +38,6 @@ div.editor_atto_toolbar button {
     margin: 0;
     border-radius: 0;
     cursor: pointer;
-    line-height: initial;
  }
 
 div.editor_atto_toolbar button + button {
index d10c55a..731161c 100644 (file)
Binary files a/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-debug.js and b/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor-debug.js differ
index 41bd2cd..0c89fae 100644 (file)
Binary files a/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor.js and b/lib/editor/atto/yui/build/moodle-editor_atto-editor/moodle-editor_atto-editor.js differ
index 41e53ad..73ae0b5 100644 (file)
Binary files a/lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin-debug.js and b/lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin-debug.js differ
index e436da5..6096475 100644 (file)
Binary files a/lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin.js and b/lib/editor/atto/yui/build/moodle-editor_atto-plugin/moodle-editor_atto-plugin.js differ
index 27f227a..7df539e 100644 (file)
@@ -12,6 +12,8 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/* global NOTIFY_WARNING, NOTIFY_INFO */
+/* eslint-disable no-unused-vars */
 
 /**
  * A autosave function for the Atto editor.
index 5b86018..cbcce69 100644 (file)
@@ -12,6 +12,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/* global LOGNAME */
 
 /**
  * @module moodle-editor_atto-editor
index b7f5eff..5048ddf 100644 (file)
@@ -12,6 +12,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/* global YUI */
 
 /**
  * @module moodle-editor_atto-plugin
index 8089a11..cba8839 100644 (file)
@@ -12,6 +12,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/* eslint-disable no-unused-vars */
 
 /**
  * The Atto WYSIWG pluggable editor, written for Moodle.
diff --git a/lib/editor/atto/yui/src/editor/js/lintconfig.js b/lib/editor/atto/yui/src/editor/js/lintconfig.js
deleted file mode 100644 (file)
index 9291d3b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/* globals rangy */
index 3f6c460..077794e 100644 (file)
@@ -12,6 +12,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/* global rangy */
 
 /**
  * @module moodle-editor_atto-editor
index 6c31d81..3e5c1a4 100644 (file)
@@ -12,6 +12,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/* global rangy */
 
 /**
  * @module moodle-editor_atto-editor
index 3c056a3..26cf46e 100644 (file)
@@ -12,6 +12,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/* global LOGNAME */
 
 /**
  * @module moodle-editor_atto-editor
index a92d6f7..ab3346c 100644 (file)
@@ -904,6 +904,7 @@ function external_format_string($str, $contextid, $striplinks = true, $options =
  *                      returned. Default false.
  *      allowid     :   If true then id attributes will not be removed, even when using htmlpurifier. Default (different from
  *                      format_text) true. Default changed id attributes are commonly needed.
+ *      blanktarget :   If true all <a> tags will have target="_blank" added unless target is explicitly specified.
  * </pre>
  *
  * @param string $text The content that may contain ULRs in need of rewriting.
@@ -915,14 +916,16 @@ function external_format_string($str, $contextid, $striplinks = true, $options =
  * @param object/array $options text formatting options
  * @return array text + textformat
  * @since Moodle 2.3
+ * @since Moodle 3.2 component, filearea and itemid are optional parameters
  */
-function external_format_text($text, $textformat, $contextid, $component, $filearea, $itemid, $options = null) {
+function external_format_text($text, $textformat, $contextid, $component = null, $filearea = null, $itemid = null,
+                                $options = null) {
     global $CFG;
 
     // Get settings (singleton).
     $settings = external_settings::get_instance();
 
-    if ($settings->get_fileurl()) {
+    if ($component and $filearea and $settings->get_fileurl()) {
         require_once($CFG->libdir . "/filelib.php");
         $text = file_rewrite_pluginfile_urls($text, $settings->get_file(), $contextid, $component, $filearea, $itemid);
     }
index 3c6e027..a9831d9 100644 (file)
Binary files a/lib/form/yui/build/moodle-form-dateselector/moodle-form-dateselector-debug.js and b/lib/form/yui/build/moodle-form-dateselector/moodle-form-dateselector-debug.js differ
index 3c6e027..a9831d9 100644 (file)
Binary files a/lib/form/yui/build/moodle-form-dateselector/moodle-form-dateselector.js and b/lib/form/yui/build/moodle-form-dateselector/moodle-form-dateselector.js differ
index a0b09a4..aa9c4fb 100644 (file)
@@ -1,3 +1,5 @@
+/* global CALENDAR, MOODLECALENDAR */
+
 /**
  * Add some custom methods to the node class to make our lives a little
  * easier within this module.
index 539a410..c495a63 100644 (file)
@@ -2460,9 +2460,7 @@ class global_navigation extends navigation_node {
 
         $coursenode = $parent->add($coursename, $url, self::TYPE_COURSE, $shortname, $course->id);
         $coursenode->hidden = (!$course->visible);
-        // We need to decode &amp;'s here as they will have been added by format_string above and attributes will be encoded again
-        // later.
-        $coursenode->title(str_replace('&amp;', '&', $fullname));
+        $coursenode->title(format_string($course->fullname, true, array('context' => $coursecontext, 'escape' => false)));
         if ($canexpandcourse) {
             // This course can be expanded by the user, make it a branch to make the system aware that its expandable by ajax.
             $coursenode->nodetype = self::NODETYPE_BRANCH;
index cda9bd3..f67947d 100644 (file)
@@ -105,8 +105,8 @@ class core_externallib_testcase extends advanced_testcase {
 
         $test = '$$ \pi $$';
         $testformat = FORMAT_MARKDOWN;
-        $correct = array('<span class="nolink"><span class="filter_mathjaxloader_equation"><p>$$ \pi $$</p>
-</span></span>', FORMAT_HTML);
+        $correct = array('<span class="filter_mathjaxloader_equation"><p><span class="nolink">$$ \pi $$</span></p>
+</span>', FORMAT_HTML);
         $this->assertSame(external_format_text($test, $testformat, $context->id, 'core', '', 0), $correct);
 
         // Filters can be opted out from by the developer.
@@ -196,6 +196,7 @@ class core_externallib_testcase extends advanced_testcase {
         $correct = 'ENFR hi there%';
         $this->assertSame($correct, external_format_string($test, $context->id, false, ['filter' => false]));
 
+        $this->assertSame("& < > \" '", format_string("& < > \" '", true, ['escape' => false]));
 
         $settings->set_raw($currentraw);
         $settings->set_filter($currentfilter);
diff --git a/lib/tests/requirejs_test.php b/lib/tests/requirejs_test.php
new file mode 100644 (file)
index 0000000..ef2732a
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Unit tests for requirejs loader.
+ *
+ * @package   core
+ * @author    Damyon Wiese <damyon@moodle.com>
+ * @copyright 2016 Damyon Wiese
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Unit tests for requirejs.
+ *
+ * @package   core
+ * @author    Damyon Wiese <damyon@moodle.com>
+ * @copyright 2016 Damyon Wiese
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class core_requirejs_testcase extends advanced_testcase {
+
+    /**
+     * Test requirejs loader
+     */
+    public function test_requirejs() {
+        global $CFG;
+
+        // Find a core module.
+        $result = core_requirejs::find_one_amd_module('core', 'templates', false);
+        $expected = ['core/templates' => $CFG->dirroot . '/lib/amd/build/templates.min.js'];
+        $this->assertEquals($expected, $result);
+
+        $result = core_requirejs::find_one_amd_module('core', 'templates', true);
+        $expected = ['core/templates' => $CFG->dirroot . '/lib/amd/src/templates.js'];
+        $this->assertEquals($expected, $result);
+
+        // Find a subsystem module (none exist yet).
+        $result = core_requirejs::find_one_amd_module('core_group', 'doesnotexist', false);
+        $expected = [];
+        $this->assertEquals($expected, $result);
+
+        // Find a plugin module.
+        $result = core_requirejs::find_one_amd_module('mod_assign', 'grading_panel', true);
+        $expected = ['mod_assign/grading_panel' => $CFG->dirroot . '/mod/assign/amd/src/grading_panel.js'];
+        $this->assertEquals($expected, $result);
+
+        // Find all modules - no debugging.
+        $result = core_requirejs::find_all_amd_modules(true);
+        foreach ($result as $key => $path) {
+            // Lets verify the first part of the key is a valid component name and the second part correctly contains "min" or not.
+            list($component, $template) = explode('/', $key, 2);
+            // Can we resolve it to a valid dir?
+            $dir = core_component::get_component_directory($component);
+            $this->assertNotEmpty($dir);
+
+            // Only "core" is allowed to have no _ in component names.
+            if (strpos($component, '_') === false) {
+                $this->assertEquals('core', $component);
+            }
+            $this->assertNotContains('.min', $path);
+        }
+
+        // Find all modules - debugging.
+        $result = core_requirejs::find_all_amd_modules(false);
+        foreach ($result as $key => $path) {
+            // Lets verify the first part of the key is a valid component name and the second part correctly contains "min" or not.
+            list($component, $template) = explode('/', $key, 2);
+            $dir = core_component::get_component_directory($component);
+            $this->assertNotEmpty($dir);
+            // Only "core" is allowed to have no _ in component names.
+            if (strpos($component, '_') === false) {
+                $this->assertEquals('core', $component);
+            }
+
+            $this->assertContains('.min', $path);
+        }
+
+    }
+}
index 07bc922..eaeb63d 100644 (file)
@@ -591,7 +591,7 @@ class core_upgradelib_testcase extends advanced_testcase {
         // Create some courses.
         $courses = array();
         $contexts = array();
-        for ($i = 0; $i < 37; $i++) {
+        for ($i = 0; $i < 45; $i++) {
             $course = $this->getDataGenerator()->create_course();
             $context = context_course::instance($course->id);
             if (in_array($i, array(2, 5, 10, 13, 14, 19, 23, 25, 30, 34, 36))) {
@@ -603,38 +603,44 @@ class core_upgradelib_testcase extends advanced_testcase {
                 $this->assign_bad_letter_boundary($context->id);
             }
 
-            if (in_array($i, array(9, 10, 11, 18, 19, 20, 29, 30, 31))) {
+            if (in_array($i, array(3, 9, 10, 11, 18, 19, 20, 29, 30, 31, 40))) {
                 grade_set_setting($course->id, 'displaytype', '3');
             } else if (in_array($i, array(8, 17, 28))) {
                 grade_set_setting($course->id, 'displaytype', '2');
             }
 
-            if ($i >= 7) {
-                $assignrow = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'name' => 'Test!'));
-                $gi = grade_item::fetch(
-                        array('itemtype' => 'mod',
-                              'itemmodule' => 'assign',
-                              'iteminstance' => $assignrow->id,
-                              'courseid' => $course->id));
-                if (in_array($i, array(13, 14, 15, 23, 24, 34, 35, 36))) {
-                    grade_item::set_properties($gi, array('display', 3));
-                    $gi->update();
-                } else if (in_array($i, array(12, 21, 32))) {
-                    grade_item::set_properties($gi, array('display', 2));
-                    $gi->update();
-                }
-                $gradegrade = new grade_grade();
-                $gradegrade->itemid = $gi->id;
-                $gradegrade->userid = $user->id;
-                $gradegrade->rawgrade = 55.5563;
-                $gradegrade->finalgrade = 55.5563;
-                $gradegrade->rawgrademax = 100;
-                $gradegrade->rawgrademin = 0;
-                $gradegrade->timecreated = time();
-                $gradegrade->timemodified = time();
-                $gradegrade->insert();
+            if (in_array($i, array(37, 43))) {
+                // Show.
+                grade_set_setting($course->id, 'report_user_showlettergrade', '1');
+            } else if (in_array($i, array(38, 42))) {
+                // Hide.
+                grade_set_setting($course->id, 'report_user_showlettergrade', '0');
             }
 
+            $assignrow = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'name' => 'Test!'));
+            $gi = grade_item::fetch(
+                    array('itemtype' => 'mod',
+                          'itemmodule' => 'assign',
+                          'iteminstance' => $assignrow->id,
+                          'courseid' => $course->id));
+            if (in_array($i, array(6, 13, 14, 15, 23, 24, 34, 35, 36, 41))) {
+                grade_item::set_properties($gi, array('display' => 3));
+                $gi->update();
+            } else if (in_array($i, array(12, 21, 32))) {
+                grade_item::set_properties($gi, array('display' => 2));
+                $gi->update();
+            }
+            $gradegrade = new grade_grade();
+            $gradegrade->itemid = $gi->id;
+            $gradegrade->userid = $user->id;
+            $gradegrade->rawgrade = 55.5563;
+            $gradegrade->finalgrade = 55.5563;
+            $gradegrade->rawgrademax = 100;
+            $gradegrade->rawgrademin = 0;
+            $gradegrade->timecreated = time();
+            $gradegrade->timemodified = time();
+            $gradegrade->insert();
+
             $contexts[] = $context;
             $courses[] = $course;
         }
@@ -659,7 +665,7 @@ class core_upgradelib_testcase extends advanced_testcase {
 
         // System setting for grade letter boundaries (default).
         set_config('grade_displaytype', '3');
-        for ($i = 0; $i < 37; $i++) {
+        for ($i = 0; $i < 45; $i++) {
             unset_config('gradebook_calculations_freeze_' . $courses[$i]->id);
         }
         upgrade_course_letter_boundary();
@@ -686,7 +692,7 @@ class core_upgradelib_testcase extends advanced_testcase {
         // System setting for grade letter boundaries (custom with problem).
         $systemcontext = context_system::instance();
         $this->assign_bad_letter_boundary($systemcontext->id);
-        for ($i = 0; $i < 37; $i++) {
+        for ($i = 0; $i < 45; $i++) {
             unset_config('gradebook_calculations_freeze_' . $courses[$i]->id);
         }
         upgrade_course_letter_boundary();
@@ -716,7 +722,7 @@ class core_upgradelib_testcase extends advanced_testcase {
 
         // System setting not showing letters.
         set_config('grade_displaytype', '2');
-        for ($i = 0; $i < 37; $i++) {
+        for ($i = 0; $i < 45; $i++) {
             unset_config('gradebook_calculations_freeze_' . $courses[$i]->id);
         }
         upgrade_course_letter_boundary();
@@ -741,6 +747,37 @@ class core_upgradelib_testcase extends advanced_testcase {
         $this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[35]->id});
         // [36] A course with grade display settings of letters with modified and good boundary (not 57) Should not be frozen.
         $this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[36]->id}));
+
+        // Previous site conditions still exist.
+        for ($i = 0; $i < 45; $i++) {
+            unset_config('gradebook_calculations_freeze_' . $courses[$i]->id);
+        }
+        upgrade_course_letter_boundary();
+
+        // [37] Site setting for not showing the letter column and course setting set to show (frozen).
+        $this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[37]->id});
+        // [38] Site setting for not showing the letter&n