Merge branch 'MDL-50312_master' of https://github.com/jinhofer/moodle
authorDan Poltawski <dan@moodle.com>
Tue, 23 Feb 2016 08:07:13 +0000 (08:07 +0000)
committerDan Poltawski <dan@moodle.com>
Tue, 23 Feb 2016 08:07:13 +0000 (08:07 +0000)
523 files changed:
CONTRIBUTING.txt [new file with mode: 0644]
Gruntfile.js
INSTALL.txt [new file with mode: 0644]
PULL_REQUEST_TEMPLATE.txt [new file with mode: 0644]
README.txt
TRADEMARK.txt
admin/environment.xml
admin/roles/classes/capability_table_with_risks.php
admin/tool/capability/styles.css
admin/tool/customlang/db/upgrade.php
admin/tool/log/db/upgrade.php
admin/tool/log/store/database/db/upgrade.php
admin/tool/log/store/standard/db/upgrade.php
auth/cas/db/upgrade.php
auth/ldap/auth.php
auth/ldap/db/upgrade.php
auth/manual/db/upgrade.php
auth/mnet/db/upgrade.php
auth/mnet/land.php
backup/backup.php
backup/restore.php
badges/tests/behat/award_badge.feature
blocks/activity_results/tests/behat/addunsupportedactivity.feature
blocks/activity_results/tests/behat/highscoreswithscales.feature
blocks/activity_results/tests/behat/highscoreswithscalesandgroups.feature
blocks/activity_results/tests/behat/lowscoreswithscales.feature
blocks/activity_results/tests/behat/lowscoreswithscalesandgroups.feature
blocks/blog_tags/block_blog_tags.php
blocks/blog_tags/tests/behat/blogtag.feature
blocks/community/db/upgrade.php
blocks/completionstatus/db/upgrade.php
blocks/course_summary/db/upgrade.php
blocks/glossary_random/backup/moodle2/restore_glossary_random_block_task.class.php
blocks/html/db/upgrade.php
blocks/navigation/db/upgrade.php
blocks/navigation/renderer.php
blocks/news_items/lang/en/block_news_items.php
blocks/news_items/tests/behat/display_news.feature
blocks/recent_activity/db/upgrade.php
blocks/section_links/db/upgrade.php
blocks/selfcompletion/db/upgrade.php
blocks/settings/db/upgrade.php
blocks/tags/block_tags.php
blocks/tags/edit_form.php
blocks/tags/lang/en/block_tags.php
blocks/tags/tests/behat/tagcloud.feature
blocks/tests/behat/hidden_block_region.feature
blocks/tests/behat/hide_blocks.feature
blog/tests/lib_test.php
config-dist.php
course/dndupload.js
course/dnduploadlib.php
course/editsection.php
course/format/lib.php
course/format/renderer.php
course/format/singleactivity/lang/en/format_singleactivity.php
course/format/singleactivity/lib.php
course/format/topics/lang/en/format_topics.php
course/format/topics/lib.php
course/format/topics/renderer.php
course/format/topics/tests/behat/edit_delete_sections.feature
course/format/topics/tests/format_topics_test.php
course/format/upgrade.txt
course/format/weeks/lang/en/format_weeks.php
course/format/weeks/lib.php
course/format/weeks/renderer.php
course/format/weeks/tests/behat/edit_delete_sections.feature
course/format/weeks/tests/format_weeks_test.php
course/lib.php
course/modlib.php
course/moodleform_mod.php
course/tests/behat/behat_course.php
course/tests/behat/course_creation.feature
course/tests/behat/coursetags.feature
enrol/database/db/upgrade.php
enrol/flatfile/db/upgrade.php
enrol/guest/db/upgrade.php
enrol/imsenterprise/db/upgrade.php
enrol/ldap/lib.php
enrol/ldap/tests/ldap_test.php
enrol/manual/db/upgrade.php
enrol/mnet/db/upgrade.php
enrol/paypal/db/upgrade.php
enrol/paypal/pix/icon.gif [deleted file]
enrol/self/db/upgrade.php
filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-debug.js
filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-min.js
filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker.js
filter/glossary/yui/src/autolinker/js/autolinker.js
filter/mathjaxloader/db/upgrade.php
filter/mediaplugin/db/upgrade.php
filter/tex/db/upgrade.php
grade/edit/tree/item.php
grade/edit/tree/item_form.php
grade/edit/tree/lib.php
grade/grading/form/rubric/db/upgrade.php
grade/grading/form/rubric/renderer.php
grade/lib.php
grade/report/grader/lib.php
grade/tests/behat/grade_aggregation.feature
grade/tests/behat/grade_calculated_grade_items.feature
grade/tests/behat/grade_calculated_grade_items_20150627.feature
grade/tests/behat/grade_grade_minmax_change.feature [new file with mode: 0644]
grade/tests/behat/grade_item_validation.feature [new file with mode: 0644]
grade/tests/behat/grade_minmax.feature
grade/tests/behat/grade_point_maximum.feature
grade/tests/behat/grade_scales_aggregation.feature
grade/tests/lib_test.php [new file with mode: 0644]
install/lang/bg/moodle.php
install/lang/dk_kursus/langconfig.php [new file with mode: 0644]
install/lang/es/admin.php
install/lang/oc_lnc/error.php
install/lang/ro/install.php
lang/en/deprecated.txt
lang/en/error.php
lang/en/grades.php
lang/en/moodle.php
lang/en/question.php
lang/en/repository.php
lang/en/role.php
lang/en/tag.php
lib/amd/build/fragment.min.js [new file with mode: 0644]
lib/amd/build/inplace_editable.min.js [new file with mode: 0644]
lib/amd/build/tag.min.js
lib/amd/src/fragment.js [new file with mode: 0644]
lib/amd/src/inplace_editable.js [new file with mode: 0644]
lib/amd/src/tag.js
lib/behat/behat_base.php
lib/behat/form_field/behat_form_field.php
lib/behat/form_field/behat_form_select.php
lib/classes/output/inplace_editable.php [new file with mode: 0644]
lib/classes/output/url_rewriter.php [new file with mode: 0644]
lib/classes/plugininfo/availability.php
lib/classes/task/delete_incomplete_users_task.php
lib/db/install.xml
lib/db/services.php
lib/db/tag.php
lib/db/upgrade.php
lib/db/upgradelib.php
lib/deprecatedlib.php
lib/dml/pgsql_native_moodle_database.php
lib/editor/atto/db/upgrade.php
lib/editor/atto/lib.php
lib/editor/atto/plugins/image/tests/behat/image.feature
lib/editor/atto/tests/behat/customtoolbar.feature [new file with mode: 0644]
lib/editor/atto/tests/fixtures/custom_toolbar_example.php [new file with mode: 0644]
lib/editor/tinymce/db/upgrade.php
lib/editor/tinymce/plugins/spellchecker/db/upgrade.php
lib/editorlib.php
lib/excellib.class.php
lib/external/externallib.php
lib/external/tests/external_test.php
lib/filelib.php
lib/flowplayer/LICENSE.txt [new file with mode: 0644]
lib/flowplayer/readme_moodle.txt
lib/form/advcheckbox.php
lib/form/dndupload.js
lib/form/modgrade.php
lib/form/tags.php
lib/form/tests/behat/modgrade_validation.feature [new file with mode: 0644]
lib/form/text.php
lib/form/url.php
lib/formslib.php
lib/grade/grade_item.php
lib/grade/tests/grade_item_test.php
lib/ldaplib.php
lib/moodlelib.php
lib/outputfragmentrequirementslib.php [new file with mode: 0644]
lib/outputrenderers.php
lib/pagelib.php
lib/pear/HTML/QuickForm/element.php
lib/pear/README_MOODLE.txt
lib/phpmailer/moodle_phpmailer.php
lib/phpunit/classes/util.php
lib/setup.php
lib/templates/email_fromname.mustache [new file with mode: 0644]
lib/templates/email_html.mustache [new file with mode: 0644]
lib/templates/email_subject.mustache [new file with mode: 0644]
lib/templates/email_text.mustache [new file with mode: 0644]
lib/templates/inplace_editable.mustache [new file with mode: 0644]
lib/testing/generator/data_generator.php
lib/tests/behat/behat_general.php
lib/tests/behat/behat_hooks.php
lib/tests/behat/behat_navigation.php
lib/tests/formslib_test.php
lib/tests/ldaplib_test.php
lib/tests/moodlelib_test.php
lib/tests/upgradelib_test.php
lib/upgrade.txt
lib/upgradelib.php
lib/weblib.php
login/signup_form.php
login/token.php
message/lib.php
message/output/email/db/upgrade.php
message/output/jabber/db/upgrade.php
message/output/popup/db/upgrade.php
message/tests/behat/delete_messages.feature
mnet/peer.php
mod/assign/db/upgrade.php
mod/assign/feedback/comments/db/upgrade.php
mod/assign/feedback/editpdf/db/upgrade.php
mod/assign/feedback/file/db/upgrade.php
mod/assign/gradingtable.php
mod/assign/lib.php
mod/assign/locallib.php
mod/assign/pix/icon.gif [deleted file]
mod/assign/submission/comments/db/upgrade.php
mod/assign/submission/file/db/upgrade.php
mod/assign/submission/onlinetext/db/upgrade.php
mod/assign/tests/behat/allow_another_attempt.feature
mod/assign/tests/behat/edit_previous_feedback.feature
mod/assign/tests/behat/rescale_grades.feature [new file with mode: 0644]
mod/assign/tests/events_test.php
mod/assign/tests/externallib_test.php
mod/assign/tests/locallib_test.php
mod/assign/yui/build/moodle-mod_assign-history/moodle-mod_assign-history-debug.js
mod/assign/yui/build/moodle-mod_assign-history/moodle-mod_assign-history-min.js
mod/assign/yui/build/moodle-mod_assign-history/moodle-mod_assign-history.js
mod/assign/yui/src/history/js/history.js
mod/assignment/db/upgrade.php
mod/assignment/db/upgradelib.php [deleted file]
mod/assignment/lang/en/assignment.php
mod/assignment/pix/icon.gif [deleted file]
mod/book/db/upgrade.php
mod/book/db/upgradelib.php [deleted file]
mod/book/locallib.php
mod/book/upgrade.txt
mod/chat/db/upgrade.php
mod/chat/pix/icon.gif [deleted file]
mod/choice/classes/event/answer_deleted.php [new file with mode: 0644]
mod/choice/classes/event/report_downloaded.php [new file with mode: 0644]
mod/choice/db/upgrade.php
mod/choice/lang/en/choice.php
mod/choice/lib.php
mod/choice/pix/icon.gif [deleted file]
mod/choice/report.php
mod/choice/tests/events_test.php
mod/choice/version.php
mod/choice/view.php
mod/data/classes/external.php
mod/data/db/upgrade.php
mod/data/pix/icon.gif [deleted file]
mod/feedback/analysis.php
mod/feedback/complete.php
mod/feedback/db/upgrade.php
mod/feedback/edit.php
mod/feedback/edit_form.php
mod/feedback/item/label/label_form.php
mod/feedback/item/multichoice/lib.php
mod/feedback/item/multichoice/multichoice_form.php
mod/feedback/item/multichoicerated/lib.php
mod/feedback/item/multichoicerated/multichoicerated_form.php
mod/feedback/item/textarea/lib.php
mod/feedback/lang/en/feedback.php
mod/feedback/lib.php
mod/feedback/pix/icon.gif [deleted file]
mod/feedback/tests/behat/behat_mod_feedback.php [new file with mode: 0644]
mod/feedback/tests/behat/question_types.feature [new file with mode: 0644]
mod/feedback/tests/behat/show_nonrespondents.feature
mod/folder/db/install.xml
mod/folder/db/upgrade.php
mod/folder/download_folder.php [new file with mode: 0644]
mod/folder/lang/en/folder.php
mod/folder/lib.php
mod/folder/mod_form.php
mod/folder/pix/icon.gif [deleted file]
mod/folder/renderer.php
mod/folder/settings.php
mod/folder/tests/externallib_test.php
mod/folder/version.php
mod/forum/backup/moodle2/backup_forum_activity_task.class.php
mod/forum/classes/output/forum_post.php
mod/forum/db/messages.php
mod/forum/db/upgrade.php
mod/forum/externallib.php
mod/forum/lang/en/forum.php
mod/forum/lib.php
mod/forum/pix/icon.gif [deleted file]
mod/forum/search.php
mod/forum/templates/forum_post_email_htmlemail.mustache
mod/forum/templates/forum_post_email_htmlemail_body.mustache [new file with mode: 0644]
mod/forum/templates/forum_post_email_textemail.mustache
mod/forum/templates/forum_post_emaildigestfull_htmlemail.mustache
mod/forum/tests/backup_forum_activity_test.php [new file with mode: 0644]
mod/forum/tests/behat/behat_mod_forum.php
mod/forum/tests/generator/lib.php
mod/forum/tests/lib_test.php
mod/forum/tests/maildigest_test.php
mod/forum/tests/output_email_test.php [new file with mode: 0644]
mod/forum/version.php
mod/glossary/db/upgrade.php
mod/glossary/pix/icon.gif [deleted file]
mod/imscp/db/upgrade.php
mod/imscp/pix/icon.gif [deleted file]
mod/imscp/tests/externallib_test.php
mod/label/db/upgrade.php
mod/label/pix/icon.gif [deleted file]
mod/lesson/db/upgrade.php
mod/lesson/lang/en/deprecated.txt
mod/lesson/lang/en/lesson.php
mod/lesson/mod_form.php
mod/lesson/pagetypes/truefalse.php
mod/lesson/pix/icon.gif [deleted file]
mod/lesson/settings.php
mod/lesson/styles.css
mod/lesson/tests/generator/lib.php
mod/lesson/version.php
mod/lti/classes/external.php
mod/lti/db/upgrade.php
mod/lti/pix/icon.gif [deleted file]
mod/lti/tests/externallib_test.php
mod/page/db/upgrade.php
mod/page/pix/icon.gif [deleted file]
mod/page/tests/externallib_test.php
mod/quiz/attemptlib.php
mod/quiz/classes/output/edit_renderer.php
mod/quiz/classes/structure.php
mod/quiz/db/upgrade.php
mod/quiz/locallib.php
mod/quiz/report/grading/report.php
mod/quiz/report/overview/db/upgrade.php
mod/quiz/report/statistics/db/upgrade.php
mod/quiz/report/statistics/statistics_table.php
mod/quiz/styles.css
mod/quiz/tests/behat/editing_remove_question.feature
mod/quiz/tests/structure_test.php
mod/quiz/upgrade.txt
mod/resource/db/upgrade.php
mod/resource/pix/icon.gif [deleted file]
mod/resource/tests/externallib_test.php
mod/scorm/backup/moodle1/lib.php
mod/scorm/backup/moodle2/backup_scorm_stepslib.php
mod/scorm/datamodels/scorm_12.js
mod/scorm/datamodels/scorm_12.php
mod/scorm/db/install.xml
mod/scorm/db/upgrade.php
mod/scorm/lang/en/scorm.php
mod/scorm/mod_form.php
mod/scorm/pix/icon.gif [deleted file]
mod/scorm/settings.php
mod/scorm/tests/generator/lib.php
mod/scorm/version.php
mod/survey/classes/external.php
mod/survey/db/upgrade.php
mod/survey/pix/icon.gif [deleted file]
mod/survey/report.php
mod/upgrade.txt
mod/url/db/upgrade.php
mod/url/pix/icon.gif [deleted file]
mod/url/tests/externallib_test.php
mod/wiki/db/upgrade.php
mod/wiki/locallib.php
mod/wiki/parser/markups/html.php
mod/wiki/parser/markups/wikimarkup.php
mod/wiki/pix/icon.gif [deleted file]
mod/wiki/tests/behat/edit_tags.feature
mod/wiki/tests/fixtures/input/html/3 [new file with mode: 0644]
mod/wiki/tests/fixtures/output/creole/2
mod/wiki/tests/fixtures/output/creole/3
mod/wiki/tests/fixtures/output/creole/4
mod/wiki/tests/fixtures/output/creole/5
mod/wiki/tests/fixtures/output/creole/7
mod/wiki/tests/fixtures/output/creole/8
mod/wiki/tests/fixtures/output/creole/9
mod/wiki/tests/fixtures/output/html/1
mod/wiki/tests/fixtures/output/html/3 [new file with mode: 0644]
mod/wiki/tests/fixtures/output/nwiki/1
mod/wiki/tests/fixtures/output/nwiki/2
mod/wiki/tests/fixtures/output/nwiki/3
mod/wiki/tests/lib_test.php
mod/wiki/tests/wikiparser_test.php
mod/workshop/db/upgrade.php
mod/workshop/form/accumulative/db/upgrade.php
mod/workshop/form/comments/db/upgrade.php
mod/workshop/form/numerrors/db/upgrade.php
mod/workshop/form/rubric/db/upgrade.php
mod/workshop/pix/icon.gif [deleted file]
my/tests/behat/add_blocks.feature
my/tests/behat/reset_all_pages.feature
my/tests/behat/reset_page.feature
npm-shrinkwrap.json
package.json
portfolio/boxnet/db/upgrade.php
portfolio/boxnet/db/upgradelib.php [deleted file]
portfolio/boxnet/lang/en/portfolio_boxnet.php
portfolio/googledocs/db/upgrade.php
portfolio/googledocs/db/upgradelib.php [deleted file]
portfolio/googledocs/lang/en/portfolio_googledocs.php
portfolio/picasa/db/upgrade.php
portfolio/picasa/db/upgradelib.php [deleted file]
portfolio/picasa/lang/en/portfolio_picasa.php
portfolio/upgrade.txt
question/behaviour/manualgraded/db/upgrade.php
question/classes/engine/variants/least_used_strategy.php
question/engine/datalib.php
question/engine/lib.php
question/engine/renderer.php
question/engine/upgrade.txt
question/tests/previewlib_test.php [new file with mode: 0644]
question/type/calculated/db/upgrade.php
question/type/ddimageortext/styles.css
question/type/ddwtos/styles.css
question/type/description/tests/behat/add.feature [new file with mode: 0644]
question/type/description/tests/behat/backup_and_restore.feature [new file with mode: 0644]
question/type/description/tests/behat/edit.feature [new file with mode: 0644]
question/type/description/tests/behat/export.feature [new file with mode: 0644]
question/type/description/tests/behat/import.feature [new file with mode: 0644]
question/type/description/tests/behat/preview.feature [new file with mode: 0644]
question/type/description/tests/fixtures/testquestion.moodle.xml [new file with mode: 0644]
question/type/essay/db/upgrade.php
question/type/essay/tests/behat/add.feature [new file with mode: 0644]
question/type/essay/tests/behat/backup_and_restore.feature [new file with mode: 0644]
question/type/essay/tests/behat/edit.feature [new file with mode: 0644]
question/type/essay/tests/behat/export.feature [new file with mode: 0644]
question/type/essay/tests/behat/import.feature [new file with mode: 0644]
question/type/essay/tests/behat/preview.feature [new file with mode: 0644]
question/type/essay/tests/fixtures/testquestion.moodle.xml [new file with mode: 0644]
question/type/match/db/upgrade.php
question/type/match/tests/behat/add.feature [new file with mode: 0644]
question/type/match/tests/behat/backup_and_restore.feature [new file with mode: 0644]
question/type/match/tests/behat/edit.feature [new file with mode: 0644]
question/type/match/tests/behat/export.feature [new file with mode: 0644]
question/type/match/tests/behat/import.feature [new file with mode: 0644]
question/type/match/tests/behat/preview.feature [new file with mode: 0644]
question/type/match/tests/fixtures/testquestion.moodle.xml [new file with mode: 0644]
question/type/multianswer/db/upgrade.php
question/type/multichoice/db/upgrade.php
question/type/multichoice/tests/behat/add.feature [new file with mode: 0644]
question/type/multichoice/tests/behat/backup_and_restore.feature [new file with mode: 0644]
question/type/multichoice/tests/behat/edit.feature [new file with mode: 0644]
question/type/multichoice/tests/behat/export.feature [new file with mode: 0644]
question/type/multichoice/tests/behat/import.feature [new file with mode: 0644]
question/type/multichoice/tests/behat/preview.feature [new file with mode: 0644]
question/type/multichoice/tests/fixtures/testquestion.moodle.xml [new file with mode: 0644]
question/type/numerical/db/upgrade.php
question/type/random/db/upgrade.php
question/type/randomsamatch/db/upgrade.php
question/type/shortanswer/db/upgrade.php
question/type/shortanswer/tests/behat/add.feature [new file with mode: 0644]
question/type/shortanswer/tests/behat/backup_and_restore.feature [new file with mode: 0644]
question/type/shortanswer/tests/behat/edit.feature [new file with mode: 0644]
question/type/shortanswer/tests/behat/export.feature [new file with mode: 0644]
question/type/shortanswer/tests/behat/import.feature [new file with mode: 0644]
question/type/shortanswer/tests/behat/preview.feature [new file with mode: 0644]
question/type/shortanswer/tests/fixtures/testquestion.moodle.xml [new file with mode: 0644]
question/type/truefalse/tests/behat/add.feature [new file with mode: 0644]
question/type/truefalse/tests/behat/backup_and_restore.feature [new file with mode: 0644]
question/type/truefalse/tests/behat/edit.feature [new file with mode: 0644]
question/type/truefalse/tests/behat/export.feature [new file with mode: 0644]
question/type/truefalse/tests/behat/import.feature [new file with mode: 0644]
question/type/truefalse/tests/behat/preview.feature [new file with mode: 0644]
question/type/truefalse/tests/fixtures/testquestion.moodle.xml [new file with mode: 0644]
question/type/upgrade.txt
repository/alfresco/db/upgrade.php
repository/alfresco/db/upgradelib.php [deleted file]
repository/alfresco/lang/en/repository_alfresco.php
repository/boxnet/db/upgrade.php
repository/boxnet/db/upgradelib.php [deleted file]
repository/boxnet/lang/en/repository_boxnet.php
repository/dropbox/db/upgrade.php
repository/googledocs/db/upgrade.php
repository/googledocs/db/upgradelib.php [deleted file]
repository/googledocs/lang/en/repository_googledocs.php
repository/lib.php
repository/picasa/db/upgrade.php
repository/picasa/db/upgradelib.php [deleted file]
repository/picasa/lang/en/repository_picasa.php
repository/upgrade.txt
rss/file.php
tag/classes/area.php
tag/classes/areas_table.php
tag/classes/collection.php
tag/classes/external.php
tag/classes/manage_table.php
tag/classes/output/tag.php
tag/classes/output/tagcloud.php
tag/classes/output/taglist.php
tag/classes/output/tagname.php [new file with mode: 0644]
tag/classes/renderer.php
tag/classes/tag.php
tag/edit.php
tag/edit_form.php
tag/lib.php
tag/manage.php
tag/templates/tagcloud.mustache
tag/templates/tagisstandard.mustache [moved from tag/templates/tagtype.mustache with 66% similarity]
tag/templates/taglist.mustache
tag/templates/tagname.mustache [deleted file]
tag/tests/behat/collections.feature
tag/tests/behat/delete_tag.feature
tag/tests/behat/edit_tag.feature
tag/tests/behat/flag_tags.feature
tag/tests/behat/official_tags.feature [deleted file]
tag/tests/behat/standard_tags.feature [new file with mode: 0644]
tag/tests/external_test.php
tag/tests/taglib_test.php
tag/upgrade.txt
theme/base/style/core.css
theme/bootstrapbase/less/moodle/bootstrapoverride.less
theme/bootstrapbase/less/moodle/core.less
theme/bootstrapbase/less/moodle/course.less
theme/bootstrapbase/style/moodle.css
theme/more/db/upgrade.php
user/addnote.php
user/edit_form.php
user/editadvanced_form.php
user/editlib.php
user/forum.php
user/lib.php
user/tests/behat/add_blocks.feature
user/tests/behat/name_fields.feature [new file with mode: 0644]
user/tests/behat/reset_page.feature
version.php
webservice/lib.php
webservice/soap/classes/wsdl.php [new file with mode: 0644]
webservice/soap/lib.php
webservice/soap/locallib.php
webservice/soap/tests/wsdl_test.php [new file with mode: 0644]
webservice/soap/version.php
webservice/tests/externallib_test.php
webservice/tests/lib_test.php [new file with mode: 0644]
webservice/upgrade.txt

diff --git a/CONTRIBUTING.txt b/CONTRIBUTING.txt
new file mode 100644 (file)
index 0000000..cfadb71
--- /dev/null
@@ -0,0 +1,56 @@
+CONTRIBUTING TO MOODLE
+======================
+
+Moodle is made by people like you. We are members of a big worldwide community
+of developers, designers, teachers, testers, translators and other users. We
+work in universities, schools, companies and other places. You are very welcome
+to join us and contribute to the project.
+
+See <https://docs.moodle.org/dev/Contributing_to_Moodle> for the many ways you
+can help, not only with coding.
+
+Moodle is open to community contributions to core, though all code must go
+through peer-review, automated behaviour testing, continuous integration and
+human post-integration checks.
+
+Pull requests
+-------------
+
+Please do not open pull requests via Github. The repository there is just a
+mirror of the official repository at <https://git.moodle.org>. Issues are
+reported and patches provided via <https://tracker.moodle.org>. See below for
+more information.
+
+Moodle core bug fixes and new features
+--------------------------------------
+
+During the years of intensive development, a mature process of including
+submitted patches has evolved.
+
+* Every bug fix or new feature must have a tracker issue.
+* You publish the branch implementing the fix or new feature in your public
+  clone of the moodle.git repository (typically on Github).
+* Your patch is peer-reviewed, discussed, integrated, tested and then released
+  as a part of moodle.git.
+* New features are developed on the master branch. Bug fixes are also
+  backported to currently supported maintenance (stable) branches.
+
+For further details, see <https://docs.moodle.org/dev/Process>.
+
+Moodle plugins
+--------------
+
+Moodle has a framework for additional plugins to extend its functionality. We
+have a Moodle plugins directory <https://moodle.org/plugins/> where you can
+register and maintain your plugin. Plugins hosted in the plugins directory can
+be easily installed and updated via the Moodle administration interface.
+
+* You are expected to have a public source code repository with your plugin
+  code.
+* After registering your plugin in the plugins directory it is reviewed before
+  being published.
+* You are expected to continuously release updated versions of the plugin via
+  the plugins directory. We do not pull from your code repository; you must do
+  it explicitly.
+
+For further details, see <https://docs.moodle.org/dev/Plugin_contribution>.
index 3dd3ef0..7412970 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/>.
+/* jshint node: true, browser: false */
 
 /**
  * @copyright  2014 Andrew Nicols
 
 module.exports = function(grunt) {
     var path = require('path'),
-        fs = require('fs'),
         tasks = {},
-        cwd = process.env.PWD || process.cwd(),
-        inAMD = path.basename(cwd) == 'amd';
+        cwd = process.env.PWD || process.cwd();
+
+    // Windows users can't run grunt in a subdirectory, so allow them to set
+    // the root by passing --root=path/to/dir.
+    if (grunt.option('root')) {
+        var root = grunt.option('root');
+        if (grunt.file.exists(__dirname, root)) {
+            cwd = path.join(__dirname, root);
+            grunt.log.ok('Setting root to '+cwd);
+        } else {
+            grunt.fail.fatal('Setting root to '+root+' failed - path does not exist');
+        }
+    }
+
+    var inAMD = path.basename(cwd) == 'amd';
+
+    // Globbing pattern for matching all AMD JS source files.
+    var amdSrc = [inAMD ? cwd + '/src/*.js' : '**/amd/src/*.js'];
+
+    /**
+     * Function to generate the destination for the uglify task
+     * (e.g. build/file.min.js). This function will be passed to
+     * the rename property of files array when building dynamically:
+     * http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically
+     *
+     * @param {String} destPath the current destination
+     * @param {String} srcPath the  matched src path
+     * @return {String} The rewritten destination path.
+     */
+    var uglify_rename = function (destPath, srcPath) {
+        destPath = srcPath.replace('src', 'build');
+        destPath = destPath.replace('.js', '.min.js');
+        destPath = path.resolve(cwd, destPath);
+        return destPath;
+    };
 
     // Project configuration.
     grunt.initConfig({
         jshint: {
             options: {jshintrc: '.jshintrc'},
-            files: [inAMD ? cwd + '/src/*.js' : '**/amd/src/*.js']
+            amd: { src: amdSrc }
         },
         uglify: {
-            dynamic_mappings: {
-                files: grunt.file.expandMapping(
-                    ['**/src/*.js', '!**/node_modules/**'],
-                    '',
-                    {
-                        cwd: cwd,
-                        rename: function(destBase, destPath) {
-                            destPath = destPath.replace('src', 'build');
-                            destPath = destPath.replace('.js', '.min.js');
-                            destPath = path.resolve(cwd, destPath);
-                            return destPath;
-                        }
-                    }
-                )
+            amd: {
+                files: [{
+                    expand: true,
+                    src: amdSrc,
+                    rename: uglify_rename
+                }]
             }
         },
         less: {
@@ -62,54 +87,79 @@ module.exports = function(grunt) {
                     compress: true
                 }
            }
+        },
+        watch: {
+            options: {
+                nospawn: true // We need not to spawn so config can be changed dynamically.
+            },
+            amd: {
+                files: ['**/amd/src/**/*.js'],
+                tasks: ['amd']
+            },
+            bootstrapbase: {
+                files: ["theme/bootstrapbase/less/**/*.less"],
+                tasks: ["less:bootstrapbase"]
+            },
+            yui: {
+                files: ['**/yui/src/**/*.js'],
+                tasks: ['shifter']
+            },
+        },
+        shifter: {
+            options: {
+                recursive: true,
+                paths: [cwd]
+            }
         }
     });
 
+    /**
+     * Shifter task. Is configured with a path to a specific file or a directory,
+     * in the case of a specific file it will work out the right module to be built.
+     *
+     * Note that this task runs the invidiaul shifter jobs async (becase it spawns
+     * so be careful to to call done().
+     */
     tasks.shifter = function() {
-       var  exec = require('child_process').spawn,
+        var async = require('async'),
             done = this.async(),
-            args = [],
-            options = {
-                recursive: true,
-                watch: false,
-                walk: false,
-                module: false
-            },
-            shifter;
+            options = grunt.config('shifter.options');
 
+        // Run the shifter processes one at a time to avoid confusing output.
+        async.eachSeries(options.paths, function (src, filedone) {
+            var args = [];
             args.push( path.normalize(__dirname + '/node_modules/shifter/bin/shifter'));
 
+            // Always ignore the node_modules directory.
+            args.push('--excludes', 'node_modules');
+
             // Determine the most appropriate options to run with based upon the current location.
-            if (path.basename(cwd) === 'src') {
-                // Detect whether we're in a src directory.
+            if (grunt.file.isMatch('**/yui/**/*.js', src)) {
+                // When passed a JS file, build our containing module (this happen with
+                // watch).
+                grunt.log.debug('Shifter passed a specific JS file');
+                src = path.dirname(path.dirname(src));
+                options.recursive = false;
+            } else if (grunt.file.isMatch('**/yui/src', src)) {
+                // When in a src directory --walk all modules.
                 grunt.log.debug('In a src directory');
                 args.push('--walk');
-                options.walk = true;
-            } else if (path.basename(path.dirname(cwd)) === 'src') {
-                // Detect whether we're in a module directory.
+                options.recursive = false;
+            } else if (grunt.file.isMatch('**/yui/src/*', src)) {
+                // When in module, only build our module.
                 grunt.log.debug('In a module directory');
-                options.module = true;
-            }
-
-            if (grunt.option('watch')) {
-                if (!options.walk && !options.module) {
-                    grunt.fail.fatal('Unable to watch unless in a src or module directory');
-                }
-
-                // It is not advisable to run with recursivity and watch - this
-                // leads to building the build directory in a race-like fashion.
-                grunt.log.debug('Detected a watch - disabling recursivity');
                 options.recursive = false;
-                args.push('--watch');
+            } else if (grunt.file.isMatch('**/yui/src/*/js', src)) {
+                // When in module src, only build our module.
+                grunt.log.debug('In a source directory');
+                src = path.dirname(src);
+                options.recursive = false;
             }
 
-            if (options.recursive) {
-                args.push('--recursive');
+            if (grunt.option('watch')) {
+                grunt.fail.fatal('The --watch option has been removed, please use `grunt watch` instead');
             }
 
-            // Always ignore the node_modules directory.
-            args.push('--excludes', 'node_modules');
-
             // Add the stderr option if appropriate
             if (grunt.option('verbose')) {
                 args.push('--lint-stderr');
@@ -121,19 +171,17 @@ module.exports = function(grunt) {
 
             var execShifter = function() {
 
-                shifter = exec("node", args, {
-                    cwd: cwd,
-                    stdio: 'inherit',
-                    env: process.env
-                });
-
-                // Tidy up after exec.
-                shifter.on('exit', function (code) {
+                grunt.log.ok("Running shifter on " + src);
+                grunt.util.spawn({
+                    cmd: "node",
+                    args: args,
+                    opts: {cwd: src, stdio: 'inherit', env: process.env}
+                }, function (error, result, code) {
                     if (code) {
                         grunt.fail.fatal('Shifter failed with code: ' + code);
                     } else {
                         grunt.log.ok('Shifter build complete.');
-                        done();
+                        filedone();
                     }
                 });
             };
@@ -143,79 +191,15 @@ module.exports = function(grunt) {
                 execShifter();
             } else {
                 // Check that there are yui modules otherwise shifter ends with exit code 1.
-                var found = false;
-                var hasYuiModules = function(directory, callback) {
-                    fs.readdir(directory, function(err, files) {
-                        if (err) {
-                            return callback(err, null);
-                        }
-
-                        // If we already found a match there is no need to continue scanning.
-                        if (found === true) {
-                            return;
-                        }
-
-                        // We need to track the number of files to know when we return a result.
-                        var pending = files.length;
-
-                        // We first check files, so if there is a match we don't need further
-                        // async calls and we just return a true.
-                        for (var i = 0; i < files.length; i++) {
-                            if (files[i] === 'yui') {
-                                return callback(null, true);
-                            }
-                        }
-
-                        // Iterate through subdirs if there were no matches.
-                        files.forEach(function (file) {
-
-                            var p = path.join(directory, file);
-                            stat = fs.statSync(p);
-                            if (!stat.isDirectory()) {
-                                pending--;
-                            } else {
-
-                                // We defer the pending-1 until we scan the whole dir and subdirs.
-                                hasYuiModules(p, function(err, result) {
-                                    if (err) {
-                                        return callback(err);
-                                    }
-
-                                    if (result === true) {
-                                        // Once we get a true we notify the caller.
-                                        found = true;
-                                        return callback(null, true);
-                                    }
-
-                                    pending--;
-                                    if (pending === 0) {
-                                        // Notify the caller that the whole dir has been scaned and there are no matches.
-                                        return callback(null, false);
-                                    }
-                                });
-                            }
-
-                            // No subdirs here, otherwise the return would be deferred until all subdirs are scanned.
-                            if (pending === 0) {
-                                return callback(null, false);
-                            }
-                        });
-                    });
-                };
-
-                hasYuiModules(cwd, function(err, result) {
-                    if (err) {
-                        grunt.fail.fatal(err.message);
-                    }
-
-                    if (result === true) {
-                        execShifter();
-                    } else {
-                        grunt.log.ok('No YUI modules to build.');
-                        done();
-                    }
-                });
+                if (grunt.file.expand({cwd: src}, '**/yui/src/**/*.js').length > 0) {
+                    args.push('--recursive');
+                    execShifter();
+                } else {
+                    grunt.log.ok('No YUI modules to build.');
+                    filedone();
+                }
             }
+        }, done);
     };
 
     tasks.startup = function() {
@@ -232,11 +216,28 @@ module.exports = function(grunt) {
         }
     };
 
+    // On watch, we dynamically modify config to build only affected files. This
+    // method is slightly complicated to deal with multiple changed files at once (copied
+    // from the grunt-contrib-watch readme).
+    var changedFiles = Object.create(null);
+    var onChange = grunt.util._.debounce(function() {
+          var files = Object.keys(changedFiles);
+          grunt.config('jshint.amd.src', files);
+          grunt.config('uglify.amd.files', [{ expand: true, src: files, rename: uglify_rename }]);
+          grunt.config('shifter.options.paths', files);
+          changedFiles = Object.create(null);
+    }, 200);
+
+    grunt.event.on('watch', function(action, filepath) {
+          changedFiles[filepath] = action;
+          onChange();
+    });
 
     // Register NPM tasks.
     grunt.loadNpmTasks('grunt-contrib-uglify');
     grunt.loadNpmTasks('grunt-contrib-jshint');
     grunt.loadNpmTasks('grunt-contrib-less');
+    grunt.loadNpmTasks('grunt-contrib-watch');
 
     // Register JS tasks.
     grunt.registerTask('shifter', 'Run Shifter against the current directory', tasks.shifter);
diff --git a/INSTALL.txt b/INSTALL.txt
new file mode 100644 (file)
index 0000000..8f8689b
--- /dev/null
@@ -0,0 +1,20 @@
+MOODLE INSTALLATION
+===================
+
+Here is a short summary of the installation process (which can take just a few
+minutes):
+
+1. Move the Moodle files into your web directory.
+
+2. Create a single database for Moodle to store all its tables in (or choose an
+   existing database).
+
+3. Visit your Moodle site with a browser. You should be taken to the
+   install.php script, which will lead you through creating a config.php file
+   and then setting up Moodle, creating an admin account etc.
+
+4. Set up a cron task to call the file admin/cron.php every minute.
+
+For more information, see <https://docs.moodle.org/en/Installing_Moodle>.
+
+Good luck and have fun!
diff --git a/PULL_REQUEST_TEMPLATE.txt b/PULL_REQUEST_TEMPLATE.txt
new file mode 100644 (file)
index 0000000..c497344
--- /dev/null
@@ -0,0 +1,7 @@
+*** PLEASE DO NOT OPEN PULL REQUESTS VIA GITHUB ***
+
+The moodle.git repository at Github is just a mirror of the official repository. We do not accept pull requests at Github.
+
+See CONTRIBUTING.txt guidelines for how to contribute patches for Moodle. Thank you.
+
+--
index b1017df..729dbe4 100644 (file)
@@ -1,29 +1,28 @@
-QUICK INSTALL
-=============
+                                 .-..-.
+   _____                         | || |
+  /____/-.---_  .---.  .---.  .-.| || | .---.
+  | |  _   _  |/  _  \/  _  \/  _  || |/  __ \
+  * | | | | | || |_| || |_| || |_| || || |___/
+    |_| |_| |_|\_____/\_____/\_____||_|\_____)
 
-For the impatient, here is a basic outline of the
-installation process, which normally takes me only
-a few minutes:
+Moodle - the world's open source learning platform
 
-1) Move the Moodle files into your web directory.
+Moodle <https://moodle.org> is a learning platform designed to provide
+educators, administrators and learners with a single robust, secure and
+integrated system to create personalised learning environments.
 
-2) Create a single database for Moodle to store all
-   its tables in (or choose an existing database).
+You can download Moodle <https://download.moodle.org> and run it on your own
+web server, ask one of our Moodle Partners <https://moodle.com/partners/> to
+assist you, or have a MoodleCloud site <https://moodle.com/cloud/> set up for
+you.
 
-3) Visit your Moodle site with a browser, you should
-   be taken to the install.php script, which will lead
-   you through creating a config.php file and then
-   setting up Moodle, creating an admin account etc.
+Moodle is widely used around the world by universities, schools, companies and
+all manner of organisations and individuals.
 
-4) Set up a cron task to call the file admin/cron.php
-   every five minutes or so.
+Moodle is provided freely as open source software, under the GNU General Public
+License <https://docs.moodle.org/dev/License>.
 
+Moodle is written in PHP and JavaScript and uses an SQL database for storing
+the data.
 
-For more information, see the INSTALL DOCUMENTATION:
-
-   http://docs.moodle.org/en/Installing_Moodle
-
-
-Good luck and have fun!
-Martin Dougiamas, Lead Developer
-
+See <https://docs.moodle.org> for details of Moodle's many features.
index d73a076..f1e3f15 100644 (file)
@@ -1,34 +1,48 @@
-------------------------
-Moodle Trademark License
-------------------------
-
-The name Moodle™ is a registered trademark of the Moodle Trust.
-
-A key part of the business model that allows us to produce and
-distribute Moodle as completely Free open source software is that
-we restrict the commercial use of the Moodle trademark to those
-who have contracted to support Moodle development (Moodle Partners).
-
-If you are intending to use the name (and/or logo) to advertise
-generic Moodle™ services (eg Moodle Hosting, Moodle Support,
-Moodle Certification, Moodle Training, Moodle Consulting,
-Moodle Customisation, Moodle Courseware Development, Moodle
-Theme design, Moodle Integrations, Moodle Installations, etc)
-or as the name of a software package, then you must seek
-direct permission in writing from the Moodle Trust via the
-moodle.com helpdesk, in accordance with normal trademark
-restrictions.
-
-There are no restrictions on how you use the name in other
-contexts (for example, if you use Moodle just to provide
-courses then you can use the name freely to refer to it.)
-
-If you aren't sure of a particular case, please ask us via
-http://moodle.com/helpdesk: we'll be happy to either provide
-you with official permission in writing or help you fix
-your wording.
-
-Martin Dougiamas
-Executive Director
-Moodle Trust
-http://moodle.com
+MOODLE TRADEMARKS POLICY
+========================
+
+The word "Moodle" is trademarked in many countries around the world. The word
+was originally an acronym: Modular Object-Oriented Dynamic Learning
+Environment. The trademark is owned by Martin Dougiamas, Founder and Director
+of Moodle.
+
+The law obligates trademark owners to police their marks and prevent the use of
+confusingly similar names by third parties. Through this policy we’d like to
+make it clear how Moodle-related projects, organisations, and people can use
+the Moodle trademark. We’d also like to be clear about how use of the word is
+restricted when used to promote commercial Moodle services. We do this to
+protect the very business model that allows us to continue developing Moodle
+for you.
+
+Allowed uses
+------------
+
+The following uses don’t require any permission at all:
+
+* Referring to the software or the Moodle project.
+* Describing your own Moodle implementation (including within corporate
+  settings).
+* Describing a Moodle-based community hub.
+* Describing some software you’ve made that integrates with Moodle
+  (eg a Moodle integration feature on another system).
+
+Restricted uses
+---------------
+
+The following uses are generally prohibited without explicit and direct
+permission being granted to you by Moodle Pty Ltd. We do this to protect the
+Moodle project from software and sites which could confuse people. Please
+contact us to ask for permission in writing.
+
+* You can’t use "Moodle" in the name of your software (including Mobile apps)
+* You can’t use "Moodle" in your company name
+* You can’t use "Moodle" in your domain name
+* You can’t use "Moodle" in advertising-related keywords (such as Adsense)
+* You can’t use "Moodle" to describe services around Moodle (such as hosting,
+  training, support, consulting, course creation services, theme development,
+  customisation, installation, integration and certification). This applies
+  even if you do not charge for the services. Note that usually only Moodle
+  Partners have this permission.
+
+For information about the Moodle Partner Certification Mark as well as for how
+to contact us, please see <https://moodle.com/trademarks/>.
index 4bf5798..43bc5e4 100644 (file)
       </CUSTOM_CHECK>
     </CUSTOM_CHECKS>
   </MOODLE>
+  <MOODLE version="3.1" requires="2.7">
+    <UNICODE level="required">
+      <FEEDBACK>
+        <ON_ERROR message="unicoderequired" />
+      </FEEDBACK>
+    </UNICODE>
+    <DATABASE level="required">
+      <VENDOR name="mariadb" version="5.5.31" />
+      <VENDOR name="mysql" version="5.5.31" />
+      <VENDOR name="postgres" version="9.1" />
+      <VENDOR name="mssql" version="10.0" />
+      <VENDOR name="oracle" version="10.2" />
+    </DATABASE>
+    <PHP version="5.4.4" level="required">
+    </PHP>
+    <PCREUNICODE level="optional">
+      <FEEDBACK>
+        <ON_CHECK message="pcreunicodewarning" />
+      </FEEDBACK>
+    </PCREUNICODE>
+    <PHP_EXTENSIONS>
+      <PHP_EXTENSION name="iconv" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="iconvrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="mbstring" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="mbstringrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="curl" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="curlrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="openssl" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="opensslrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="tokenizer" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="tokenizerrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="xmlrpc" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="xmlrpcrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="soap" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="soaprecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="ctype" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="ctyperequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="zip" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="ziprequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="zlib" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="gd" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="gdrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="simplexml" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="simplexmlrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="spl" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="splrequired" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="pcre" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="dom" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="xml" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="intl" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="intlrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="json" level="required">
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="hash" level="required"/>
+    </PHP_EXTENSIONS>
+    <PHP_SETTINGS>
+      <PHP_SETTING name="memory_limit" value="96M" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="settingmemorylimit" />
+        </FEEDBACK>
+      </PHP_SETTING>
+      <PHP_SETTING name="file_uploads" value="1" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="settingfileuploads" />
+        </FEEDBACK>
+      </PHP_SETTING>
+      <PHP_SETTING name="opcache.enable" value="1" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="opcacherecommended" />
+        </FEEDBACK>
+      </PHP_SETTING>
+    </PHP_SETTINGS>
+    <CUSTOM_CHECKS>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="unsupporteddbstorageengine" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
+        <FEEDBACK>
+          <ON_ERROR message="quizattemptsupgradedmessage" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="slashargumentswarning" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+      <CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="unsupporteddbtablerowformat" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+    </CUSTOM_CHECKS>
+  </MOODLE>
 </COMPATIBILITY_MATRIX>
index acf7257..96addb5 100644 (file)
@@ -35,7 +35,6 @@ abstract class core_role_capability_table_with_risks extends core_role_capabilit
     protected $allpermissions; // We don't need perms ourselves, but all our subclasses do.
     protected $strperms; // Language string cache.
     protected $risksurl; // URL in moodledocs about risks.
-    protected $riskicons = array(); // Cache to avoid regenerating the HTML for each risk icon.
     /** @var array The capabilities to highlight as default/inherited. */
     protected $parentpermissions;
     protected $displaypermissions;
@@ -183,12 +182,12 @@ abstract class core_role_capability_table_with_risks extends core_role_capabilit
      */
     public function get_risk_icon($type) {
         global $OUTPUT;
-        if (!isset($this->riskicons[$type])) {
-            $iconurl = $OUTPUT->pix_url('i/' . str_replace('risk', 'risk_', $type));
-            $text = '<img src="' . $iconurl . '" alt="' . get_string($type . 'short', 'admin') . '" />';
-            $action = new popup_action('click', $this->risksurl, 'docspopup');
-            $this->riskicons[$type] = $OUTPUT->action_link($this->risksurl, $text, $action, array('title'=>get_string($type, 'admin')));
-        }
-        return $this->riskicons[$type];
+
+        $iconurl = $OUTPUT->pix_url('i/' . str_replace('risk', 'risk_', $type));
+        $text = '<img src="' . $iconurl . '" alt="' . get_string($type . 'short', 'admin') . '" />';
+        $action = new popup_action('click', $this->risksurl, 'docspopup');
+        $riskicon = $OUTPUT->action_link($this->risksurl, $text, $action, array('title'=>get_string($type, 'admin')));
+
+        return $riskicon;
     }
 }
index 757066e..a3d1046 100644 (file)
@@ -26,7 +26,7 @@
 .path-admin-tool-capability .comparisontable tbody th span {display:block;color:#666;font-size:80%;}
 .path-admin-tool-capability .comparisontable tbody td {border:1px solid #DFDFDF;}
 
-.path-admin-tool-capability .comparisontable .inherit {color:#666;}
-.path-admin-tool-capability .comparisontable .allow {color:#006600;font-weight:bold;}
-.path-admin-tool-capability .comparisontable .prevent {color:#ad6704;font-weight:bold;}
-.path-admin-tool-capability .comparisontable .prohibit {color:#880000;font-weight:bold;}
\ No newline at end of file
+.path-admin-tool-capability .comparisontable .inherit {color:#666}
+.path-admin-tool-capability .comparisontable .allow {background-color:#006600;font-weight:bold;color:white;}
+.path-admin-tool-capability .comparisontable .prevent {background-color:#ad6704;font-weight:bold;color:white;}
+.path-admin-tool-capability .comparisontable .prohibit {background-color:#880000;font-weight:bold;color:white;}
\ No newline at end of file
index 01f87e9..b3c5c03 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-function xmldb_tool_customlang_upgrade($oldversion) {
-    global $CFG, $DB, $OUTPUT;
-
-    $dbman = $DB->get_manager();
-
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
+defined('MOODLE_INTERNAL') || die();
 
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+function xmldb_tool_customlang_upgrade($oldversion) {
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index 2a4eab3..ef219e0 100644 (file)
@@ -31,20 +31,7 @@ defined('MOODLE_INTERNAL') || die();
  * @return bool always true
  */
 function xmldb_tool_log_upgrade($oldversion) {
-    global $CFG, $DB, $OUTPUT;
-
-    $dbman = $DB->get_manager();
-
-    if ($oldversion < 2014040600) {
-        // Reset logging defaults in dev branches,
-        // in production upgrade the install.php is executed instead.
-        require_once(__DIR__ . '/install.php');
-        xmldb_tool_log_install();
-        upgrade_plugin_savepoint(true, 2014040600, 'tool', 'log');
-    }
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index 565efed..dc92035 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-function xmldb_logstore_database_upgrade($oldversion) {
-
-    if ($oldversion < 2014041700) {
-        // Clean up old config.
-        unset_config('excludelevels', 'logstore_database');
-        unset_config('excludeactions', 'logstore_database');
-
-        // Savepoint reached.
-        upgrade_plugin_savepoint(true, 2014041700, 'logstore', 'database');
-    }
+defined('MOODLE_INTERNAL') || die();
 
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+function xmldb_logstore_database_upgrade($oldversion) {
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index 9b4247b..b844b62 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-function xmldb_logstore_standard_upgrade($oldversion) {
-    global $CFG, $DB;
-
-    $dbman = $DB->get_manager();
-
-    if ($oldversion < 2014032000) {
-
-        // Define field anonymous to be added to logstore_standard_log.
-        $table = new xmldb_table('logstore_standard_log');
-        $field = new xmldb_field('anonymous', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'relateduserid');
-
-        // Conditionally launch add field anonymous.
-        if (!$dbman->field_exists($table, $field)) {
-            $dbman->add_field($table, $field);
-        }
-
-        // Standard savepoint reached.
-        upgrade_plugin_savepoint(true, 2014032000, 'logstore', 'standard');
-    }
-
-    if ($oldversion < 2014041500) {
-
-        // Define index contextid-component (not unique) to be dropped form logstore_standard_log.
-        $table = new xmldb_table('logstore_standard_log');
-        $index = new xmldb_index('contextid-component', XMLDB_INDEX_NOTUNIQUE, array('contextid', 'component'));
-
-        // Conditionally launch drop index contextid-component.
-        if ($dbman->index_exists($table, $index)) {
-            $dbman->drop_index($table, $index);
-        }
-
-        // Define index courseid (not unique) to be dropped form logstore_standard_log.
-        $table = new xmldb_table('logstore_standard_log');
-        $index = new xmldb_index('courseid', XMLDB_INDEX_NOTUNIQUE, array('courseid'));
-
-        // Conditionally launch drop index courseid.
-        if ($dbman->index_exists($table, $index)) {
-            $dbman->drop_index($table, $index);
-        }
-
-        // Define index eventname (not unique) to be dropped form logstore_standard_log.
-        $table = new xmldb_table('logstore_standard_log');
-        $index = new xmldb_index('eventname', XMLDB_INDEX_NOTUNIQUE, array('eventname'));
+defined('MOODLE_INTERNAL') || die();
 
-        // Conditionally launch drop index eventname.
-        if ($dbman->index_exists($table, $index)) {
-            $dbman->drop_index($table, $index);
-        }
-
-        // Define index crud (not unique) to be dropped form logstore_standard_log.
-        $table = new xmldb_table('logstore_standard_log');
-        $index = new xmldb_index('crud', XMLDB_INDEX_NOTUNIQUE, array('crud'));
-
-        // Conditionally launch drop index crud.
-        if ($dbman->index_exists($table, $index)) {
-            $dbman->drop_index($table, $index);
-        }
-
-        // Define index edulevel (not unique) to be dropped form logstore_standard_log.
-        $table = new xmldb_table('logstore_standard_log');
-        $index = new xmldb_index('edulevel', XMLDB_INDEX_NOTUNIQUE, array('edulevel'));
-
-        // Conditionally launch drop index edulevel.
-        if ($dbman->index_exists($table, $index)) {
-            $dbman->drop_index($table, $index);
-        }
-
-        // Define index course-time (not unique) to be added to logstore_standard_log.
-        $table = new xmldb_table('logstore_standard_log');
-        $index = new xmldb_index('course-time', XMLDB_INDEX_NOTUNIQUE, array('courseid', 'anonymous', 'timecreated'));
-
-        // Conditionally launch add index course-time.
-        if (!$dbman->index_exists($table, $index)) {
-            $dbman->add_index($table, $index);
-        }
-
-        // Define index user-module (not unique) to be added to logstore_standard_log.
-        $table = new xmldb_table('logstore_standard_log');
-        $index = new xmldb_index('user-module', XMLDB_INDEX_NOTUNIQUE, array('userid', 'contextlevel', 'contextinstanceid', 'crud', 'edulevel', 'timecreated'));
-
-        // Conditionally launch add index user-module.
-        if (!$dbman->index_exists($table, $index)) {
-            $dbman->add_index($table, $index);
-        }
-
-        // Standard savepoint reached.
-        upgrade_plugin_savepoint(true, 2014041500, 'logstore', 'standard');
-    }
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+function xmldb_logstore_standard_upgrade($oldversion) {
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index bca88a4..d421185 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * @param int $oldversion the version we are upgrading from
  * @return bool result
  */
 function xmldb_auth_cas_upgrade($oldversion) {
-
-    // Moodle v2.5.0 release upgrade line
-    // Put any upgrade step following this
-
-    // MDL-39323 New setting in 2.5, make sure it's defined.
-    if ($oldversion < 2013052100) {
-        if (get_config('start_tls', 'auth/cas') === false) {
-            set_config('start_tls', 0, 'auth/cas');
-        }
-        upgrade_plugin_savepoint(true, 2013052100, 'auth', 'cas');
-    }
-
-    if ($oldversion < 2013091700) {
-        // The value of the phpCAS language constants has changed from
-        // 'langname' to 'CAS_Languages_Langname'.
-        if ($cas_language = get_config('auth/cas', 'language')) {
-            set_config('language', 'CAS_Languages_'.ucfirst($cas_language), 'auth/cas');
-        }
-
-        upgrade_plugin_savepoint(true, 2013091700, 'auth', 'cas');
-    }
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG, $DB;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
 
     if ($oldversion < 2014111001) {
-        global $DB;
         // From now on the default LDAP objectClass setting for AD has been changed, from 'user' to '(samaccounttype=805306368)'.
         if (is_enabled_auth('cas')
                 && ($DB->get_field('config_plugins', 'value', array('name' => 'user_type', 'plugin' => 'auth/cas')) === 'ad')
index 9d3a4ad..7098223 100644 (file)
@@ -113,31 +113,7 @@ class auth_plugin_ldap extends auth_plugin_base {
         }
 
         // Hack prefix to objectclass
-        if (empty($this->config->objectclass)) {
-            // Can't send empty filter
-            $this->config->objectclass = '(objectClass=*)';
-        } else if (stripos($this->config->objectclass, 'objectClass=') === 0) {
-            // Value is 'objectClass=some-string-here', so just add ()
-            // around the value (filter _must_ have them).
-            $this->config->objectclass = '('.$this->config->objectclass.')';
-        } else if (strpos($this->config->objectclass, '(') !== 0) {
-            // Value is 'some-string-not-starting-with-left-parentheses',
-            // which is assumed to be the objectClass matching value.
-            // So build a valid filter with it.
-            $this->config->objectclass = '(objectClass='.$this->config->objectclass.')';
-        } else {
-            // There is an additional possible value
-            // '(some-string-here)', that can be used to specify any
-            // valid filter string, to select subsets of users based
-            // on any criteria. For example, we could select the users
-            // whose objectClass is 'user' and have the
-            // 'enabledMoodleUser' attribute, with something like:
-            //
-            //   (&(objectClass=user)(enabledMoodleUser=1))
-            //
-            // In this particular case we don't need to do anything,
-            // so leave $this->config->objectclass as is.
-        }
+        $this->config->objectclass = ldap_normalise_objectclass($this->config->objectclass);
     }
 
     /**
@@ -2081,7 +2057,23 @@ class auth_plugin_ldap extends auth_plugin_base {
         $entry = ldap_get_entries_moodle($ldapconn, $sr);
         $info = array_change_key_case($entry[0], CASE_LOWER);
         $maxpwdage = $info['maxpwdage'][0];
-
+        if ($sr = ldap_read($ldapconn, $user_dn, '(objectClass=*)', array('msDS-ResultantPSO'))) {
+            if ($entry = ldap_get_entries_moodle($ldapconn, $sr)) {
+                $info = array_change_key_case($entry[0], CASE_LOWER);
+                $userpso = $info['msds-resultantpso'][0];
+
+                // If a PSO exists, FGPP is being utilized.
+                // Grab the new maxpwdage from the msDS-MaximumPasswordAge attribute of the PSO.
+                if (!empty($userpso)) {
+                    $sr = ldap_read($ldapconn, $userpso, '(objectClass=*)', array('msDS-MaximumPasswordAge'));
+                    if ($entry = ldap_get_entries_moodle($ldapconn, $sr)) {
+                        $info = array_change_key_case($entry[0], CASE_LOWER);
+                        // Default value of msds-maximumpasswordage is 42 and is always set.
+                        $maxpwdage = $info['msds-maximumpasswordage'][0];
+                    }
+                }
+            }
+        }
         // ----------------------------------------------------------------
         // MSDN says that "pwdLastSet contains the number of 100 nanosecond
         // intervals since January 1, 1601 (UTC), stored in a 64 bit integer".
index 3a320e3..762815c 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * @param int $oldversion the version we are upgrading from
  * @return bool result
  */
 function xmldb_auth_ldap_upgrade($oldversion) {
-
-    // Moodle v2.5.0 release upgrade line
-    // Put any upgrade step following this
-
-    // MDL-39323 New setting in 2.5, make sure it's defined.
-    if ($oldversion < 2013052100) {
-        if (get_config('start_tls', 'auth/ldap') === false) {
-            set_config('start_tls', 0, 'auth/ldap');
-        }
-        upgrade_plugin_savepoint(true, 2013052100, 'auth', 'ldap');
-    }
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG, $DB;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
 
     if ($oldversion < 2014111001) {
-        global $DB;
         // From now on the default LDAP objectClass setting for AD has been changed, from 'user' to '(samaccounttype=805306368)'.
         if (is_enabled_auth('ldap')
                 && ($DB->get_field('config_plugins', 'value', array('name' => 'user_type', 'plugin' => 'auth/ldap')) === 'ad')
index 3039953..3c0ae55 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * @param int $oldversion the version we are upgrading from
  * @return bool result
  */
 function xmldb_auth_manual_upgrade($oldversion) {
-    global $CFG, $DB, $OUTPUT;
-
-    $dbman = $DB->get_manager();
-
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index 0090939..bfdef15 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * @param int $oldversion the version we are upgrading from
  * @return bool result
  */
 function xmldb_auth_mnet_upgrade($oldversion) {
-    global $CFG, $DB, $OUTPUT;
-
-    $dbman = $DB->get_manager();
-
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index 59adbf3..8be9cf3 100644 (file)
@@ -35,6 +35,7 @@ $wantsremoteurl = optional_param('remoteurl', false, PARAM_BOOL);
 $url = new moodle_url('/auth/mnet/jump.php', array('token'=>$token, 'idp'=>$remotewwwroot, 'wantsurl'=>$wantsurl));
 if ($wantsremoteurl !== false) $url->param('remoteurl', $wantsremoteurl);
 $PAGE->set_url($url);
+$PAGE->set_context(context_system::instance());
 
 $site = get_site();
 
index 688726d..4e8ba89 100644 (file)
@@ -138,7 +138,9 @@ if ($backup->get_stage() == backup_ui::STAGE_FINAL) {
     }
 
     // Get HTML from logger.
-    $loghtml = $logger->get_html();
+    if ($CFG->debugdisplay) {
+        $loghtml = $logger->get_html();
+    }
 
     // Hide the progress display and first backup step bar (the 'finished' step will show next).
     echo html_writer::end_div();
index 25a216c..ab97369 100644 (file)
@@ -110,7 +110,9 @@ if (!$restore->is_independent()) {
             // Do actual restore.
             $restore->execute();
             // Get HTML from logger.
-            $loghtml = $logger->get_html();
+            if ($CFG->debugdisplay) {
+                $loghtml = $logger->get_html();
+            }
             // Hide this section because we are now going to make the page show 'finished'.
             echo html_writer::end_div();
             echo html_writer::script('document.getElementById("executionprogress").style.display = "none";');
index 0b68bd7..bbc28ae 100644 (file)
@@ -217,16 +217,13 @@ Feature: Award badges
     And I follow "Course 1"
     And I press "Mark as complete: Test assignment name"
     And I log out
-    And I log in as "admin"
-    # We can't wait for cron to happen, so the admin manually triggers it.
-    And I trigger cron
-    # The admin needs to trigger cron twice to see the completion status as completed.
-    # We wait more than 1 minute because of the next cron run scheduled time.
-    And I wait "61" seconds
-    And I trigger cron
-    # Finally the admin goes back to homepage to continue the user story.
-    And I am on site homepage
-    And I log out
+    # Completion cron won't mark the whole course completed unless the
+    # individual criteria was marked completed more than a second ago. So
+    # run it twice, first to mark the criteria and second for the course.
+    And I run the scheduled task "core\task\completion_regular_task"
+    And I wait "1" seconds
+    And I run the scheduled task "core\task\completion_regular_task"
+    # The student should now see their badge.
     And I log in as "student1"
     And I follow "Profile" in the user menu
     Then I should see "Course Badge"
index 111c96f..012549e 100644 (file)
@@ -35,6 +35,6 @@ Feature: The activity results block displays student scores
     When I follow "Test assignment"
     And I click on "Edit settings" "link" in the "Administration" "block"
     And I set the following fields to these values:
-      | id_modgrade_type | None |
+      | id_grade_modgrade_type | None |
     And I press "Save and return to course"
     Then I should see "Error: the activity selected uses a grading method that is not supported by this block." in the "Activity results" "block"
index 1263382..b5e52f8 100644 (file)
@@ -39,8 +39,8 @@ Feature: The activity results block displays student scores as scales
       | Assignment name | Test assignment |
       | Description | Offline text |
       | assignsubmission_file_enabled | 0 |
-      | id_modgrade_type | Scale |
-      | id_modgrade_scale | My Scale |
+      | id_grade_modgrade_type | Scale |
+      | id_grade_modgrade_scale | My Scale |
     And I follow "Course 1"
     And I navigate to "Grades" node in "Course administration"
     And I turn editing mode on
index 7856da5..d546fda 100644 (file)
@@ -56,8 +56,8 @@ Feature: The activity results block displays student scores as scales
       | Assignment name | Test assignment |
       | Description | Offline text |
       | assignsubmission_file_enabled | 0 |
-      | id_modgrade_type | Scale |
-      | id_modgrade_scale | My Scale |
+      | id_grade_modgrade_type | Scale |
+      | id_grade_modgrade_scale | My Scale |
       | Group mode | Separate groups |
     And I follow "Course 1"
     And I navigate to "Grades" node in "Course administration"
index 149e0f6..00f31f6 100644 (file)
@@ -39,8 +39,8 @@ Feature: The activity results block displays student scores as scales
       | Assignment name | Test assignment |
       | Description | Offline text |
       | assignsubmission_file_enabled | 0 |
-      | id_modgrade_type | Scale |
-      | id_modgrade_scale | My Scale |
+      | id_grade_modgrade_type | Scale |
+      | id_grade_modgrade_scale | My Scale |
     And I follow "Course 1"
     And I navigate to "Grades" node in "Course administration"
     And I turn editing mode on
index 9134339..be5ae33 100644 (file)
@@ -56,8 +56,8 @@ Feature: The activity results block displays student scores as scales
       | Assignment name | Test assignment |
       | Description | Offline text |
       | assignsubmission_file_enabled | 0 |
-      | id_modgrade_type | Scale |
-      | id_modgrade_scale | My Scale |
+      | id_grade_modgrade_type | Scale |
+      | id_grade_modgrade_scale | My Scale |
       | Group mode | Separate groups |
     And I follow "Course 1"
     And I navigate to "Grades" node in "Course administration"
index 6edc7b5..f46bd41 100644 (file)
@@ -121,7 +121,7 @@ class block_blog_tags extends block_base {
             $type = " AND (p.publishstate = 'site' or p.publishstate='public')";
         }
 
-        $sql  = "SELECT t.id, t.tagtype, t.rawname, t.name, COUNT(DISTINCT ti.id) AS ct
+        $sql  = "SELECT t.id, t.isstandard, t.rawname, t.name, COUNT(DISTINCT ti.id) AS ct
                    FROM {tag} t, {tag_instance} ti, {post} p, {blog_association} ba
                   WHERE t.id = ti.tagid AND p.id = ti.itemid
                         $type
@@ -136,7 +136,7 @@ class block_blog_tags extends block_base {
         }
 
         $sql .= "
-               GROUP BY t.id, t.tagtype, t.name, t.rawname
+               GROUP BY t.id, t.isstandard, t.name, t.rawname
                ORDER BY ct DESC, t.name ASC";
 
         if ($tags = $DB->get_records_sql($sql, null, 0, $this->config->numberoftags)) {
@@ -165,7 +165,7 @@ class block_blog_tags extends block_base {
                     $size = 20 - ( (int)((($currenttag - 1) / $totaltags) * 20) );
                 }
 
-                $tag->class = "$tag->tagtype s$size";
+                $tag->class = ($tag->isstandard ? "standardtag " : "") . "s$size";
                 $etags[] = $tag;
 
             }
index 192ba5e..d840c38 100644 (file)
@@ -14,8 +14,8 @@ Feature: Adding blog tag block
       | fullname  | shortname |
       | Course 1  | c1        |
     And the following "tags" exist:
-      | name         | tagtype  |
-      | Neverusedtag | official |
+      | name         | isstandard  |
+      | Neverusedtag | 1           |
     And the following "course enrolments" exist:
       | user     | course | role           |
       | teacher1 | c1     | editingteacher |
index bcc82dc..3a3e7b1 100644 (file)
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  *
  * @param int $oldversion
- * @param object $block
  */
 function xmldb_block_community_upgrade($oldversion) {
-    global $CFG, $DB;
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index 070ebcc..f44773a 100644 (file)
@@ -37,6 +37,8 @@
  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Handles upgrading instances of this block.
  *
  * @param object $block
  */
 function xmldb_block_completionstatus_upgrade($oldversion, $block) {
-    global $DB;
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this.
-
-    if ($oldversion < 2012112901) {
-        // Get the instances of this block.
-        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'completionstatus', 'pagetypepattern' => 'my-index'))) {
-            // Loop through and remove them from the My Moodle page.
-            foreach ($blocks as $block) {
-                blocks_delete_instance($block);
-            }
-        }
-        // Savepoint reached.
-        upgrade_block_savepoint(true, 2012112901, 'completionstatus');
-    }
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
@@ -80,4 +58,4 @@ function xmldb_block_completionstatus_upgrade($oldversion, $block) {
     // Put any upgrade step following this.
 
     return true;
-}
\ No newline at end of file
+}
index 0c1549e..1678a1b 100644 (file)
@@ -37,6 +37,8 @@
  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Handles upgrading instances of this block.
  *
  * @param object $block
  */
 function xmldb_block_course_summary_upgrade($oldversion, $block) {
-    global $DB;
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this.
-
-    if ($oldversion < 2012112901) {
-        // Get the instances of this block.
-        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'course_summary', 'pagetypepattern' => 'my-index'))) {
-            // Loop through and remove them from the My Moodle page.
-            foreach ($blocks as $block) {
-                blocks_delete_instance($block);
-            }
-
-        }
-
-        // Savepoint reached.
-        upgrade_block_savepoint(true, 2012112901, 'course_summary');
-    }
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
@@ -84,4 +58,4 @@ function xmldb_block_course_summary_upgrade($oldversion, $block) {
     // Put any upgrade step following this.
 
     return true;
-}
\ No newline at end of file
+}
index 017e407..cfc5bc1 100644 (file)
@@ -62,9 +62,16 @@ class restore_glossary_random_block_task extends restore_block_task {
             if (!empty($config->glossary)) {
                 // Get glossary mapping and replace it in config
                 if ($glossarymap = restore_dbops::get_backup_ids_record($this->get_restoreid(), 'glossary', $config->glossary)) {
-                    $config->glossary = $glossarymap->newitemid;
+                    $mappedglossary = $DB->get_record('glossary', array('id' => $glossarymap->newitemid),
+                        'id,course,globalglossary', MUST_EXIST);
+                    $config->glossary = $mappedglossary->id;
+                    $config->courseid = $mappedglossary->course;
+                    $config->globalglossary = $mappedglossary->globalglossary;
                     $configdata = base64_encode(serialize($config));
                     $DB->set_field('block_instances', 'configdata', $configdata, array('id' => $blockid));
+                } else {
+                    // The block refers to a glossary not present in the backup file.
+                    $DB->set_field('block_instances', 'configdata', '', array('id' => $blockid));
                 }
             }
         }
index ff87abf..4b5a51a 100644 (file)
  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Upgrade code for the HTML block.
  *
  * @param int $oldversion
- * @param object $block
  */
 function xmldb_block_html_upgrade($oldversion) {
-    global $CFG, $DB;
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index 6ea9268..430bb9e 100644 (file)
@@ -37,6 +37,8 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * As of the implementation of this block and the general navigation code
  * in Moodle 2.0 the body of immediate upgrade work for this block and
  * was complex due to us wanting to remvoe the outmoded blocks that this
  * block was going to replace.
  *
- * @global moodle_database $DB
  * @param int $oldversion
  * @param object $block
  */
 function xmldb_block_navigation_upgrade($oldversion, $block) {
-    global $DB;
-
-    // Moodle v2.2.0 release upgrade line
-    // Put any upgrade step following this.
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
@@ -85,4 +65,4 @@ function xmldb_block_navigation_upgrade($oldversion, $block) {
     // Put any upgrade step following this.
 
     return true;
-}
\ No newline at end of file
+}
index 131c559..86565e8 100644 (file)
@@ -70,7 +70,8 @@ class block_navigation_renderer extends plugin_renderer_base {
 
         // Turn our navigation items into list items.
         $lis = array();
-        $number = 0;
+        // Set the number to be static for unique id's.
+        static $number = 0;
         foreach ($items as $item) {
             $number++;
             if (!$item->display && !$item->contains_active_node()) {
index 905fbfa..ac124e2 100644 (file)
@@ -22,6 +22,6 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-$string['news_items:addinstance'] = 'Add a new latest news block';
-$string['news_items:myaddinstance'] = 'Add a new latest news block to Dashboard';
-$string['pluginname'] = 'Latest news';
+$string['news_items:addinstance'] = 'Add a new latest announcements block';
+$string['news_items:myaddinstance'] = 'Add a new latest announcements block to Dashboard';
+$string['pluginname'] = 'Latest announcements';
index e848027..ecac0bd 100644 (file)
@@ -1,11 +1,11 @@
 @block @block_news_items
-Feature: Latest news block displays the course latest news
-  In order to be aware of the course news
+Feature: Latest announcements block displays the course latest news
+  In order to be aware of the course announcements
   As a user
-  I need to see the latest news in the main course page
+  I need to see the latest announcements block in the main course page
 
   @javascript
-  Scenario: Latest course news are displayed and can be configured
+  Scenario: Latest course announcements are displayed and can be configured
     Given the following "users" exist:
       | username | firstname | lastname | email |
       | teacher1 | Teacher | 1 | teacher1@example.com |
@@ -18,28 +18,28 @@ Feature: Latest news block displays the course latest news
     And I log out
     And I log in as "teacher1"
     And I follow "Course 1"
-    When I add a new topic to "News forum" forum with:
+    When I add a new topic to "Announcements" forum with:
       | Subject | Discussion One |
       | Message | Not important |
-    And I add a new topic to "News forum" forum with:
+    And I add a new topic to "Announcements" forum with:
       | Subject | Discussion Two |
       | Message | Not important |
-    And I add a new topic to "News forum" forum with:
+    And I add a new topic to "Announcements" forum with:
       | Subject | Discussion Three |
       | Message | Not important |
     And I follow "Course 1"
-    Then I should see "Discussion One" in the "Latest news" "block"
-    And I should see "Discussion Two" in the "Latest news" "block"
-    And I should see "Discussion Three" in the "Latest news" "block"
+    Then I should see "Discussion One" in the "Latest announcements" "block"
+    And I should see "Discussion Two" in the "Latest announcements" "block"
+    And I should see "Discussion Three" in the "Latest announcements" "block"
     And I follow "Edit settings"
     And I set the following fields to these values:
       | News items to show | 2 |
     And I press "Save and display"
-    And I should not see "Discussion One" in the "Latest news" "block"
-    And I should see "Discussion Two" in the "Latest news" "block"
-    And I should see "Discussion Three" in the "Latest news" "block"
+    And I should not see "Discussion One" in the "Latest announcements" "block"
+    And I should see "Discussion Two" in the "Latest announcements" "block"
+    And I should see "Discussion Three" in the "Latest announcements" "block"
     And I follow "Edit settings"
     And I set the following fields to these values:
       | News items to show | 0 |
     And I press "Save and display"
-    And "Latest news" "block" should not exist
+    And "Latest announcements" "block" should not exist
index 8d0f893..02e8be0 100644 (file)
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Upgrade code for the recent activity block.
  *
- * @global moodle_database $DB
  * @param int $oldversion
  * @param object $block
  */
 function xmldb_block_recent_activity_upgrade($oldversion, $block) {
-    global $CFG, $DB;
-
-    $dbman = $DB->get_manager(); // loads ddl manager and xmldb classes
-
-    if ($oldversion < 2014012000) {
-
-        // Define table block_recent_activity to be created.
-        $table = new xmldb_table('block_recent_activity');
-
-        // Adding fields to table block_recent_activity.
-        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
-        $table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('cmid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('action', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null);
-        $table->add_field('modname', XMLDB_TYPE_CHAR, '20', null, null, null, null);
-
-        // Adding keys to table block_recent_activity.
-        $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
-
-        // Adding indexes to table block_recent_activity.
-        $table->add_index('coursetime', XMLDB_INDEX_NOTUNIQUE, array('courseid', 'timecreated'));
-
-        // Conditionally launch create table for block_recent_activity.
-        if (!$dbman->table_exists($table)) {
-            $dbman->create_table($table);
-            // Insert dummy log record for each existing course to notify that their logs need to be migrated.
-            $DB->execute('INSERT INTO {block_recent_activity} (timecreated, userid, courseid, cmid, action) '.
-                    'SELECT ?, 0, id, 0, 3 FROM {course}',
-                    array(time()));
-        }
-
-        // Recent_activity savepoint reached.
-        upgrade_block_savepoint(true, 2014012000, 'recent_activity');
-    }
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index 057f275..66f7957 100644 (file)
@@ -37,6 +37,8 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Upgrade code for the section links block.
  *
  * @param object $block
  */
 function xmldb_block_section_links_upgrade($oldversion, $block) {
-    global $DB;
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-    if ($oldversion < 2013012200.00) {
-
-        // The section links block used to use its own crazy plugin name.
-        // Here we are converting it to the proper component name.
-        $oldplugin = 'blocks/section_links';
-        $newplugin = 'block_section_links';
-
-        // Use the proper API here... thats what we should be doing as it ensures any caches etc are cleared
-        // along the way!
-        // It may be quicker to just write an SQL statement but that would be reckless.
-        $config = get_config($oldplugin);
-        if (!empty($config)) {
-            foreach ($config as $name => $value) {
-                set_config($name, $value, $newplugin);
-                unset_config($name, $oldplugin);
-            }
-        }
-
-        // Main savepoint reached.
-        upgrade_block_savepoint(true, 2013012200.00, 'section_links');
-    }
-
-
-    // Moodle v2.5.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index e79331c..9dee1f5 100644 (file)
@@ -37,6 +37,8 @@
  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * Handles upgrading instances of this block.
  *
  * @param object $block
  */
 function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
-    global $DB;
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this.
-
-    if ($oldversion < 2012112901) {
-        // Get the instances of this block.
-        if ($blocks = $DB->get_records('block_instances', array('blockname' => 'selfcompletion', 'pagetypepattern' => 'my-index'))) {
-            // Loop through and remove them from the My Moodle page.
-            foreach ($blocks as $block) {
-                blocks_delete_instance($block);
-            }
-
-        }
-
-        // Savepoint reached.
-        upgrade_block_savepoint(true, 2012112901, 'selfcompletion');
-    }
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
@@ -84,4 +58,4 @@ function xmldb_block_selfcompletion_upgrade($oldversion, $block) {
     // Put any upgrade step following this.
 
     return true;
-}
\ No newline at end of file
+}
index b1cf6f8..bd96db6 100644 (file)
@@ -37,6 +37,8 @@
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * As of the implementation of this block and the general navigation code
  * in Moodle 2.0 the body of immediate upgrade work for this block and
  * was complex due to us wanting to remvoe the outmoded blocks that this
  * block was going to replace.
  *
- * @global moodle_database $DB
  * @param int $oldversion
  * @param object $block
  */
 function xmldb_block_settings_upgrade($oldversion, $block) {
-    global $DB;
-
-    // Moodle v2.2.0 release upgrade line
-    // Put any upgrade step following this
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
@@ -85,4 +65,4 @@ function xmldb_block_settings_upgrade($oldversion, $block) {
     // Put any upgrade step following this.
 
     return true;
-}
\ No newline at end of file
+}
index 31ced58..e483abe 100644 (file)
@@ -70,8 +70,8 @@ class block_tags extends block_base {
             $this->config->numberoftags = 80;
         }
 
-        if (empty($this->config->tagtype)) {
-            $this->config->tagtype = '';
+        if (empty($this->config->showstandard)) {
+            $this->config->showstandard = core_tag_tag::BOTH_STANDARD_AND_NOT;
         }
 
         if (empty($this->config->ctx)) {
@@ -102,7 +102,7 @@ class block_tags extends block_base {
         // Get a list of tags.
 
         $tagcloud = core_tag_collection::get_tag_cloud($this->config->tagcoll,
-                $this->config->tagtype,
+                $this->config->showstandard == core_tag_tag::STANDARD_ONLY,
                 $this->config->numberoftags,
                 'name', '', $this->page->context->id, $this->config->ctx, $this->config->rec);
         $this->content->text = $OUTPUT->render_from_template('core_tag/tagcloud', $tagcloud->export_for_template($OUTPUT));
index 89742c5..4ea8209 100644 (file)
@@ -48,10 +48,10 @@ class block_tags_edit_form extends block_edit_form {
         $mform->setDefault('config_numberoftags', 80);
 
         $defaults = array(
-            'official' => get_string('officialonly', 'block_tags'),
-            '' => get_string('anytype', 'block_tags'));
-        $mform->addElement('select', 'config_tagtype', get_string('defaultdisplay', 'block_tags'), $defaults);
-        $mform->setDefault('config_tagtype', '');
+            core_tag_tag::STANDARD_ONLY => get_string('standardonly', 'block_tags'),
+            core_tag_tag::BOTH_STANDARD_AND_NOT => get_string('anytype', 'block_tags'));
+        $mform->addElement('select', 'config_showstandard', get_string('defaultdisplay', 'block_tags'), $defaults);
+        $mform->setDefault('config_showstandard', core_tag_tag::BOTH_STANDARD_AND_NOT);
 
         $defaults = array(0 => context_system::instance()->get_context_name());
         $parentcontext = context::instance_by_id($this->block->instance->parentcontextid);
index 02dd7a1..8f1a1b7 100644 (file)
@@ -26,11 +26,11 @@ $string['anycollection'] = 'Any';
 $string['anytype'] = 'All';
 $string['configtitle'] = 'Block title';
 $string['disabledtags'] = 'Tags are disabled';
-$string['defaultdisplay'] = 'Tag type to display';
-$string['officialonly'] = 'Only official';
+$string['defaultdisplay'] = 'Display tags';
 $string['pluginname'] = 'Tags';
 $string['recursivecontext'] = 'Include child contexts';
 $string['recursivecontext_help'] = 'If unchecked, tags of items in the context specified above will be displayed excluding underlying contexts, for example, you can search on course level only without searching inside course activities';
+$string['standardonly'] = 'Only standard';
 $string['tagcollection'] = 'Tag collection';
 $string['tagcollection_help'] = 'Select tag collection to display tags from. If you choose "Any" '
         . 'the tags from all collections except for those marked with * will be displayed';
index 7a25490..36e1bc0 100644 (file)
@@ -13,8 +13,8 @@ Feature: Block tags displaying tag cloud
       | fullname  | shortname |
       | Course 1  | c1        |
     And the following "tags" exist:
-      | name         | tagtype  |
-      | Neverusedtag | official |
+      | name         | isstandard  |
+      | Neverusedtag | 1           |
     And the following "course enrolments" exist:
       | user     | course | role           |
       | teacher1 | c1     | editingteacher |
index f08b349..bd3a6c4 100644 (file)
@@ -19,7 +19,7 @@ Feature: Show hidden blocks in a docked block region when editing
     And I set the following fields to these values:
       | Visible | No |
     And I click on "Save changes" "button"
-    And I configure the "Latest news" block
+    And I configure the "Latest announcements" block
     And I set the following fields to these values:
       | Visible | No |
     And I click on "Save changes" "button"
@@ -33,13 +33,13 @@ Feature: Show hidden blocks in a docked block region when editing
     When I click on "Save changes" "button"
     # Editing is on so they should be visible
     Then I should see "Search forums"
-    And I should see "Latest news"
+    And I should see "Latest announcements"
     And I should see "Upcoming events"
     And I should see "Recent activity"
     And I turn editing mode off
     # Editing is off, so they should no longer be visible
     And I should not see "Search forums"
-    And I should not see "Latest news"
+    And I should not see "Latest announcements"
     And I should not see "Upcoming events"
     And I should not see "Recent activity"
 
index 50f0843..43ae149 100644 (file)
@@ -17,8 +17,8 @@ Feature: Block visibility
   Scenario: Hiding all blocks on the page should remove the column they're in
     Given I open the "Search forums" blocks action menu
     And I click on "Hide Search forums block" "link" in the "Search forums" "block"
-    And I open the "Latest news" blocks action menu
-    And I click on "Hide Latest news block" "link" in the "Latest news" "block"
+    And I open the "Latest announcements" blocks action menu
+    And I click on "Hide Latest announcements block" "link" in the "Latest announcements" "block"
     And I open the "Upcoming events" blocks action menu
     And I click on "Hide Upcoming events block" "link" in the "Upcoming events" "block"
     And I open the "Recent activity" blocks action menu
index 81eac30..80c3be5 100644 (file)
@@ -66,7 +66,7 @@ class core_blog_lib_testcase extends advanced_testcase {
 
         // Create default tag.
         $tag = $this->getDataGenerator()->create_tag(array('userid' => $user->id,
-            'rawname' => 'Testtagname', 'tagtype' => 'official'));
+            'rawname' => 'Testtagname', 'isstandard' => 1));
 
         // Create default post.
         $post = new stdClass();
index beb9ac3..469884d 100644 (file)
@@ -298,6 +298,11 @@ $CFG->admin = 'admin';
 // This setting will make some graphs (eg user logs) use lines instead of bars
 //      $CFG->preferlinegraphs = true;
 //
+// This setting allows you to specify a class to rewrite outgoing urls
+// enabling 'clean urls' in conjunction with an apache / nginx handler.
+// The handler must implement \core\output\url_rewriter.
+//      $CFG->urlrewriteclass = '\local_cleanurls\url_rewriter';
+//
 // Enabling this will allow custom scripts to replace existing moodle scripts.
 // For example: if $CFG->customscripts/course/view.php exists then
 // it will be used instead of $CFG->wwwroot/course/view.php
@@ -589,6 +594,10 @@ $CFG->admin = 'admin';
 // Divert all outgoing emails to this address to test and debug emailing features
 // $CFG->divertallemailsto = 'root@localhost.local'; // NOT FOR PRODUCTION SERVERS!
 //
+// Except for certain email addresses you want to let through for testing. Accepts
+// a comma separated list of regexes.
+// $CFG->divertallemailsexcept = 'tester@dev.com, fred(\+.*)?@example.com'; // NOT FOR PRODUCTION SERVERS!
+//
 // Uncomment if you want to allow empty comments when modifying install.xml files.
 // $CFG->xmldbdisablecommentchecking = true;    // NOT FOR PRODUCTION SERVERS!
 //
index 1a1d434..eb759d8 100644 (file)
@@ -743,7 +743,7 @@ M.course_dndupload = {
         var self = this;
 
         if (file.size > this.maxbytes) {
-            alert("'"+file.name+"' "+M.util.get_string('filetoolarge', 'moodle'));
+            new M.core.alert({message: M.util.get_string('namedfiletoolarge', 'moodle', {filename: file.name})});
             return;
         }
 
@@ -777,11 +777,11 @@ M.course_dndupload = {
                         } else {
                             // Error - remove the dummy element
                             resel.parent.removeChild(resel.li);
-                            alert(result.error);
+                            new M.core.alert({message: result.error});
                         }
                     }
                 } else {
-                    alert(M.util.get_string('servererror', 'moodle'));
+                    new M.core.alert({message: M.util.get_string('servererror', 'moodle')});
                 }
             }
         };
@@ -1002,11 +1002,11 @@ M.course_dndupload = {
                         } else {
                             // Error - remove the dummy element
                             resel.parent.removeChild(resel.li);
-                            alert(result.error);
+                            new M.core.alert({message: result.error});
                         }
                     }
                 } else {
-                    alert(M.util.get_string('servererror', 'moodle'));
+                    new M.core.alert({message: M.util.get_string('servererror', 'moodle')});
                 }
             }
         };
index e491718..843ea9a 100644 (file)
@@ -61,7 +61,7 @@ function dndupload_add_to_course($course, $modnames) {
             array('dndworkingtextlink', 'moodle'),
             array('dndworkingtext', 'moodle'),
             array('dndworkinglink', 'moodle'),
-            array('filetoolarge', 'moodle'),
+            array('namedfiletoolarge', 'moodle'),
             array('actionchoice', 'moodle'),
             array('servererror', 'moodle'),
             array('upload', 'moodle'),
index 1aff731..14b7493 100644 (file)
@@ -114,28 +114,7 @@ if ($mform->is_cancelled()){
             $data->availability = null;
         }
     }
-    $DB->update_record('course_sections', $data);
-    rebuild_course_cache($course->id, true);
-    if (isset($data->section)) {
-        // Usually edit form does not change relative section number but just in case.
-        $sectionnum = $data->section;
-    }
-    course_get_format($course->id)->update_section_format_options($data);
-
-    // Set section info, as this might not be present in form_data.
-    if (!isset($data->section))  {
-        $data->section = $sectionnum;
-    }
-    // Trigger an event for course section update.
-    $event = \core\event\course_section_updated::create(
-            array(
-                'objectid' => $data->id,
-                'courseid' => $course->id,
-                'context' => $context,
-                'other' => array('sectionnum' => $data->section)
-            )
-        );
-    $event->trigger();
+    course_update_section($course, $section, $data);
 
     $PAGE->navigation->clear_cache();
     redirect(course_get_url($course, $section, array('sr' => $sectionreturn)));
index d5423f7..8a4078c 100644 (file)
@@ -1030,6 +1030,76 @@ abstract class format_base {
 
         return true;
     }
+
+    /**
+     * Prepares the templateable object to display section name
+     *
+     * @param \section_info|\stdClass $section
+     * @param bool $linkifneeded
+     * @param bool $editable
+     * @param null|lang_string|string $edithint
+     * @param null|lang_string|string $editlabel
+     * @return \core\output\inplace_editable
+     */
+    public function inplace_editable_render_section_name($section, $linkifneeded = true,
+                                                         $editable = null, $edithint = null, $editlabel = null) {
+        global $USER, $CFG;
+        require_once($CFG->dirroot.'/course/lib.php');
+
+        if ($editable === null) {
+            $editable = !empty($USER->editing) && has_capability('moodle/course:update',
+                    context_course::instance($section->course));
+        }
+
+        $displayvalue = $title = get_section_name($section->course, $section);
+        if ($linkifneeded) {
+            // Display link under the section name if the course format setting is to display one section per page.
+            $url = course_get_url($section->course, $section->section, array('navigation' => true));
+            if ($url) {
+                $displayvalue = html_writer::link($url, $title);
+            }
+            $itemtype = 'sectionname';
+        } else {
+            // If $linkifneeded==false, we never display the link (this is used when rendering the section header).
+            // Itemtype 'sectionnamenl' (nl=no link) will tell the callback that link should not be rendered -
+            // there is no other way callback can know where we display the section name.
+            $itemtype = 'sectionnamenl';
+        }
+        if (empty($edithint)) {
+            $edithint = new lang_string('editsectionname');
+        }
+        if (empty($editlabel)) {
+            $editlabel = new lang_string('newsectionname', '', $title);
+        }
+
+        return new \core\output\inplace_editable('format_' . $this->format, $itemtype, $section->id, $editable,
+            $displayvalue, $section->name, $edithint, $editlabel);
+    }
+
+    /**
+     * Updates the value in the database and modifies this object respectively.
+     *
+     * ALWAYS check user permissions before performing an update! Throw exceptions if permissions are not sufficient
+     * or value is not legit.
+     *
+     * @param stdClass $section
+     * @param string $itemtype
+     * @param mixed $newvalue
+     * @return \core\output\inplace_editable
+     */
+    public function inplace_editable_update_section_name($section, $itemtype, $newvalue) {
+        if ($itemtype === 'sectionname' || $itemtype === 'sectionnamenl') {
+            require_login($section->course, false, null, true, true);
+            $context = context_course::instance($section->course);
+            require_capability('moodle/course:update', $context);
+
+            $newtitle = clean_param($newvalue, PARAM_TEXT);
+            if (strval($section->name) !== strval($newtitle)) {
+                course_update_section($section->course, $section, array('name' => $newtitle));
+            }
+            return $this->inplace_editable_render_section_name($section, ($itemtype === 'sectionname'), true);
+        }
+    }
 }
 
 /**
index 77a34a5..c88d14d 100644 (file)
@@ -71,7 +71,7 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
     abstract protected function page_title();
 
     /**
-     * Generate the section title
+     * Generate the section title, wraps it in a link to the section page if page is to be displayed on a separate page
      *
      * @param stdClass $section The course_section entry from DB
      * @param stdClass $course The course entry from DB
@@ -86,6 +86,17 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
         return $title;
     }
 
+    /**
+     * Generate the section title to be displayed on the section page, without a link
+     *
+     * @param stdClass $section The course_section entry from DB
+     * @param stdClass $course The course entry from DB
+     * @return string HTML to output.
+     */
+    public function section_title_without_link($section, $course) {
+        return get_section_name($course, $section);
+    }
+
     /**
      * Generate the edit control action menu
      *
@@ -193,7 +204,7 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
             'aria-label'=> get_section_name($course, $section)));
 
         // Create a span that contains the section title to be used to create the keyboard section move menu.
-        $o .= html_writer::tag('span', $this->section_title($section, $course), array('class' => 'hidden sectionname'));
+        $o .= html_writer::tag('span', get_section_name($course, $section), array('class' => 'hidden sectionname'));
 
         $leftcontent = $this->section_left_content($section, $course, $onsectionpage);
         $o.= html_writer::tag('div', $leftcontent, array('class' => 'left side'));
@@ -788,7 +799,7 @@ abstract class format_section_renderer_base extends plugin_renderer_base {
         if (!$thissection->visible) {
             $classes .= ' dimmed_text';
         }
-        $sectionname = html_writer::tag('span', get_section_name($course, $displaysection));
+        $sectionname = html_writer::tag('span', $this->section_title_without_link($thissection, $course));
         $sectiontitle .= $this->output->heading($sectionname, 3, $classes);
 
         $sectiontitle .= html_writer::end_tag('div');
index 9b2887b..b6da590 100644 (file)
@@ -31,4 +31,4 @@ $string['orphaned'] = 'Orphaned';
 $string['orphanedwarning'] = 'These activities are unreachable by users!';
 $string['pluginname'] = 'Single activity format';
 $string['sectionname'] = '';
-$string['warningchangeformat'] = 'When changing the existing course format to "Single activity" make sure that you removed all extra activities from the course including the "News forum". Note that sections structure may be modified.';
+$string['warningchangeformat'] = 'When changing the existing course format to "Single activity" make sure that you removed all extra activities from the course including "Announcements". Note that sections structure may be modified.';
index 65cd546..813e2c6 100644 (file)
@@ -230,8 +230,16 @@ class format_singleactivity extends format_base {
         }
 
         // Make sure the current activity is in the 0-section.
+        $changed = false;
         if ($activity && $activity->sectionnum != 0) {
             moveto_module($activity, $modinfo->get_section_info(0));
+            $changed = true;
+        }
+        if ($activity && !$activity->visible) {
+            set_coursemodule_visible($activity->id, 1);
+            $changed = true;
+        }
+        if ($changed) {
             // Cache was reset so get modinfo again.
             $modinfo = get_fast_modinfo($this->courseid);
         }
index 6518d5b..69856d4 100644 (file)
@@ -25,7 +25,9 @@
 
 $string['currentsection'] = 'This topic';
 $string['editsection'] = 'Edit topic';
+$string['editsectionname'] = 'Edit topic name';
 $string['deletesection'] = 'Delete topic';
+$string['newsectionname'] = 'New name for topic {$a}';
 $string['sectionname'] = 'Topic';
 $string['pluginname'] = 'Topics format';
 $string['section0name'] = 'General';
index 228b122..da48e81 100644 (file)
@@ -382,4 +382,45 @@ class format_topics extends format_base {
     public function can_delete_section($section) {
         return true;
     }
+
+    /**
+     * Prepares the templateable object to display section name
+     *
+     * @param \section_info|\stdClass $section
+     * @param bool $linkifneeded
+     * @param bool $editable
+     * @param null|lang_string|string $edithint
+     * @param null|lang_string|string $editlabel
+     * @return \core\output\inplace_editable
+     */
+    public function inplace_editable_render_section_name($section, $linkifneeded = true,
+                                                         $editable = null, $edithint = null, $editlabel = null) {
+        if (empty($edithint)) {
+            $edithint = new lang_string('editsectionname', 'format_topics');
+        }
+        if (empty($editlabel)) {
+            $title = get_section_name($section->course, $section);
+            $editlabel = new lang_string('newsectionname', 'format_topics', $title);
+        }
+        return parent::inplace_editable_render_section_name($section, $linkifneeded, $editable, $edithint, $editlabel);
+    }
+}
+
+/**
+ * Implements callback inplace_editable() allowing to edit values in-place
+ *
+ * @param string $itemtype
+ * @param int $itemid
+ * @param mixed $newvalue
+ * @return \core\output\inplace_editable
+ */
+function format_topics_inplace_editable($itemtype, $itemid, $newvalue) {
+    global $DB, $CFG;
+    require_once($CFG->dirroot . '/course/lib.php');
+    if ($itemtype === 'sectionname' || $itemtype === 'sectionnamenl') {
+        $section = $DB->get_record_sql(
+            'SELECT s.* FROM {course_sections} s JOIN {course} c ON s.course = c.id WHERE s.id = ? AND c.format = ?',
+            array($itemid, 'topics'), MUST_EXIST);
+        return course_get_format($section->course)->inplace_editable_update_section_name($section, $itemtype, $newvalue);
+    }
 }
index c23bd0c..9ed95bd 100644 (file)
@@ -73,6 +73,28 @@ class format_topics_renderer extends format_section_renderer_base {
         return get_string('topicoutline');
     }
 
+    /**
+     * Generate the section title, wraps it in a link to the section page if page is to be displayed on a separate page
+     *
+     * @param stdClass $section The course_section entry from DB
+     * @param stdClass $course The course entry from DB
+     * @return string HTML to output.
+     */
+    public function section_title($section, $course) {
+        return $this->render(course_get_format($course)->inplace_editable_render_section_name($section));
+    }
+
+    /**
+     * Generate the section title to be displayed on the section page, without a link
+     *
+     * @param stdClass $section The course_section entry from DB
+     * @param stdClass $course The course entry from DB
+     * @return string HTML to output.
+     */
+    public function section_title_without_link($section, $course) {
+        return $this->render(course_get_format($course)->inplace_editable_render_section_name($section, false));
+    }
+
     /**
      * Generate the edit control items of a section
      *
index 150c5e3..1e6a7dd 100644 (file)
@@ -56,6 +56,18 @@ Feature: Sections can be edited and deleted in topics format
     Then I should see "This is the second topic" in the "li#section-2" "css_element"
     And I should not see "Topic 2" in the "li#section-2" "css_element"
 
+  @javascript
+  Scenario: Inline edit section name in topics format
+    When I click on "Edit topic name" "link" in the "li#section-1" "css_element"
+    And I set the field "New name for topic Topic 1" to "Midterm evaluation"
+    And I press key "13" in the field "New name for topic Topic 1"
+    Then I should not see "Topic 1" in the "#region-main" "css_element"
+    And "New name for topic" "field" should not exist
+    And I should see "Midterm evaluation" in the "li#section-1" "css_element"
+    And I follow "Course 1"
+    And I should not see "Topic 1" in the "#region-main" "css_element"
+    And I should see "Midterm evaluation" in the "li#section-1" "css_element"
+
   Scenario: Deleting the last section in topics format
     When I delete section "5"
     Then I should see "Are you absolutely sure you want to completely delete \"Topic 5\" and all the activities it contains?"
index 3253e45..45e8c00 100644 (file)
@@ -146,4 +146,69 @@ class format_topics_testcase extends advanced_testcase {
             }
         }
     }
+
+    /**
+     * Test web service updating section name
+     */
+    public function test_update_inplace_editable() {
+        global $CFG, $DB, $PAGE;
+        require_once($CFG->dirroot . '/lib/external/externallib.php');
+
+        $this->resetAfterTest();
+        $user = $this->getDataGenerator()->create_user();
+        $this->setUser($user);
+        $course = $this->getDataGenerator()->create_course(array('numsections' => 5, 'format' => 'topics'),
+            array('createsections' => true));
+        $section = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
+
+        // Call webservice without necessary permissions.
+        try {
+            core_external::update_inplace_editable('format_topics', 'sectionname', $section->id, 'New section name');
+            $this->fail('Exception expected');
+        } catch (moodle_exception $e) {
+            $this->assertEquals('Course or activity not accessible. (Not enrolled)',
+                    $e->getMessage());
+        }
+
+        // Change to teacher and make sure that section name can be updated using web service update_inplace_editable().
+        $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
+        $this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id);
+
+        $res = core_external::update_inplace_editable('format_topics', 'sectionname', $section->id, 'New section name');
+        $res = external_api::clean_returnvalue(core_external::update_inplace_editable_returns(), $res);
+        $this->assertEquals('New section name', $res['value']);
+        $this->assertEquals('New section name', $DB->get_field('course_sections', 'name', array('id' => $section->id)));
+    }
+
+    /**
+     * Test callback updating section name
+     */
+    public function test_inplace_editable() {
+        global $DB, $PAGE;
+
+        $this->resetAfterTest();
+        $user = $this->getDataGenerator()->create_user();
+        $course = $this->getDataGenerator()->create_course(array('numsections' => 5, 'format' => 'topics'),
+            array('createsections' => true));
+        $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
+        $this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id);
+        $this->setUser($user);
+
+        $section = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
+
+        // Call callback format_topics_inplace_editable() directly.
+        $tmpl = component_callback('format_topics', 'inplace_editable', array('sectionname', $section->id, 'Rename me again'));
+        $this->assertInstanceOf('core\output\inplace_editable', $tmpl);
+        $res = $tmpl->export_for_template($PAGE->get_renderer('core'));
+        $this->assertEquals('Rename me again', $res['value']);
+        $this->assertEquals('Rename me again', $DB->get_field('course_sections', 'name', array('id' => $section->id)));
+
+        // Try updating using callback from mismatching course format.
+        try {
+            $tmpl = component_callback('format_weeks', 'inplace_editable', array('sectionname', $section->id, 'New name'));
+            $this->fail('Exception expected');
+        } catch (moodle_exception $e) {
+            $this->assertEquals(1, preg_match('/^Can not find data record in database/', $e->getMessage()));
+        }
+    }
 }
index fce6e1c..8d82f27 100644 (file)
@@ -2,6 +2,10 @@ This files describes API changes for course formats
 
 Overview of this plugin type at http://docs.moodle.org/dev/Course_formats
 
+=== 3.1 ===
+* Course format may use the inplace_editable template to allow quick editing of section names, see
+  https://docs.moodle.org/dev/Inplace_editable and MDL-51802 for example implementation.
+
 === 3.0 ===
 * Course formats should now use section_edit_control_items and use the returned array of controls items and their attributes to create a
   renderable menu or array of links.  Plugin calls to section_edit_controls will now include the section edit control in the returned array.
index 905e71a..61626e0 100644 (file)
@@ -25,7 +25,9 @@
 
 $string['currentsection'] = 'This week';
 $string['editsection'] = 'Edit week';
+$string['editsectionname'] = 'Edit week name';
 $string['deletesection'] = 'Delete week';
+$string['newsectionname'] = 'New name for week {$a}';
 $string['sectionname'] = 'Week';
 $string['pluginname'] = 'Weekly format';
 $string['section0name'] = 'General';
index 7bcf1f4..dcb9658 100644 (file)
@@ -432,4 +432,45 @@ class format_weeks extends format_base {
     public function can_delete_section($section) {
         return true;
     }
+
+    /**
+     * Prepares the templateable object to display section name
+     *
+     * @param \section_info|\stdClass $section
+     * @param bool $linkifneeded
+     * @param bool $editable
+     * @param null|lang_string|string $edithint
+     * @param null|lang_string|string $editlabel
+     * @return \core\output\inplace_editable
+     */
+    public function inplace_editable_render_section_name($section, $linkifneeded = true,
+                                                         $editable = null, $edithint = null, $editlabel = null) {
+        if (empty($edithint)) {
+            $edithint = new lang_string('editsectionname', 'format_weeks');
+        }
+        if (empty($editlabel)) {
+            $title = get_section_name($section->course, $section);
+            $editlabel = new lang_string('newsectionname', 'format_weeks', $title);
+        }
+        return parent::inplace_editable_render_section_name($section, $linkifneeded, $editable, $edithint, $editlabel);
+    }
+}
+
+/**
+ * Implements callback inplace_editable() allowing to edit values in-place
+ *
+ * @param string $itemtype
+ * @param int $itemid
+ * @param mixed $newvalue
+ * @return \core\output\inplace_editable
+ */
+function format_weeks_inplace_editable($itemtype, $itemid, $newvalue) {
+    global $DB, $CFG;
+    require_once($CFG->dirroot . '/course/lib.php');
+    if ($itemtype === 'sectionname' || $itemtype === 'sectionnamenl') {
+        $section = $DB->get_record_sql(
+            'SELECT s.* FROM {course_sections} s JOIN {course} c ON s.course = c.id WHERE s.id = ? AND c.format = ?',
+            array($itemid, 'weeks'), MUST_EXIST);
+        return course_get_format($section->course)->inplace_editable_update_section_name($section, $itemtype, $newvalue);
+    }
 }
index 33590fd..af45ae3 100644 (file)
@@ -59,4 +59,26 @@ class format_weeks_renderer extends format_section_renderer_base {
     protected function page_title() {
         return get_string('weeklyoutline');
     }
+
+    /**
+     * Generate the section title, wraps it in a link to the section page if page is to be displayed on a separate page
+     *
+     * @param stdClass $section The course_section entry from DB
+     * @param stdClass $course The course entry from DB
+     * @return string HTML to output.
+     */
+    public function section_title($section, $course) {
+        return $this->render(course_get_format($course)->inplace_editable_render_section_name($section));
+    }
+
+    /**
+     * Generate the section title to be displayed on the section page, without a link
+     *
+     * @param stdClass $section The course_section entry from DB
+     * @param stdClass $course The course entry from DB
+     * @return string HTML to output.
+     */
+    public function section_title_without_link($section, $course) {
+        return $this->render(course_get_format($course)->inplace_editable_render_section_name($section, false));
+    }
 }
index 0e296c7..355059a 100644 (file)
@@ -57,6 +57,18 @@ Feature: Sections can be edited and deleted in weeks format
     Then I should see "This is the second week" in the "li#section-2" "css_element"
     And I should not see "8 May - 14 May" in the "li#section-2" "css_element"
 
+  @javascript
+  Scenario: Inline edit section name in weeks format
+    When I click on "Edit week name" "link" in the "li#section-1" "css_element"
+    And I set the field "New name for week 1 May - 7 May" to "Midterm evaluation"
+    And I press key "13" in the field "New name for week 1 May - 7 May"
+    Then I should not see "1 May - 7 May" in the "#region-main" "css_element"
+    And "New name for week" "field" should not exist
+    And I should see "Midterm evaluation" in the "li#section-1" "css_element"
+    And I follow "Course 1"
+    And I should not see "1 May - 7 May" in the "#region-main" "css_element"
+    And I should see "Midterm evaluation" in the "li#section-1" "css_element"
+
   Scenario: Deleting the last section in weeks format
     Given I should see "29 May - 4 June" in the "li#section-5" "css_element"
     When I delete section "5"
index ad014fc..a22ce02 100644 (file)
@@ -152,4 +152,69 @@ class format_weeks_testcase extends advanced_testcase {
             }
         }
     }
+
+    /**
+     * Test web service updating section name
+     */
+    public function test_update_inplace_editable() {
+        global $CFG, $DB, $PAGE;
+        require_once($CFG->dirroot . '/lib/external/externallib.php');
+
+        $this->resetAfterTest();
+        $user = $this->getDataGenerator()->create_user();
+        $this->setUser($user);
+        $course = $this->getDataGenerator()->create_course(array('numsections' => 5, 'format' => 'weeks'),
+            array('createsections' => true));
+        $section = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
+
+        // Call webservice without necessary permissions.
+        try {
+            core_external::update_inplace_editable('format_weeks', 'sectionname', $section->id, 'New section name');
+            $this->fail('Exception expected');
+        } catch (moodle_exception $e) {
+            $this->assertEquals('Course or activity not accessible. (Not enrolled)',
+                    $e->getMessage());
+        }
+
+        // Change to teacher and make sure that section name can be updated using web service update_inplace_editable().
+        $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
+        $this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id);
+
+        $res = core_external::update_inplace_editable('format_weeks', 'sectionname', $section->id, 'New section name');
+        $res = external_api::clean_returnvalue(core_external::update_inplace_editable_returns(), $res);
+        $this->assertEquals('New section name', $res['value']);
+        $this->assertEquals('New section name', $DB->get_field('course_sections', 'name', array('id' => $section->id)));
+    }
+
+    /**
+     * Test callback updating section name
+     */
+    public function test_inplace_editable() {
+        global $CFG, $DB, $PAGE;
+
+        $this->resetAfterTest();
+        $user = $this->getDataGenerator()->create_user();
+        $course = $this->getDataGenerator()->create_course(array('numsections' => 5, 'format' => 'weeks'),
+            array('createsections' => true));
+        $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
+        $this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id);
+        $this->setUser($user);
+
+        $section = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
+
+        // Call callback format_weeks_inplace_editable() directly.
+        $tmpl = component_callback('format_weeks', 'inplace_editable', array('sectionname', $section->id, 'Rename me again'));
+        $this->assertInstanceOf('core\output\inplace_editable', $tmpl);
+        $res = $tmpl->export_for_template($PAGE->get_renderer('core'));
+        $this->assertEquals('Rename me again', $res['value']);
+        $this->assertEquals('Rename me again', $DB->get_field('course_sections', 'name', array('id' => $section->id)));
+
+        // Try updating using callback from mismatching course format.
+        try {
+            $tmpl = component_callback('format_topics', 'inplace_editable', array('sectionname', $section->id, 'New name'));
+            $this->fail('Exception expected');
+        } catch (moodle_exception $e) {
+            $this->assertEquals(1, preg_match('/^Can not find data record in database/', $e->getMessage()));
+        }
+    }
 }
index 0c2acd3..4cb1e52 100644 (file)
@@ -1198,37 +1198,10 @@ function set_section_visible($courseid, $sectionnumber, $visibility) {
 
     $resourcestotoggle = array();
     if ($section = $DB->get_record("course_sections", array("course"=>$courseid, "section"=>$sectionnumber))) {
-        $DB->set_field("course_sections", "visible", "$visibility", array("id"=>$section->id));
-
-        $event = \core\event\course_section_updated::create(array(
-            'context' => context_course::instance($courseid),
-            'objectid' => $section->id,
-            'other' => array(
-                'sectionnum' => $sectionnumber
-            )
-        ));
-        $event->add_record_snapshot('course_sections', $section);
-        $event->trigger();
-
-        if (!empty($section->sequence)) {
-            $modules = explode(",", $section->sequence);
-            foreach ($modules as $moduleid) {
-                if ($cm = get_coursemodule_from_id(null, $moduleid, $courseid)) {
-                    if ($visibility) {
-                        // As we unhide the section, we use the previously saved visibility stored in visibleold.
-                        set_coursemodule_visible($moduleid, $cm->visibleold);
-                    } else {
-                        // We hide the section, so we hide the module but we store the original state in visibleold.
-                        set_coursemodule_visible($moduleid, 0);
-                        $DB->set_field('course_modules', 'visibleold', $cm->visible, array('id' => $moduleid));
-                    }
-                    \core\event\course_module_updated::create_from_cm($cm)->trigger();
-                }
-            }
-        }
-        rebuild_course_cache($courseid, true);
+        course_update_section($courseid, $section, array('visible' => $visibility));
 
         // Determine which modules are visible for AJAX update
+        $modules = !empty($section->sequence) ? explode(',', $section->sequence) : array();
         if (!empty($modules)) {
             list($insql, $params) = $DB->get_in_or_equal($modules);
             $select = 'id ' . $insql . ' AND visible = ?';
@@ -1877,6 +1850,70 @@ function course_delete_section($course, $section, $forcedeleteifnotempty = true)
     return $result;
 }
 
+/**
+ * Updates the course section
+ *
+ * This function does not check permissions or clean values - this has to be done prior to calling it.
+ *
+ * @param int|stdClass $course
+ * @param stdClass $section record from course_sections table - it will be updated with the new values
+ * @param array|stdClass $data
+ */
+function course_update_section($course, $section, $data) {
+    global $DB;
+
+    $courseid = (is_object($course)) ? $course->id : (int)$course;
+
+    // Some fields can not be updated using this method.
+    $data = array_diff_key((array)$data, array('id', 'course', 'section', 'sequence'));
+    $changevisibility = (array_key_exists('visible', $data) && (bool)$data['visible'] != (bool)$section->visible);
+    if (array_key_exists('name', $data) && \core_text::strlen($data['name']) > 255) {
+        throw new moodle_exception('maximumchars', 'moodle', '', 255);
+    }
+
+    // Update record in the DB and course format options.
+    $data['id'] = $section->id;
+    $DB->update_record('course_sections', $data);
+    rebuild_course_cache($courseid, true);
+    course_get_format($courseid)->update_section_format_options($data);
+
+    // Update fields of the $section object.
+    foreach ($data as $key => $value) {
+        if (property_exists($section, $key)) {
+            $section->$key = $value;
+        }
+    }
+
+    // Trigger an event for course section update.
+    $event = \core\event\course_section_updated::create(
+        array(
+            'objectid' => $section->id,
+            'courseid' => $courseid,
+            'context' => context_course::instance($courseid),
+            'other' => array('sectionnum' => $section->section)
+        )
+    );
+    $event->trigger();
+
+    // If section visibility was changed, hide the modules in this section too.
+    if ($changevisibility && !empty($section->sequence)) {
+        $modules = explode(',', $section->sequence);
+        foreach ($modules as $moduleid) {
+            if ($cm = get_coursemodule_from_id(null, $moduleid, $courseid)) {
+                if ($data['visible']) {
+                    // As we unhide the section, we use the previously saved visibility stored in visibleold.
+                    set_coursemodule_visible($moduleid, $cm->visibleold);
+                } else {
+                    // We hide the section, so we hide the module but we store the original state in visibleold.
+                    set_coursemodule_visible($moduleid, 0);
+                    $DB->set_field('course_modules', 'visibleold', $cm->visible, array('id' => $moduleid));
+                }
+                \core\event\course_module_updated::create_from_cm($cm)->trigger();
+            }
+        }
+    }
+}
+
 /**
  * Checks if the current user can delete a section (if course format allows it and user has proper permissions).
  *
index 89588dc..b878ca1 100644 (file)
@@ -453,6 +453,11 @@ function can_update_moduleinfo($cm) {
 function update_moduleinfo($cm, $moduleinfo, $course, $mform = null) {
     global $DB, $CFG;
 
+    $data = new stdClass();
+    if ($mform) {
+        $data = $mform->get_data();
+    }
+
     // Attempt to include module library before we make any changes to DB.
     include_modulelib($moduleinfo->modulename);
 
@@ -523,9 +528,44 @@ function update_moduleinfo($cm, $moduleinfo, $course, $mform = null) {
         $moduleinfo->introformat = $moduleinfo->introeditor['format'];
         unset($moduleinfo->introeditor);
     }
+    // Get the a copy of the grade_item before it is modified incase we need to scale the grades.
+    $oldgradeitem = null;
+    $newgradeitem = null;
+    if (!empty($data->grade_rescalegrades) && $data->grade_rescalegrades == 'yes') {
+        // Fetch the grade item before it is updated.
+        $oldgradeitem = grade_item::fetch(array('itemtype' => 'mod',
+                                                'itemmodule' => $moduleinfo->modulename,
+                                                'iteminstance' => $moduleinfo->instance,
+                                                'itemnumber' => 0,
+                                                'courseid' => $moduleinfo->course));
+    }
+
     $updateinstancefunction = $moduleinfo->modulename."_update_instance";
     if (!$updateinstancefunction($moduleinfo, $mform)) {
-        print_error('cannotupdatemod', '', course_get_url($course, $cw->section), $moduleinfo->modulename);
+        print_error('cannotupdatemod', '', course_get_url($course, $cm->section), $moduleinfo->modulename);
+    }
+
+    // This needs to happen AFTER the grademin/grademax have already been updated.
+    if (!empty($data->grade_rescalegrades) && $data->grade_rescalegrades == 'yes') {
+        // Get the grade_item after the update call the activity to scale the grades.
+        $newgradeitem = grade_item::fetch(array('itemtype' => 'mod',
+                                                'itemmodule' => $moduleinfo->modulename,
+                                                'iteminstance' => $moduleinfo->instance,
+                                                'itemnumber' => 0,
+                                                'courseid' => $moduleinfo->course));
+        if ($newgradeitem && $oldgradeitem->gradetype == GRADE_TYPE_VALUE && $newgradeitem->gradetype == GRADE_TYPE_VALUE) {
+            $params = array(
+                $course,
+                $cm,
+                $oldgradeitem->grademin,
+                $oldgradeitem->grademax,
+                $newgradeitem->grademin,
+                $newgradeitem->grademax
+            );
+            if (!component_callback('mod_' . $moduleinfo->modulename, 'rescale_activity_grades', $params)) {
+                print_error('cannotreprocessgrades', '', course_get_url($course, $cm->section), $moduleinfo->modulename);
+            }
+        }
     }
 
     // Make sure visibility is set correctly (in particular in calendar).
index 690dda8..1f493d0 100644 (file)
@@ -109,9 +109,9 @@ abstract class moodleform_mod extends moodleform {
         $this->_features->defaultcompletion = plugin_supports('mod', $this->_modname, FEATURE_MODEDIT_DEFAULT_COMPLETION, true);
         $this->_features->rating            = plugin_supports('mod', $this->_modname, FEATURE_RATE, false);
         $this->_features->showdescription   = plugin_supports('mod', $this->_modname, FEATURE_SHOW_DESCRIPTION, false);
-
         $this->_features->gradecat          = ($this->_features->outcomes or $this->_features->hasgrades);
         $this->_features->advancedgrading   = plugin_supports('mod', $this->_modname, FEATURE_ADVANCED_GRADING, false);
+        $this->_features->canrescale = (component_callback_exists('mod_' . $this->_modname, 'rescale_activity_grades') !== false);
     }
 
     /**
@@ -405,7 +405,9 @@ abstract class moodleform_mod extends moodleform {
 
             $permission=CAP_ALLOW;
             $rolenamestring = null;
+            $isupdate = false;
             if (!empty($this->_cm)) {
+                $isupdate = true;
                 $context = context_module::instance($this->_cm->id);
 
                 $rolenames = get_role_names_with_caps_in_context($context, array('moodle/rating:rate', 'mod/'.$this->_cm->modname.':rate'));
@@ -420,7 +422,25 @@ abstract class moodleform_mod extends moodleform {
             $mform->setDefault('assessed', 0);
             $mform->addHelpButton('assessed', 'aggregatetype', 'rating');
 
-            $mform->addElement('modgrade', 'scale', get_string('scale'), false);
+            $gradeoptions = array('isupdate' => $isupdate,
+                                  'currentgrade' => false,
+                                  'hasgrades' => false,
+                                  'canrescale' => $this->_features->canrescale,
+                                  'useratings' => $this->_features->rating);
+            if ($isupdate) {
+                $gradeitem = grade_item::fetch(array('itemtype' => 'mod',
+                                                     'itemmodule' => $this->_cm->modname,
+                                                     'iteminstance' => $this->_cm->instance,
+                                                     'itemnumber' => 0,
+                                                     'courseid' => $COURSE->id));
+                if ($gradeitem) {
+                    $gradeoptions['currentgrade'] = $gradeitem->grademax;
+                    $gradeoptions['currentgradetype'] = $gradeitem->gradetype;
+                    $gradeoptions['currentscaleid'] = $gradeitem->scaleid;
+                    $gradeoptions['hasgrades'] = $gradeitem->has_grades();
+                }
+            }
+            $mform->addElement('modgrade', 'scale', get_string('scale'), $gradeoptions);
             $mform->disabledIf('scale', 'assessed', 'eq', 0);
             $mform->addHelpButton('scale', 'modgrade', 'grades');
             $mform->setDefault('scale', $CFG->gradepointdefault);
@@ -641,6 +661,12 @@ abstract class moodleform_mod extends moodleform {
     public function standard_grading_coursemodule_elements() {
         global $COURSE, $CFG;
         $mform =& $this->_form;
+        $isupdate = !empty($this->_cm);
+        $gradeoptions = array('isupdate' => $isupdate,
+                              'currentgrade' => false,
+                              'hasgrades' => false,
+                              'canrescale' => $this->_features->canrescale,
+                              'useratings' => $this->_features->rating);
 
         if ($this->_features->hasgrades) {
 
@@ -650,7 +676,21 @@ abstract class moodleform_mod extends moodleform {
 
             //if supports grades and grades arent being handled via ratings
             if (!$this->_features->rating) {
-                $mform->addElement('modgrade', 'grade', get_string('grade'));
+
+                if ($isupdate) {
+                    $gradeitem = grade_item::fetch(array('itemtype' => 'mod',
+                                                         'itemmodule' => $this->_cm->modname,
+                                                         'iteminstance' => $this->_cm->instance,
+                                                         'itemnumber' => 0,
+                                                         'courseid' => $COURSE->id));
+                    if ($gradeitem) {
+                        $gradeoptions['currentgrade'] = $gradeitem->grademax;
+                        $gradeoptions['currentgradetype'] = $gradeitem->gradetype;
+                        $gradeoptions['currentscaleid'] = $gradeitem->scaleid;
+                        $gradeoptions['hasgrades'] = $gradeitem->has_grades();
+                    }
+                }
+                $mform->addElement('modgrade', 'grade', get_string('grade'), $gradeoptions);
                 $mform->addHelpButton('grade', 'modgrade', 'grades');
                 $mform->setDefault('grade', $CFG->gradepointdefault);
             }
index e0ba5c1..344a208 100644 (file)
@@ -139,6 +139,7 @@ class behat_course extends behat_base {
 
         return array(
             new Given('I add a "' . $this->escape($activity) . '" to section "' . $this->escape($section) . '"'),
+            new Given('I wait to be redirected'),
             new Given('I set the following fields to these values:', $data),
             new Given('I press "' . get_string('savechangesandreturntocourse') . '"')
         );
index e4bacb8..42ea501 100644 (file)
@@ -19,14 +19,14 @@ Feature: Managers can create courses
     And I log out
     When I log in as "teacher1"
     And I follow "Course 1"
-    Then "Latest news" "block" should exist
-    And I follow "News forum"
+    Then "Latest announcements" "block" should exist
+    And I follow "Announcements"
     And "Add a new topic" "button" should exist
     And "Forced subscription" "link" should not exist
     And I log out
     And I log in as "student1"
     And I follow "Course 1"
-    And I follow "News forum"
+    And I follow "Announcements"
     And "Add a new topic" "button" should not exist
     And I should see "Forced subscription" in the "Administration" "block"
 
index f76f93a..b330e80 100644 (file)
@@ -15,8 +15,8 @@ Feature: Tagging courses
       | Course 1  | c1        |
       | Course 2  | c2        |
     And the following "tags" exist:
-      | name         | tagtype  |
-      | Neverusedtag | official |
+      | name         | isstandard  |
+      | Neverusedtag | 1           |
     And the following "course enrolments" exist:
       | user     | course | role           |
       | teacher1 | c1     | editingteacher |
index d1eb164..a2d2c53 100644 (file)
  */
 
 defined('MOODLE_INTERNAL') || die();
-function xmldb_enrol_database_upgrade($oldversion) {
-    global $CFG, $DB;
-
-    $dbman = $DB->get_manager();
-
-
-    // Moodle v2.3.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
 
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+function xmldb_enrol_database_upgrade($oldversion) {
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index ebe5dd7..f16aa4d 100644 (file)
 defined('MOODLE_INTERNAL') || die();
 
 function xmldb_enrol_flatfile_upgrade($oldversion) {
-    global $CFG, $DB;
-
-    $dbman = $DB->get_manager();
-
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index 8ae2004..e1111f7 100644 (file)
  * This file keeps track of upgrades to the guest enrolment plugin.
  *
  * @package    enrol_guest
- * @copyright  2011 Petr Skoda {@link http://skodak.org
+ * @copyright  2011 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 defined('MOODLE_INTERNAL') || die();
 
 function xmldb_enrol_guest_upgrade($oldversion) {
-    global $CFG, $DB, $OUTPUT;
-
-    $dbman = $DB->get_manager();
-
-    // Moodle v2.2.0 release upgrade line
-    // Put any upgrade step following this
-
-    if ($oldversion < 2011112901) {
-        // convert all null passwords to empty strings
-        $DB->set_field('enrol', 'password', '', array('enrol'=>'guest', 'password'=>null));
-
-        upgrade_plugin_savepoint(true, 2011112901, 'enrol', 'guest');
-    }
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
@@ -68,5 +38,3 @@ function xmldb_enrol_guest_upgrade($oldversion) {
 
     return true;
 }
-
-
index 7fb9ea3..0bc6134 100644 (file)
@@ -31,24 +31,7 @@ defined('MOODLE_INTERNAL') || die();
  * @return bool true
  */
 function xmldb_enrol_imsenterprise_upgrade($oldversion) {
-    global $CFG, $DB;
-
-    $dbman = $DB->get_manager();
-
-    // Moodle v2.3.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.4.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index ae1a9e4..8fa81d6 100644 (file)
@@ -33,6 +33,13 @@ class enrol_ldap_plugin extends enrol_plugin {
     protected $enroltype = 'enrol_ldap';
     protected $errorlogtag = '[ENROL LDAP] ';
 
+    /**
+     * The object class to use when finding users.
+     *
+     * @var string $userobjectclass
+     */
+    protected $userobjectclass;
+
     /**
      * Constructor for the plugin. In addition to calling the parent
      * constructor, we define and 'fix' some settings depending on the
@@ -59,8 +66,13 @@ class enrol_ldap_plugin extends enrol_plugin {
         unset($ldap_usertypes);
 
         $default = ldap_getdefaults();
-        // Remove the objectclass default, as the values specified there are for
-        // users, and we are dealing with groups here.
+
+        // The objectclass in the defaults is for a user.
+        // This will be required later, but enrol_ldap uses 'objectclass' for its group objectclass.
+        // Save the normalised user objectclass for later.
+        $this->userobjectclass = ldap_normalise_objectclass($default['objectclass'][$this->get_config('user_type')]);
+
+        // Remove the objectclass default, as the values specified there are for users, and we are dealing with groups here.
         unset($default['objectclass']);
 
         // Use defaults if values not given. Dont use this->get_config()
@@ -72,31 +84,19 @@ class enrol_ldap_plugin extends enrol_plugin {
             }
         }
 
+        // Normalise the objectclass used for groups.
         if (empty($this->config->objectclass)) {
-            // Can't send empty filter. Fix it for now and future occasions
-            $this->set_config('objectclass', '(objectClass=*)');
-        } else if (stripos($this->config->objectclass, 'objectClass=') === 0) {
-            // Value is 'objectClass=some-string-here', so just add ()
-            // around the value (filter _must_ have them).
-            // Fix it for now and future occasions
-            $this->set_config('objectclass', '('.$this->config->objectclass.')');
-        } else if (stripos($this->config->objectclass, '(') !== 0) {
-            // Value is 'some-string-not-starting-with-left-parentheses',
-            // which is assumed to be the objectClass matching value.
-            // So build a valid filter with it.
-            $this->set_config('objectclass', '(objectClass='.$this->config->objectclass.')');
+            // No objectclass set yet - set a default class.
+            $this->config->objectclass = ldap_normalise_objectclass(null, '*');
+            $this->set_config('objectclass', $this->config->objectclass);
         } else {
-            // There is an additional possible value
-            // '(some-string-here)', that can be used to specify any
-            // valid filter string, to select subsets of users based
-            // on any criteria. For example, we could select the users
-            // whose objectClass is 'user' and have the
-            // 'enabledMoodleUser' attribute, with something like:
-            //
-            //   (&(objectClass=user)(enabledMoodleUser=1))
-            //
-            // In this particular case we don't need to do anything,
-            // so leave $this->config->objectclass as is.
+            $objectclass = ldap_normalise_objectclass($this->config->objectclass);
+            if ($objectclass !== $this->config->objectclass) {
+                // The objectclass was changed during normalisation.
+                // Save it in config, and update the local copy of config.
+                $this->set_config('objectclass', $objectclass);
+                $this->config->objectclass = $objectclass;
+            }
         }
     }
 
@@ -490,7 +490,7 @@ class enrol_ldap_plugin extends enrol_plugin {
                                 // as the idnumber does not match their dn and we get dn's from membership.
                                 $memberidnumbers = array();
                                 foreach ($ldapmembers as $ldapmember) {
-                                    $result = ldap_read($this->ldapconnection, $ldapmember, '(objectClass=*)',
+                                    $result = ldap_read($this->ldapconnection, $ldapmember, $this->userobjectclass,
                                                         array($this->config->idnumber_attribute));
                                     $entry = ldap_first_entry($this->ldapconnection, $result);
                                     $values = ldap_get_values($this->ldapconnection, $entry, $this->config->idnumber_attribute);
@@ -838,10 +838,9 @@ class enrol_ldap_plugin extends enrol_plugin {
         require_once($CFG->libdir.'/ldaplib.php');
 
         $ldap_contexts = explode(';', $this->get_config('user_contexts'));
-        $ldap_defaults = ldap_getdefaults();
 
         return ldap_find_userdn($this->ldapconnection, $userid, $ldap_contexts,
-                                '(objectClass='.$ldap_defaults['objectclass'][$this->get_config('user_type')].')',
+                                $this->userobjectclass,
                                 $this->get_config('idnumber_attribute'), $this->get_config('user_search_sub'));
     }
 
index be471bd..9ac6277 100644 (file)
@@ -469,4 +469,64 @@ class enrol_ldap_testcase extends advanced_testcase {
             }
         }
     }
+
+    /**
+     * Test that normalisation of the use objectclass is completed successfully.
+     *
+     * @dataProvider objectclass_fetch_provider
+     * @param string $usertype The supported user type
+     * @param string $expected The expected filter value
+     */
+    public function test_objectclass_fetch($usertype, $expected) {
+        $this->resetAfterTest();
+        // Set the user type - this must be performed before the plugin is instantiated.
+        set_config('user_type', $usertype, 'enrol_ldap');
+
+        // Fetch the plugin.
+        $instance = enrol_get_plugin('ldap');
+
+        // Use reflection to sneak a look at the plugin.
+        $rc = new ReflectionClass('enrol_ldap_plugin');
+        $rcp = $rc->getProperty('userobjectclass');
+        $rcp->setAccessible(true);
+
+        // Fetch the current userobjectclass value.
+        $value = $rcp->getValue($instance);
+        $this->assertEquals($expected, $value);
+    }
+
+    /**
+     * Data provider for the test_objectclass_fetch testcase.
+     *
+     * @return array of testcases.
+     */
+    public function objectclass_fetch_provider() {
+        return array(
+            // This is the list of values from ldap_getdefaults() normalised.
+            'edir' => array(
+                'edir',
+                '(objectClass=user)'
+            ),
+            'rfc2307' => array(
+                'rfc2307',
+                '(objectClass=posixaccount)'
+            ),
+            'rfc2307bis' => array(
+                'rfc2307bis',
+                '(objectClass=posixaccount)'
+            ),
+            'samba' => array(
+                'samba',
+                '(objectClass=sambasamaccount)'
+            ),
+            'ad' => array(
+                'ad',
+                '(samaccounttype=805306368)'
+            ),
+            'default' => array(
+                'default',
+                '(objectClass=*)'
+            ),
+        );
+    }
 }
index 7b98f19..5ec65e3 100644 (file)
  * This file keeps track of upgrades to the manual enrolment plugin
  *
  * @package    enrol_manual
- * @copyright  2012 Petr Skoda {@link http://skodak.org
+ * @copyright  2012 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 defined('MOODLE_INTERNAL') || die();
 
 function xmldb_enrol_manual_upgrade($oldversion) {
-    global $CFG, $DB, $OUTPUT;
-
-    $dbman = $DB->get_manager();
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-    if ($oldversion < 2012100702) {
-        // Set default expiry threshold to 1 day.
-        $DB->execute("UPDATE {enrol} SET expirythreshold = 86400 WHERE enrol = 'manual' AND expirythreshold = 0");
-        upgrade_plugin_savepoint(true, 2012100702, 'enrol', 'manual');
-    }
-
-    if ($oldversion < 2012101400) {
-        // Delete obsoleted settings, now using expiry* prefix to make them more consistent.
-        unset_config('notifylast', 'enrol_manual');
-        unset_config('notifyhour', 'enrol_manual');
-        upgrade_plugin_savepoint(true, 2012101400, 'enrol', 'manual');
-    }
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
@@ -77,5 +44,3 @@ function xmldb_enrol_manual_upgrade($oldversion) {
 
     return true;
 }
-
-
index e66d6ec..2a59641 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-
 // This file is part of Moodle - http://moodle.org/
 //
 // Moodle is free software: you can redistribute it and/or modify
 defined('MOODLE_INTERNAL') || die();
 
 function xmldb_enrol_mnet_upgrade($oldversion) {
-    global $CFG, $DB;
-
-    $dbman = $DB->get_manager();
-
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index faf51dc..1497469 100644 (file)
 // Please do not forget to use upgrade_set_timeout()
 // before any action that may take longer time to finish.
 
-function xmldb_enrol_paypal_upgrade($oldversion) {
-    global $CFG, $DB;
-
-    $dbman = $DB->get_manager();
-
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
+defined('MOODLE_INTERNAL') || die();
 
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+function xmldb_enrol_paypal_upgrade($oldversion) {
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
diff --git a/enrol/paypal/pix/icon.gif b/enrol/paypal/pix/icon.gif
deleted file mode 100644 (file)
index 86fc60a..0000000
Binary files a/enrol/paypal/pix/icon.gif and /dev/null differ
index 62cb0df..82bb97d 100644 (file)
  * This file keeps track of upgrades to the self enrolment plugin
  *
  * @package    enrol_self
- * @copyright  2012 Petr Skoda {@link http://skodak.org
+ * @copyright  2012 Petr Skoda {@link http://skodak.org}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 defined('MOODLE_INTERNAL') || die();
 
 function xmldb_enrol_self_upgrade($oldversion) {
-    global $CFG, $DB, $OUTPUT;
-
-    $dbman = $DB->get_manager();
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-    if ($oldversion < 2012101400) {
-        // Set default expiry threshold to 1 day.
-        $DB->execute("UPDATE {enrol} SET expirythreshold = 86400 WHERE enrol = 'self' AND expirythreshold = 0");
-        upgrade_plugin_savepoint(true, 2012101400, 'enrol', 'self');
-    }
-
-    if ($oldversion < 2012120600) {
-        // Enable new self enrolments everywhere.
-        $DB->execute("UPDATE {enrol} SET customint6 = 1 WHERE enrol = 'self'");
-        upgrade_plugin_savepoint(true, 2012120600, 'enrol', 'self');
-    }
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    if ($oldversion < 2013112100) {
-        // Set customint1 (group enrolment key) to 0 if it was not set (null).
-        $DB->execute("UPDATE {enrol} SET customint1 = 0 WHERE enrol = 'self' AND customint1 IS NULL");
-        upgrade_plugin_savepoint(true, 2013112100, 'enrol', 'self');
-    }
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
@@ -76,5 +38,3 @@ function xmldb_enrol_self_upgrade($oldversion) {
 
     return true;
 }
-
-
index ecffc3c..58f6b4c 100644 (file)
Binary files a/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-debug.js and b/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-debug.js differ
index 46b748d..c2fdc14 100644 (file)
Binary files a/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-min.js and b/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker-min.js differ
index ecffc3c..58f6b4c 100644 (file)
Binary files a/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker.js and b/filter/glossary/yui/build/moodle-filter_glossary-autolinker/moodle-filter_glossary-autolinker.js differ
index 3689b4a..2d0471e 100644 (file)
@@ -73,7 +73,6 @@ Y.extend(AUTOLINKER, Y.Base, {
             alertpanelid,
             definition,
             position;
-        var self = this;
         try {
             data = Y.JSON.parse(content);
             if (data.success){
@@ -89,7 +88,7 @@ Y.extend(AUTOLINKER, Y.Base, {
 
                     // Register alertpanel for stacking.
                     alertpanelid = '#moodle-dialogue-' + alertpanel.get('COUNT');
-                    alertpanel.on('complete', this._deletealertpanel(self.alertpanels, alertpanelid));
+                    alertpanel.on('complete', this._deletealertpanel, this, alertpanelid);
 
                     // We already have some windows opened, so set the right position...
                     if (!Y.Object.isEmpty(this.alertpanels)){
@@ -118,8 +117,8 @@ Y.extend(AUTOLINKER, Y.Base, {
         });
         return lastPosition;
     },
-    _deletealertpanel : function(alertpanels, alertpanelid) {
-        delete alertpanels[alertpanelid];
+    _deletealertpanel : function(ev, alertpanelid) {
+        delete this.alertpanels[alertpanelid];
     }
 }, {
     NAME : AUTOLINKERNAME,
index eb1e4cd..056cc18 100644 (file)
@@ -22,6 +22,8 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * @param int $oldversion the version we are upgrading from
  * @return bool result
@@ -31,9 +33,6 @@ function xmldb_filter_mathjaxloader_upgrade($oldversion) {
 
     $dbman = $DB->get_manager();
 
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
-
     if ($oldversion < 2014081100) {
 
         $sslcdnurl = get_config('filter_mathjaxloader', 'httpsurl');
index 3e37445..2a70d61 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * @param int $oldversion the version we are upgrading from
  * @return bool result
  */
 function xmldb_filter_mediaplugin_upgrade($oldversion) {
-    global $CFG, $DB;
-
-    $dbman = $DB->get_manager();
-
-
-    if ($oldversion < 2011121200) {
-        // Move all the media enable setttings that are now handled by core media renderer.
-        foreach (array('html5video', 'html5audio', 'mp3', 'flv', 'wmp', 'qt', 'rm',
-                'youtube', 'vimeo', 'swf') as $type) {
-            $existingkey = 'filter_mediaplugin_enable_' . $type;
-            if (array_key_exists($existingkey, $CFG)) {
-                set_config('core_media_enable_' . $type, $CFG->{$existingkey});
-                unset_config($existingkey);
-            }
-        }
-
-        // Override setting for html5 to turn it on (previous default was off; because
-        // of changes in the way fallbacks are handled, this is now unlikely to cause
-        // a problem, and is required for mobile a/v support on non-Flash devices, so
-        // this change is basically needed in order to maintain existing behaviour).
-        set_config('core_media_enable_html5video', 1);
-        set_config('core_media_enable_html5audio', 1);
-
-        upgrade_plugin_savepoint(true, 2011121200, 'filter', 'mediaplugin');
-    }
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index 703a7d4..14aa3d8 100644 (file)
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
+defined('MOODLE_INTERNAL') || die();
+
 /**
  * @param int $oldversion the version we are upgrading from
  * @return bool result
  */
 function xmldb_filter_tex_upgrade($oldversion) {
-    global $CFG, $DB;
-
-    $dbman = $DB->get_manager();
-
-
-    // Moodle v2.3.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.4.0 release upgrade line
-    // Put any upgrade step following this
-
-
-    // Moodle v2.5.0 release upgrade line.
-    // Put any upgrade step following this.
-
-
-    // Moodle v2.6.0 release upgrade line.
-    // Put any upgrade step following this.
-
-    if ($oldversion < 2013120300) {
-        $settings = array(
-                'density', 'latexbackground', 'convertformat', 'pathlatex',
-                'convertformat', 'pathconvert', 'pathdvips', 'latexpreamble');
-
-        // Move tex settings to config_pluins and delete entries from the config table.
-        foreach ($settings as $setting) {
-            $existingkey = 'filter_tex_'.$setting;
-            if (array_key_exists($existingkey, $CFG)) {
-                set_config($setting, $CFG->{$existingkey}, 'filter_tex');
-                unset_config($existingkey);
-            }
-        }
-
-        upgrade_plugin_savepoint(true, 2013120300, 'filter', 'tex');
-    }
-
-    // Moodle v2.7.0 release upgrade line.
-    // Put any upgrade step following this.
+    global $CFG;
 
     // Moodle v2.8.0 release upgrade line.
     // Put any upgrade step following this.
index 75d3901..7ee5cbe 100644 (file)
@@ -156,6 +156,8 @@ if ($mform->is_cancelled()) {
     }
 
     $grade_item = new grade_item(array('id'=>$id, 'courseid'=>$courseid));
+    $oldmin = $grade_item->grademin;
+    $oldmax = $grade_item->grademax;
     grade_item::set_properties($grade_item, $data);
     $grade_item->outcomeid = null;
 
@@ -175,6 +177,12 @@ if ($mform->is_cancelled()) {
 
     } else {
         $grade_item->update();
+
+        if (!empty($data->rescalegrades) && $data->rescalegrades == 'yes') {
+            $newmin = $grade_item->grademin;
+            $newmax = $grade_item->grademax;
+            $grade_item->re