Compare commits

..

635 Commits

Author SHA1 Message Date
Dan Poltawski 382d80646b weekly release 2.9.9+ 2016-11-29 13:32:32 +00:00
Dan Poltawski 9d4c11199e Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-11-29 13:32:31 +00:00
Vladimir Zhirov b99f854795 MDL-57163 installation: fixed "Call to undefined function curl_version" 2016-11-29 14:13:45 +01:00
AMOS bot 89ad5776d4 Automatically generated installer lang files 2016-11-27 00:06:18 +08:00
David Monllao 9bff4d35db weekly release 2.9.9+ 2016-11-25 15:56:35 +08:00
David Monllao 47ccd6b3d7 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-11-25 15:56:33 +08:00
Damyon Wiese 7724705df1 MDL-57100 JS: Exceptions give exceptions
Exceptions returned from ajax are not in the format expected by the JS, so
an error occurs and the exception popups are not appearing.

Conflicts:
	lib/amd/build/notification.min.js
	lib/amd/src/notification.js
2016-11-23 18:08:14 +00:00
AMOS bot e767bf986d Automatically generated installer lang files 2016-11-23 00:05:44 +08:00
AMOS bot 7747f5f717 Automatically generated installer lang files 2016-11-17 00:05:26 +08:00
Eloy Lafuente (stronk7) da84dd37f3 Moodle release 2.9.9 2016-11-12 20:21:22 +01:00
Eloy Lafuente (stronk7) 3c413110ff Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-11-12 20:21:19 +01:00
AMOS bot 7ba4955f9d Automatically generated installer lang files 2016-11-12 00:29:41 +08:00
Andrew Nicols 8c504c1f0e Merge branch 'MDL-55121-29' of git://github.com/lameze/moodle into MOODLE_29_STABLE 2016-11-11 15:14:36 +08:00
Simey Lameze dfe8919c6c MDL-55121 environment: check for unsuported php version 7.1 2016-11-11 12:35:10 +08:00
Dan Poltawski 5c2adb282f MDL-55777 version: bump 2016-11-10 13:48:39 +00:00
Dan Poltawski bc9fc77b39 Merge branch 'MDL-55777-29' of git://github.com/ankitagarwal/moodle into MOODLE_29_STABLE 2016-11-10 13:46:49 +00:00
Ankit Agarwal 86c22b202d MDL-55777 installation: Check libcurl version on install 2016-11-10 10:24:09 +05:30
Juan Leyva 0ee30fc5b8 MDL-56268 webservice: Format backtrace to avoid display private datawq 2016-11-07 13:15:57 +00:00
AMOS bot f0e38c2ce6 Automatically generated installer lang files 2016-11-07 00:05:18 +08:00
AMOS bot 5c86055249 Automatically generated installer lang files 2016-10-26 00:04:57 +08:00
Simey Lameze 4daa27678a MDL-51347 core_notes: check view notes capability by course context 2016-10-17 16:18:34 +08:00
AMOS bot ec091d8198 Automatically generated installer lang files 2016-10-17 00:07:17 +08:00
AMOS bot f342654ca7 Automatically generated installer lang files 2016-10-15 00:05:17 +08:00
AMOS bot eb28fb4f3a Automatically generated installer lang files 2016-10-12 00:05:27 +08:00
Tim Hunt 3142206102 MDL-53744 question file access: fix access checks 2016-10-10 11:11:26 +08:00
AMOS bot a954d77d37 Automatically generated installer lang files 2016-10-09 00:06:56 +08:00
AMOS bot 7bb24f9884 Automatically generated installer lang files 2016-10-08 00:05:18 +08:00
AMOS bot 3b7c411dcf Automatically generated installer lang files 2016-10-05 00:06:51 +08:00
AMOS bot d4b822cfb1 Automatically generated installer lang files 2016-09-28 00:05:12 +08:00
Juan Leyva f01632affa MDL-56065 user: Fix update_users Web Service
Users won’t be updated if:
- They are admins and the user updating is not
- They are the guest user
- They are mnet users
- They are deleted users
2016-09-26 18:39:30 +02:00
AMOS bot 1dec402e96 Automatically generated installer lang files 2016-09-23 00:05:13 +08:00
AMOS bot cbe5699193 Automatically generated installer lang files 2016-09-20 00:05:01 +08:00
AMOS bot b8a545f8de Automatically generated installer lang files 2016-09-17 00:05:16 +08:00
AMOS bot 93a1739f39 Automatically generated installer lang files 2016-09-16 00:05:36 +08:00
Dan Poltawski 216b71f03e weekly release 2.9.8+ 2016-09-15 11:15:18 +01:00
Jake Dallimore f55a65b0bf MDL-55945 login: fix https support for forgot_password.php 2016-09-15 09:23:45 +08:00
Eloy Lafuente (stronk7) 567ab3d5d1 Moodle release 2.9.8 2016-09-10 22:50:11 +02:00
Eloy Lafuente (stronk7) ebbad9ca59 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-09-10 22:50:07 +02:00
AMOS bot b2d737b90d Automatically generated installer lang files 2016-08-30 00:05:23 +08:00
AMOS bot db46fe6c59 Automatically generated installer lang files 2016-08-27 00:05:17 +08:00
AMOS bot b31ba08ffa Automatically generated installer lang files 2016-08-25 00:05:53 +08:00
Jake Dallimore 365ecbead3 MDL-50803 login: Remove token from URL in forgot password process
Store the token value in the session and redirect to self, thus
removing the token from the URL and eliminating the problem where
the token is exposed via the http referer header.
2016-08-16 10:29:17 +01:00
AMOS bot 51bde4b0dc Automatically generated installer lang files 2016-08-10 00:05:20 +08:00
AMOS bot 72f8b25b24 Automatically generated installer lang files 2016-08-06 00:05:31 +08:00
Juan Leyva ce75268a2f MDL-49026 webservice: Remove tokens on password change 2016-08-02 09:32:53 +08:00
AMOS bot 2d6e97b5c2 Automatically generated installer lang files 2016-08-02 00:04:49 +08:00
AMOS bot f14fa82b5b Automatically generated installer lang files 2016-07-29 00:06:15 +08:00
AMOS bot 4fd4f002ee Automatically generated installer lang files 2016-07-20 00:05:48 +08:00
AMOS bot 139f1a0ad8 Automatically generated installer lang files 2016-07-16 00:06:08 +08:00
AMOS bot fa8fb6fbe1 Automatically generated installer lang files 2016-07-13 00:05:16 +08:00
AMOS bot 27d127b9c5 Automatically generated installer lang files 2016-07-11 00:06:26 +08:00
Eloy Lafuente (stronk7) 1174a463f3 Moodle release 2.9.7 2016-07-10 00:29:12 +02:00
Eloy Lafuente (stronk7) 33d0756aac Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-07-10 00:29:07 +02:00
Jake Dallimore 41d01a8f98 MDL-53431 tool_monitor: Access control for tool monitor subscriptions 2016-07-05 10:47:02 +08:00
Marina Glancy 67889ed5be MDL-55069 core: escape special characters in email headers 2016-07-04 12:28:09 +01:00
Andrew Nicols 65c1213e00 Merge branch 'MDL-53019_29' of git://github.com/stronk7/moodle into MOODLE_29_STABLE 2016-07-04 09:14:43 +08:00
AMOS bot df4907d146 Automatically generated installer lang files 2016-07-02 00:05:34 +08:00
Eloy Lafuente (stronk7) 85d91d18b4 MDL-53019 environment: 3.2 requirements added
Changes:
 - PHP 5.6.5 required
2016-07-01 13:50:14 +02:00
AMOS bot b0dd37fa73 Automatically generated installer lang files 2016-06-28 00:06:26 +08:00
AMOS bot 4f5fba677a Automatically generated installer lang files 2016-06-22 00:06:50 +08:00
AMOS bot 95ac714f8f Automatically generated installer lang files 2016-06-21 00:06:10 +08:00
AMOS bot 1ea01c9c50 Automatically generated installer lang files 2016-06-21 00:06:09 +08:00
AMOS bot 94587407ec Automatically generated installer lang files 2016-06-20 00:05:26 +08:00
AMOS bot f3076b17b4 Automatically generated installer lang files 2016-06-04 00:04:54 +08:00
AMOS bot b54ac35cb3 Automatically generated installer lang files 2016-06-02 00:04:42 +08:00
AMOS bot 8b3a8b9438 Automatically generated installer lang files 2016-05-25 00:05:08 +08:00
AMOS bot e3e619e845 Automatically generated installer lang files 2016-05-24 00:04:48 +08:00
Dan Poltawski c345c3a460 weekly release 2.9.6+ 2016-05-20 10:15:27 +01:00
Dan Poltawski 81b1e515f4 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-05-20 10:15:24 +01:00
Andrew Nicols 218d2c0eb3 Merge branch 'wip-mdl-54564-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-05-18 12:27:06 +08:00
Andrew Nicols 81fcfc2065 MDL-54620 rating: Add tests for get_aggregate_string 2016-05-18 12:13:06 +08:00
Andrew Nicols 5c18bd041a Merge branch 'MDL-54620_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-05-18 12:11:49 +08:00
Rajesh Taneja ad1b3e2a11 MDL-54564 behat: Wait after hover, to ensure page is ready 2016-05-18 11:17:32 +08:00
Kevin Wiliarty e647d73811 MDL-54620 ratings: display '0' when aggregate = 0 2016-05-18 07:38:06 +08:00
AMOS bot 554826ec78 Automatically generated installer lang files 2016-05-15 00:05:13 +08:00
AMOS bot d23c5c8c8d Automatically generated installer lang files 2016-05-10 00:05:03 +08:00
Eloy Lafuente (stronk7) 9ea5796a63 Moodle release 2.9.6 2016-05-08 00:23:51 +02:00
Dan Poltawski 061fd45c33 Merge branch 'MDL-54042-29' of git://github.com/damyon/moodle into MOODLE_29_STABLE 2016-05-06 14:09:28 +01:00
Damyon Wiese 178d87e0b6 MDL-54042 user: Add unit test to cover change 2016-05-06 16:43:56 +08:00
Damyon Wiese ebdec47991 MDL-54042 user: Fix debugging in core_user_get_users_by_field
The course object returned by enrol_get_all_users_courses does not include the defaultgroupingid.

This course object is passed to user_get_user_details - which does need
the defaultgroupingid.

All the other group info is returned (groupmode) etc - so it makes sense to also return this extra field.
2016-05-06 16:43:56 +08:00
David Monllao 18c4978bba weekly release 2.9.5+ 2016-05-06 16:14:59 +08:00
David Monllao 383b1ae15d Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-05-06 16:14:57 +08:00
Andrew Nicols b53f8c676c Merge branch 'wip-mdl-53701-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-05-06 10:14:48 +08:00
Dan Poltawski 6cae543378 MDL-54062 bootstrapbase: remove unused less file
This file has never been included in our CSS.
2016-05-06 09:46:46 +08:00
Eloy Lafuente (stronk7) 53a51dab0a MDL-53944 dml: make char2real() for mysql to support decimals
- With the patch, 6 positions of scale accuracy are guaranteed
  per individual casted value.
- Backed with unit tests, both for varchar and clob.
- Added 2 missing tests about uses of the method with params
  and values.

Note: 6 was picked because looking to all databases implementation
postgres was found to be casting to real, aka, 6.
2016-05-06 09:46:45 +08:00
Adam Olley cf0374d303 MDL-54007 mod_assign: Limit unit tests to core plugins
Without this change, the unit tests make assumptions for the output of
mod_assign functions/webservices that do not hold true when 3rd party
submission and feedback plugins are installed.
2016-05-06 09:46:45 +08:00
Simey Lameze 3194244721 MDL-53913 core_user: make parameters consistent across versions 2016-05-06 09:46:44 +08:00
Fred Woolard b1b9ddc302 MDL-53713 core: account for session_start returning false 2016-05-06 09:46:44 +08:00
David Monllao 9e96e0b36f MDL-53750 shibboleth: Passing a var to empty for PHP 5.4 2016-05-06 09:46:44 +08:00
John Okely 93b0e733cc MDL-53750 auth: fix logout bug in shibboleth
Original patch by Dr. Michael Schneider
2016-05-06 09:46:43 +08:00
Frederic Massart 16227d8ef3 MDL-51369 course: Adding tests to cover restoring course info 2016-05-06 09:46:43 +08:00
Frederic Massart 2950f9fb91 MDL-51369 backup: Respect capabilities when restoring course info
In short, when a user is creating a new course they can set
the ID number, shortname, fullname and summary. However, when
they merge a backup into a course they need the permissions to do so.
2016-05-06 09:46:43 +08:00
Frederic Massart 872fe961f8 MDL-53954 user: Prevent locked profile fields from being edited 2016-05-06 09:46:42 +08:00
Andrew Nicols d98c246599 MDL-53755 forum: Check session when marking posts 2016-05-06 09:46:42 +08:00
Andrew Nicols bc890913fe MDL-53696 forum: Check discussion in forum 2016-05-06 09:46:42 +08:00
Tim Hunt 6739845c85 MDL-53589 badges: fix capability check 2016-05-06 09:46:41 +08:00
Dan Marsden aaa49aa835 MDL-53546 SCORM: Set window.opener to null 2016-05-06 09:46:41 +08:00
Rajesh Taneja 8ed8c68dfb MDL-53701 core_lib: use date_format_string for utf8
So when language is different say Hebrew then
it would pic codepage-1255. As  is json_encoded
we need to ensure we get utf8 string. so use
date_format_string instead
2016-05-05 16:36:33 +08:00
AMOS bot 6a59a0b349 Automatically generated installer lang files 2016-05-05 00:04:50 +08:00
Dan Poltawski 1cb6ac499a weekly release 2.9.5+ 2016-05-03 20:38:05 +01:00
Dan Poltawski 9a5709f474 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-05-03 20:38:03 +01:00
Dan Poltawski efa18040dc Merge branch 'wip-MDL-53402-29-v2' of git://github.com/abgreeve/moodle into MOODLE_29_STABLE 2016-05-03 09:13:29 +01:00
Dan Poltawski f2aa7e7bd9 MDL-54008 tests: clarify comment in tz test 2016-05-03 09:10:31 +01:00
Dan Poltawski fe404e039c Merge branch 'MDL-54008_29-normalise' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-05-03 09:09:08 +01:00
Adrian Greeve 2a8f372e1c MDL-53402 mod_data: field values of 0 are now displayed. 2016-05-03 15:09:22 +08:00
David Monllao a9cca2b893 MDL-54008 tz: Unexisting tz with decimals fallback to rounded down integer 2016-05-03 14:02:13 +08:00
David Monllao ae77a3d6d1 Merge branch 'wip-MDL-53402-29' of git://github.com/abgreeve/moodle into MOODLE_29_STABLE 2016-05-03 13:03:55 +08:00
Adrian Greeve 85ac3cdbb0 MDL-53402 mod_data: Added custom validation code for data fields.
Added custom validation to radiobutton, menu, and checkbox.
2016-05-03 12:54:49 +08:00
David Monllao 809233d23f Merge branch 'MDL-51142-29' of git://github.com/damyon/moodle into MOODLE_29_STABLE 2016-05-03 09:59:18 +08:00
Dan Poltawski 166a09028f Merge branch 'wip-MDL-53402-29' of git://github.com/abgreeve/moodle into MOODLE_29_STABLE 2016-05-02 17:06:28 +01:00
Dan Poltawski a34068d126 Merge branch 'MDL-54019_m29' of git://github.com/markn86/moodle into MOODLE_29_STABLE 2016-05-02 16:57:14 +01:00
Dan Poltawski 7d0051154e Merge branch 'wip-mdl-53861-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-05-02 16:55:53 +01:00
Mark Nelson d19d7309e6 MDL-54019 core_behat: fixed typo 2016-05-02 18:12:06 +08:00
Dan Poltawski ecccb0d30c Merge branch 'wip_MDL-53033_m29' of git://github.com/gjb2048/moodle into MOODLE_29_STABLE 2016-05-02 10:17:11 +01:00
Dan Poltawski 3ece99e9d0 Merge branch 'MDL-53904-29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2016-05-02 10:16:38 +01:00
Dan Poltawski 283375144b Merge branch 'MDL-54008_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-05-02 09:52:25 +01:00
Damyon Wiese 6d9f6af6ef MDL-51142 assign: Fix for group assignments with NEW status 2016-05-02 16:44:48 +08:00
Clement Smith 5056eeab3a MDL-51142 mod/assign: Fix erroneous submission status display
This prevents display of submission time/date when the assignment
submission record is in a new state. It also keeps the display of
overdue assignments identical for those students who have viewed
the assignment yet not submitted, for those students who have
not viewed the assignment, and for those students who have not
viewed the assignment yet the instructor has accessed the grading
page.
2016-05-02 16:44:47 +08:00
Rajesh Taneja 99913f0b50 MDL-53861 behat: o/p buffer is not used in Behat 2.5.x
Don't need ob_flush() as o/p is not buffered
in behat 2.5.x
2016-05-02 15:55:18 +08:00
David Monllao 9b9c08cdbb Merge branch 'MDL-53901-29' of git://github.com/damyon/moodle into MOODLE_29_STABLE 2016-05-02 15:54:26 +08:00
David Monllao 4f3a6d382e Merge branch 'MDL-53635-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2016-05-02 15:38:31 +08:00
Juan Leyva 47f7b1e386 MDL-53635 message_airnotifier: Remove tags from notifications 2016-05-02 09:33:29 +02:00
David Monllao e50f5d51a5 MDL-54008 timezone: Updating references to Caracas tz.
I've removed Caracas direct references because it would fail on
some systems, it would depend on how updated is the olson version
PHP is using.
2016-05-02 15:07:20 +08:00
Adrian Greeve 0f8a2d6734 MDL-53402 mod_data: Behat test for entering zero in required fields. 2016-05-02 13:40:10 +08:00
Adrian Greeve c01cbb3e1a MDL-53402 mod_data: Required fields can contain 0.
The number and text field would not accept 0 as a
valid response.
2016-05-02 13:40:05 +08:00
Damyon Wiese 44465eddef MDL-53901 login: Redirect to https if loginhttps is enabled
This just prevents a double redirect.
2016-05-02 11:22:17 +08:00
David Monllao ded031cfc8 Merge branch 'MDL-53980-29-enfix' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2016-05-02 10:47:59 +08:00
AMOS bot 9a7adbcd32 Automatically generated installer lang files 2016-05-02 00:04:37 +08:00
AMOS bot d3d1f84271 Automatically generated installer lang files 2016-04-30 00:07:10 +08:00
Dan Poltawski 4039f94021 weekly release 2.9.5+ 2016-04-29 12:26:59 +01:00
Andrew Nicols 382274be5b MDL-53858 quiz accessibility: Correct aria-labelledby attribute 2016-04-29 12:14:24 +01:00
Andrew Nicols 9909401af4 Merge branch 'MDL-53858_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-04-29 12:14:23 +01:00
David Monllao c3732af3f3 Merge branch 'MDL-53928_29' of git://github.com/stronk7/moodle into MOODLE_29_STABLE 2016-04-29 12:14:23 +01:00
Helen Foster 180e818331 MDL-53980 lang: Merge English strings from the en_fix language pack 2016-04-29 08:10:32 +02:00
Marina Glancy a94e86d9cc MDL-53904 course: apply default completion when approving request 2016-04-27 15:57:15 +08:00
Henning Bostelmann 2779372c17 MDL-53780 mod_assign: Remove teachers from submission group members 2016-04-26 15:38:01 +01:00
Dan Poltawski 7159a9ab0c Merge branch 'MDL-53855_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-04-26 11:18:31 +01:00
Dan Poltawski 953b8cb7c8 weekly release 2.9.5+ 2016-04-26 09:28:25 +01:00
David Monllao 8c1d988566 Merge branch 'MDL-52550-29' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE 2016-04-26 11:12:58 +08:00
Dan Poltawski f570ad59cf Merge branch 'MDL-49754-29' of https://github.com/xow/moodle into MOODLE_29_STABLE 2016-04-25 14:38:46 +01:00
Eloy Lafuente (stronk7) 0138da3949 MDL-53928 environment: add xmlreader requirement for 3.1 2016-04-24 01:36:46 +02:00
Eloy Lafuente (stronk7) e7975d1443 weekly release 2.9.5+ 2016-04-22 10:57:04 +02:00
Panagiotis Nikoloutsopoulos 753cde3442 MDL-52550 atto: Added preventDefaults for events dragover and dragenter 2016-04-21 15:11:35 +08:00
Dan Poltawski 38dbbecc4d Merge branch 'wip-MDL-52642-29' of git://github.com/abgreeve/moodle into MOODLE_29_STABLE 2016-04-20 13:48:39 +01:00
Dan Poltawski 9b2faf2056 Merge branch 'MDL-53095-29' of git://github.com/lameze/moodle into MOODLE_29_STABLE 2016-04-20 11:52:16 +01:00
David Monllao af61aeda9b Merge branch 'MDL-53757_m29' of git://github.com/markn86/moodle into MOODLE_29_STABLE 2016-04-20 15:53:42 +08:00
Nick Phillips 9abda98e48 MDL-53757 core_calendar: always show whole day's events in 'day' view 2016-04-20 15:49:41 +08:00
David Monllao be0f46f922 Merge branch 'MDL-53676_29' of https://github.com/wjroes/moodle into MOODLE_29_STABLE 2016-04-20 11:17:07 +08:00
Eloy Lafuente (stronk7) 75dcdc098e Merge branch 'MDL-53660-29' of git://github.com/danpoltawski/moodle into MOODLE_29_STABLE 2016-04-20 01:20:21 +02:00
Andrew Nicols 35720ce43b Merge branch 'MDL-53779-29' of git://github.com/FMCorz/moodle into MOODLE_29_STABLE 2016-04-19 10:37:04 +08:00
Eloy Lafuente (stronk7) 2e97e1fee1 Merge branch 'MDL-53796_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-04-19 01:59:01 +02:00
Tim Hunt 4ead6b97f0 MDL-53858 quiz accessibility: nav block should have role='navigation' 2016-04-18 17:37:22 +01:00
Tim Hunt 46b091a67e MDL-53855 accessibility: navbar should be in exactly one nav region
And that should be labelled.
2016-04-18 16:57:06 +01:00
Eloy Lafuente (stronk7) b61f86a052 weekly release 2.9.5+ 2016-04-15 10:19:14 +02:00
Eloy Lafuente (stronk7) 867824322f Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-04-15 10:19:09 +02:00
Mark Nielsen 92f2b31f74 MDL-53660 mod_forum: Fix link decoding in single discussions
This only happens when user data is not included.
2016-04-13 16:00:58 +01:00
Gareth J Barnard 445312d685 MDL-53033 themes: Invalid attribute values for div.c1.btn. 2016-04-13 12:56:13 +01:00
Dan Poltawski 59d7b59a0b Revert "Merge branch 'MDL-52944-29' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE"
This reverts commit e0339be416, reversing
changes made to a6d9d5f7e4.
2016-04-13 10:49:08 +01:00
David Risner 54df1bdcf7 MDL-53095 repository_merlot: change merlot url use https 2016-04-13 15:11:49 +08:00
David Monllao 256cd103ba MDL-53796 behat: Move get_debug_text to base class 2016-04-13 10:37:10 +08:00
AMOS bot 48d1f7267b Automatically generated installer lang files 2016-04-13 00:04:34 +08:00
Dan Poltawski bf980316b0 Merge branch 'MDL-52263-29' of git://github.com/crazyserver/moodle into MOODLE_29_STABLE 2016-04-12 16:50:32 +01:00
Pau Ferrer Ocaña 88546dad6b MDL-52263 libraries: Add test cases to external_format_text options 2016-04-12 15:04:46 +02:00
Pau Ferrer Ocaña f32bd23f8f MDL-52263 libraries: Add options to external_format_text 2016-04-12 14:56:19 +02:00
Dan Poltawski e0339be416 Merge branch 'MDL-52944-29' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE 2016-04-12 13:13:59 +01:00
Frederic Massart fefe867a72 MDL-53779 external: get_string and get_strings use PARAM_RAW
For the string parameters and translated strings.
2016-04-12 17:04:50 +08:00
spvickers eb81e0b50a MDL-49754 mod_lti: Fixes to JSON format
@id elements in JSON corrected to match the IMS spec.  Version number of
the service updated.
2016-04-12 15:50:02 +08:00
Adrian Greeve a1468ef48b MDL-52642 blog: Fix notices for swapping contexts in activities. 2016-04-12 13:55:08 +08:00
Stephen Bourget 795e302ea4 MDL-52642 block_blog_menu: behat test 2016-04-12 13:54:58 +08:00
David Monllao a6d9d5f7e4 Merge branch 'MDL-53007_29_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_29_STABLE 2016-04-12 11:31:41 +08:00
David Monllao ff51028d8d Merge branch 'MDL-53770-29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2016-04-12 10:54:34 +08:00
Dan Poltawski e43bea4883 Merge branch 'MDL-53417-29' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE 2016-04-11 16:37:09 +01:00
Dan Poltawski 3f80f680ad Merge branch 'MDL-53674-29-eventmsg' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2016-04-11 14:29:16 +01:00
Dan Poltawski 5f100892d0 Merge branch 'MDL-53728_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-04-11 14:10:24 +01:00
Dan Poltawski e561b3b818 Merge branch 'MDL-52338-29' of https://github.com/dg711/moodle into MOODLE_29_STABLE 2016-04-11 13:53:22 +01:00
Andrew Nicols 6837221beb MDL-52942 forum: Allow posting to multiple groups in eachuser forums 2016-04-11 12:45:17 +08:00
Devang Gaur 475c4d7ca8 MDL-52338 blocks: message link should not appear when set false 2016-04-11 08:31:22 +05:30
Marina Glancy 95a2aa2e1c MDL-53770 mod_lti: allow to uninstall ltisource plugins 2016-04-11 09:04:46 +08:00
David Mudrák a3ac5646e4 MDL-53674 event monitor: Do not send HTML as plain text formatted emails
There were two problems here.

* The $msgdata->fullmessage was always formatted as HTML even if the
  $msgdata->fullmessageformat was set to the original template's format.
* The plain text part of the emailed message contained HTML code.

The patch makes sure that the original template is always formatted into
HTML and then converted to plain text before setting the text/plain
multipart of the sent email.
2016-04-08 15:15:18 +02:00
Cameron Ball 91a5c94a00 MDL-52944 atto: Use event-key to handle enter key 2016-04-08 12:37:05 +08:00
Panagiotis Nikoloutsopoulos 44019add1f MDL-52944 atto: Contenteditable command 'FormatBlock' set to 'p' 2016-04-08 12:37:04 +08:00
Mark Johnson e938870101 MDL-53007 block_navigation: Set width of item text to prevent overflow 2016-04-07 11:48:03 +01:00
Andrew Nicols 98eb681cc0 weekly release 2.9.5+ 2016-04-07 14:00:36 +08:00
Andrew Nicols d414753678 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-04-07 14:00:33 +08:00
Willem Roes 451d540527 MDL-53676 block_navigation: fix incorrect array iteration 2016-04-07 07:46:45 +02:00
Rajesh Taneja aab5ef2cbc MDL-52502 behat: Flush buffer to show differences 2016-04-07 09:39:37 +08:00
AMOS bot 378b622a09 Automatically generated installer lang files 2016-04-07 00:05:17 +08:00
Dan Poltawski 888adbee07 Merge branch 'MDL-53000-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2016-04-06 15:48:03 +01:00
Tim Hunt 6e56027b5b MDL-53728 question import/export: improve form structure 2016-04-06 15:36:30 +01:00
Juan Leyva bc1ded6ef4 MDL-53000 mod_assign: Unit tests for get_file_areas 2016-04-06 12:56:58 +02:00
Andrew Nicols ff0cc2dc3c Merge branch 'wip-mdl-53381-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-04-06 12:24:58 +08:00
Rajesh Taneja ec0a000564 MDL-53381 behat: Add support to execute step api
With chain step deprecation, execute api will
help user to execute step api and backport it
2016-04-06 11:00:14 +08:00
Eloy Lafuente (stronk7) e596ea8ca5 Merge branch 'MDL-53115-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-04-06 03:33:17 +02:00
Andrew Nicols 10c227830e MDL-53461 assign: Unit test regex fix 2016-04-06 08:57:13 +08:00
Andrew Nicols 1b46b00f98 Merge branch 'MDL-53461-29' of git://github.com/crazyserver/moodle into MOODLE_29_STABLE 2016-04-06 08:57:04 +08:00
Eloy Lafuente (stronk7) 1f7044c5b9 MDL-52502 behat: clean 2 uses of method and fix upgrade.txt version 2016-04-06 00:27:23 +02:00
Eloy Lafuente (stronk7) dfaf8c5ad8 Merge branch 'wip-mdl-52502-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-04-06 00:25:16 +02:00
Eloy Lafuente (stronk7) 61b4aaab0a Merge branch 'MDL-53671-29' of git://github.com/dpalou/moodle into MOODLE_29_STABLE 2016-04-06 00:04:45 +02:00
Eloy Lafuente (stronk7) 9b59cfbb52 Merge branch 'MDL-53647_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-04-05 22:00:39 +02:00
Dan Poltawski 01d1a3300b Merge branch 'MDL-53000-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2016-04-05 14:34:14 +01:00
Dan Poltawski aa86e76af8 Merge branch 'MDL-53175-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2016-04-05 12:17:45 +01:00
Pau Ferrer Ocaña de14b56501 MDL-53461 assign: Fix intro images to be shown in the mobile app 2016-04-05 09:33:44 +02:00
Andrew Nicols ef19640b64 Merge branch 'MDL-53500-29' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE 2016-04-05 12:28:50 +08:00
Rajesh Taneja b2095de913 MDL-52502 behat: Ensure php web and cli version is same 2016-04-05 11:48:26 +08:00
Rajesh Taneja bc4ad1c39e MDL-52502 phpunit: Add php, db and os deatils 2016-04-05 11:48:25 +08:00
Eloy Lafuente (stronk7) d59e64b4f1 Merge branch 'MDL-53256-m29' of https://github.com/micaherne/moodle into MOODLE_29_STABLE 2016-04-04 19:03:02 +02:00
Dan Poltawski 5e01d61014 Merge branch 'wip-MDL-49861-29' of git://github.com/abgreeve/moodle into MOODLE_29_STABLE 2016-04-04 12:10:21 +01:00
Michael Aherne b2c13a1120 MDL-53256 cache: Prevent overwriting of cache config with invalid data 2016-04-04 08:55:39 +01:00
Andrew Nicols a39a67a436 Merge branch 'MDL-53661_29' of https://github.com/sam-moodle/moodle into MOODLE_29_STABLE 2016-04-04 12:26:21 +08:00
Andrew Nicols 27cc73e9e2 MDL-53115 mod_lesson: Remove unnecessary @javascript tags 2016-04-04 08:09:55 +08:00
Andrew Nicols 278ff79d84 MDL-53115 mod_choice: Remove unnecessary @javascript tags 2016-04-04 08:09:23 +08:00
Tim Hunt a8afcb2e4a MDL-53647 quiz summary: keep row class names in synch around headings 2016-04-02 13:23:21 +01:00
Dani Palou 64224cb840 MDL-53671 book: Return whole filepath in book_export_contents 2016-04-01 15:32:32 +02:00
AMOS bot b5f8d6b1a1 Automatically generated installer lang files 2016-04-01 00:05:04 +08:00
Dan Poltawski 4709d5dfcb weekly release 2.9.5+ 2016-03-31 14:06:34 +08:00
Dan Poltawski 9f724212ee Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-03-31 14:06:31 +08:00
Jay Jayswal c8d840561c MDL-53417 glossary: Glossary printer friendly link responsive 2016-03-31 13:59:39 +08:00
Dan Marsden 8f7dc60ad2 MDL-53500 report_outline: Allow parent role to view all activities.
Parents are not enrolled in the course, use $user to generate modinfo
for uservisible checks.
2016-03-31 13:39:03 +08:00
Sam Chaffee d0841d8c4a MDL-53661 mod_lti: Fix lti_prepare_type_for_save forcessl config 2016-03-30 18:30:16 -06:00
Adrian Greeve 66f2486da2 MDL-49861 mod_data: Behat step to test adding records.
Clicking 'Save and add another' should clear the form.
2016-03-30 16:36:40 +08:00
Adrian Greeve 64aaf5ff59 MDL-49861 mod_data: Save and add another button clears fields. 2016-03-30 16:36:21 +08:00
Juan Leyva d77bdd910c MDL-53175 filter: Fix text formatting for the book and page modules 2016-03-30 09:32:35 +01:00
Juan Leyva 7cd6eefe28 MDL-53175 file: Allow file_rewrite_pluginfile_urls to reverse 2016-03-30 09:32:34 +01:00
Eloy Lafuente (stronk7) 7eb83278bb Merge branch 'wip-mdl-49150-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-03-30 00:11:14 +02:00
Eloy Lafuente (stronk7) 616a362577 Merge branch 'MDL-52388-29' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE 2016-03-29 23:14:36 +02:00
AMOS bot b09ac036dc Automatically generated installer lang files 2016-03-30 00:04:36 +08:00
David Monllao 2e40d98863 Merge branch 'MDL-53356-29' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE 2016-03-29 15:57:25 +08:00
David Monllao cbadf3ac6b Merge branch 'MDL-53432-git-less-css-MOODLE_29_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_29_STABLE 2016-03-29 15:43:50 +08:00
David Monllao c67965f6d7 Merge branch 'wip-mdl-53434-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-03-29 14:24:11 +08:00
David Monllao f61e80bd87 Merge branch 'MDL-52646_29' of https://github.com/wjroes/moodle into MOODLE_29_STABLE 2016-03-29 12:59:03 +08:00
Dan Poltawski c055478914 Merge branch 'MDL-52976-29' of git://github.com/lameze/moodle into MOODLE_29_STABLE 2016-03-29 10:24:36 +08:00
AMOS bot d5ef4a3706 Automatically generated installer lang files 2016-03-29 00:04:35 +08:00
Brendan Heywood bbd073a455 MDL-53432 core: Treat derived css and js as binary files in git 2016-03-26 22:19:34 +11:00
Dan Poltawski 996a5331ab Merge branch 'wip-MDL-53538-29' of git://github.com/abgreeve/moodle into MOODLE_29_STABLE 2016-03-26 11:37:40 +08:00
Dan Poltawski 27891b6a0d Merge branch 'MDL-53562-forum-reply-re-MOODLE_29_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_29_STABLE 2016-03-26 10:36:39 +08:00
Dan Poltawski 5c65da3a2e MDL-53507 quiz: fix bad htmlid 2016-03-26 10:06:46 +08:00
Dan Poltawski bd9348c532 Merge branch 'MDL-53507_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-03-26 10:06:13 +08:00
Adrian Greeve 3668f28734 MDL-50795 atto: Pasting into atto removes background colour style.
Copying from one atto editor to another comes with a lot of style
information. This removes the color attributes which make the page
look ugly when competing with different themes.
2016-03-26 09:35:34 +08:00
AMOS bot a2e4255a34 Automatically generated installer lang files 2016-03-25 00:04:51 +08:00
Eloy Lafuente (stronk7) 1912e615f7 weekly release 2.9.5+ 2016-03-24 12:58:19 +01:00
Cameron Ball a1c33bf60f MDL-52388 output: Only stop displaying pager next link on last page
Thank you to Brenda Uga for working on this.
2016-03-24 17:20:07 +08:00
Simey Lameze c46180ef04 MDL-52976 core: replace all HTTP_RAW_POST_DATA usages
Backport of the MDL-52976.

This patch replace all usages of HTTP_RAW_POST_DATA that was deprecated on PHP 5.6 by
file_get_contents('php://input'). Only the TinyMCE library has not been updated.
2016-03-24 12:07:51 +08:00
Brendan Heywood 3529bdaa22 MDL-53356 admin: Fixed erroneous sectionerror when upgrade is needed 2016-03-23 16:27:17 +08:00
Dan Poltawski b40e2262d3 Merge branch 'MDL-52952-29-fix' of github.com:xow/moodle into MOODLE_29_STABLE 2016-03-23 12:08:08 +08:00
John Okely e2133abd7b MDL-52952 forms: Ignore autofill catching fields in form change checker 2016-03-23 11:55:56 +08:00
Dan Poltawski 10d22b709c Merge branch 'MDL-53383-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-03-23 08:31:54 +08:00
Tim Hunt 03edf12b9c MDL-53507 quiz editing: was possible to lose questions
If you dragged a question to the top of the quiz, it could
disappear. Several other cases of dragging questions to the
same place in sequence, but to a different page/section were
also failing, and have been fixed.
2016-03-22 23:05:04 +00:00
Marina Glancy 62a16f7ca0 MDL-45274 mod_feedback: show heading on non-respondents page 2016-03-22 23:05:52 +01:00
Eloy Lafuente (stronk7) f1fcb8e252 Merge branch 'MDL-53547_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-03-22 22:58:55 +01:00
Tim Hunt f7e12e6d14 MDL-53547 logstore_database: better DB driver handling in unit test 2016-03-22 06:46:35 +00:00
Adrian Greeve 922fa7a2f2 MDL-53538 mod_data: Unit test for data_get_advance_search_ids 2016-03-22 14:30:06 +08:00
Adrian Greeve 7055d71865 MDL-53538 mod_data: Show no records message instead of error.
When there are no records in the database module and a user
does an advanced search. Show a message that there are no entries
in the database.
2016-03-22 14:29:56 +08:00
Rajesh Taneja 2084e35009 MDL-49150 behat: Removed unnecessary @javascript tags 2016-03-22 13:57:59 +08:00
Dan Poltawski 069cea91f6 Merge branch 'MDL-52158-29' of https://github.com/xow/moodle into MOODLE_29_STABLE 2016-03-22 10:32:33 +08:00
Eloy Lafuente (stronk7) 06ecd3de42 Merge branch 'MDL-48307-29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2016-03-22 00:13:00 +01:00
Brendan Heywood acb947d98a MDL-53562 forum: Fixed missing forum subject Re: prefix 2016-03-22 09:26:49 +11:00
Eloy Lafuente (stronk7) d0f1a93260 Merge branch 'MDL-52978_m29' of git://github.com/markn86/moodle into MOODLE_29_STABLE 2016-03-21 23:07:34 +01:00
Willem Roes 2183bea2f8 MDL-52646 mod_scorm: fix missing launch_data for SCORM 2004 2016-03-21 09:03:30 +01:00
Dan Poltawski dda9cf907f Merge branch 'MOODLE_29_STABLE-MDL-53407-editing-css' of https://github.com/Dagefoerde/moodle into MOODLE_29_STABLE 2016-03-21 14:48:44 +08:00
Dan Poltawski f9b568088e Merge branch 'MDL-52952-29' of https://github.com/xow/moodle into MOODLE_29_STABLE 2016-03-21 14:44:20 +08:00
Dan Poltawski 256a84657b Merge branch 'MDL-53239_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-03-21 14:12:14 +08:00
James 4dde5d381e MDL-53383 navigation: Do not require $type in remove()
navigation_node_collection -> remove function broken when $type is null
2016-03-21 12:18:19 +08:00
Dan Poltawski bf56548d60 Merge branch 'MDL-53262-verp-confirm-from-support-MOODLE_29_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_29_STABLE 2016-03-21 11:37:37 +08:00
Dan Poltawski 7aee70bd08 Merge branch 'MDL-53489_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-03-21 11:02:05 +08:00
Jay Jayswal 67405a0d68 MDL-52158 auth: Improve recaptcha settings and help 2016-03-21 10:32:25 +08:00
Dan Poltawski b8b55ad3f4 Merge branch 'MDL-53548-m29' of https://github.com/sammarshallou/moodle into MOODLE_29_STABLE 2016-03-21 09:20:36 +08:00
Brendan Heywood bbf6676fb4 MDL-53262 inboundmessage: Fix inconsistent confirm From vs email body 2016-03-20 15:53:05 +11:00
sam marshall af22f8a159 MDL-53548 Accessibility: Block show/hide keyboard access broken 2016-03-18 13:49:04 +00:00
Grigory Baleevskiy 5ff9e45817 MDL-52978 core_lib: fixed wrong days showing for dates in datepicker 2016-03-18 12:31:21 +08:00
Eloy Lafuente (stronk7) 389ba35049 weekly release 2.9.5+ 2016-03-17 14:00:35 +01:00
Eloy Lafuente (stronk7) be454c9310 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-03-17 14:00:31 +01:00
David Monllao 4e285f7f45 MDL-53239 grader report: Add all names to error msg 2016-03-17 10:57:44 +08:00
Dan Poltawski ea26ec7524 Revert "MDL-52133 mod_assign: Pass userid param when saving grade"
This reverts commit 9ba2218a2a.
2016-03-17 09:30:52 +08:00
Andrew Nicols c0ed242820 Merge branch 'MDL-51828-29' of git://github.com/FMCorz/moodle into MOODLE_29_STABLE 2016-03-16 10:04:10 +08:00
Frederic Massart 352c88f166 MDL-51828 repository_wikimedia: Always use PNG for SVG files 2016-03-16 09:52:42 +08:00
Eloy Lafuente (stronk7) 263be92760 Merge branch 'MDL-53139-29' of https://github.com/dg711/moodle into MOODLE_29_STABLE 2016-03-16 00:19:11 +01:00
Eloy Lafuente (stronk7) 8489c94238 Merge branch 'MDL-53430-29' of git://github.com/merrill-oakland/moodle into MOODLE_29_STABLE 2016-03-16 00:05:41 +01:00
Eloy Lafuente (stronk7) feed83488b Merge branch 'mdl-53133-m29' of git://github.com/deraadt/moodle into MOODLE_29_STABLE 2016-03-15 23:53:56 +01:00
Russell Smith bfc7fd680e MDL-53323 profiling: Close session as early as possible. 2016-03-15 21:21:24 +01:00
Tim Hunt ba84a7e3f4 MDL-53489 quiz editing: fix display of long section headings 2016-03-15 18:36:21 +00:00
AMOS bot 14f7892048 Automatically generated installer lang files 2016-03-16 00:04:25 +08:00
Andrew Nicols 3648a75ef1 Merge branch 'MDL-53234-support-email-MOODLE_29_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_29_STABLE 2016-03-15 13:44:10 +08:00
Andrew Nicols 627cfe2398 Merge branch 'MDL-53351-29-lti-notice' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2016-03-15 12:50:00 +08:00
David Monllao 905626ba79 MDL-53176 grades: Fix upgrade version 2016-03-14 14:10:09 +08:00
David Monllao d67e511a9a Merge branch 'MDL-53176-29' of git://github.com/merrill-oakland/moodle into MOODLE_29_STABLE
Conflicts:
	version.php
2016-03-14 14:08:55 +08:00
Eloy Lafuente (stronk7) b0f0573e74 Moodle release 2.9.5 2016-03-12 00:38:01 +01:00
Rajesh Taneja e600e7c368 MDL-53434 behat: Improved exit status of parallel run
Exit status should contain pass/fail information
of each run it is executing. Every bit of status
will have information of pass/fail status of parallel
process
2016-03-11 21:08:26 +08:00
Rajesh Taneja 6967933d4a MDL-53434 behat: Added support for $CFG->behat_profiles
This config will be supported to avoid broken configuration
in future. As this is limited, we need will still use
->behat_config to set config values which can't be set by
behat_profiles
2016-03-11 21:08:10 +08:00
dg711 75a2731b32 MDL-53139 admin: case diff issue with email 2016-03-11 16:29:29 +05:30
John Okely 73e226c971 MDL-52952 forms: Fix chrome autofilling passwords again
In MDL-45772 a hack was introduced to some forms to stop browsers from
putting the user's password into password fields in forms unrelated to
logging in.

Chrome now no longer fills the user's password in the first password
field in the page. There now needs to be a plain text input above it
for the username too.
2016-03-11 10:33:56 +08:00
Eric Merrill b53f9ed5f1 MDL-53430 dml: Fix recordset_walk for additional parameters 2016-03-10 16:33:25 -05:00
Eric Merrill be7a01b355 MDL-53176 grades: Adding index to improve history search
Backport of MDL-50385
2016-03-10 12:00:45 -05:00
Eloy Lafuente (stronk7) 0fa77a0fb6 weekly release 2.9.4+ 2016-03-10 13:31:06 +01:00
Eloy Lafuente (stronk7) 4c4acce05c Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-03-10 13:31:02 +01:00
Jan C. Dageförde dbade23e87 MDL-53407 themes: Add CSS class editing only if appropriate
The CSS class `editing` should only be added if the user is in editing
mode AND she is allowed to edit the rendered page. `user_is_editing()`
achieves exactly this, without changing behaviour for the appropriate
pages.
2016-03-10 10:43:51 +01:00
Eloy Lafuente (stronk7) 214950de2a MDL-51167 tool_monitor: fix too strict condition & minor cleanup 2016-03-10 00:07:18 +01:00
Simey Lameze 82d0c0b521 MDL-50705 auth_db: apply standard cleaning to all fields
Also unit tests were added to cover the new clean_data() method.
2016-03-09 18:30:47 +01:00
Simey Lameze 54d6ee8c08 MDL-50705 core_user: introduce new fill_properties_cache()
Also the get_property_definition() was created to get the property without retrieve the whole definition cache and
    unit tests were created to tests those new methods.
2016-03-09 18:30:45 +01:00
Brendan Heywood 2e735a14f9 MDL-53234 admin: Fixed wrong default support email bug 2016-03-09 20:56:35 +11:00
Andrew Nicols b8c31d0786 MDL-49897 calendar: mktime => usergetmidnight 2016-03-09 13:18:41 +08:00
Michael de Raadt 9ba2218a2a MDL-52133 mod_assign: Pass userid param when saving grade 2016-03-09 15:30:44 +11:00
Simey Lameze 01b19e761f MDL-53031 mod_assign: add session check on assignment plugins management 2016-03-08 19:54:24 +01:00
AMOS bot 5c166e1f1a Automatically generated installer lang files 2016-03-09 00:04:30 +08:00
Jun Pataleta 094fddd00f MDL-52433 user: Remove unnecessary capability check 2016-03-08 12:24:27 +01:00
David Monllao d2acadec4c Merge branch 'wip-MDL-41648-29' of https://github.com/dg711/moodle into MOODLE_29_STABLE 2016-03-08 15:33:16 +08:00
Andrew Nicols c4bd64c245 Merge branch 'MDL-49897_29' of https://github.com/rushi963/moodle into MOODLE_29_STABLE 2016-03-08 15:27:31 +08:00
David Monllao 853cae5ebc Merge branch 'MDL-50218-29' of https://github.com/xow/moodle into MOODLE_29_STABLE 2016-03-08 14:42:01 +08:00
David Monllao 06e664ebbf Merge branch 'MDL-52068-29' of git://github.com/FMCorz/moodle into MOODLE_29_STABLE 2016-03-08 14:29:48 +08:00
Andrew Nicols a815974aab Merge branch 'MDL-53046-29' of https://github.com/xow/moodle into MOODLE_29_STABLE 2016-03-08 14:10:50 +08:00
David Monllao 2e24a0f873 Merge branch 'MDL-52984_29' of https://github.com/rushi963/moodle into MOODLE_29_STABLE 2016-03-08 14:04:40 +08:00
Andrew Nicols bce1ce2780 Merge branch 'MDL-53047-login-anchor-MOODLE_29_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_29_STABLE 2016-03-08 13:21:46 +08:00
Simey Lameze ff7bacf32b MDL-51167 tool_monitor: check course visibility and user capabilities 2016-03-08 03:09:37 +01:00
Andrew Nicols 1faf581711 Merge branch 'MDL-53210-29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2016-03-08 09:56:04 +08:00
Cameron Ball 4d6f159f68 MDL-52651 htmlpurifier: Append rel=noreferrer to links.
Thank you to Zachary Durber for originally working on this issue.
2016-03-08 02:08:10 +01:00
Andrew Nicols 17c67de63f Merge branch 'MDL-53291_29_ajax_fix' of https://github.com/BenKelada/moodle into MOODLE_29_STABLE 2016-03-08 07:43:13 +08:00
Krista Koivisto 3c069c16db MDL-52774 ajax: Require authentication when getting nav branch
When getting the navigation branch data through AJAX, require
login if forcelogin is set.
2016-03-08 00:39:09 +01:00
Juan Leyva fe5146d598 MDL-52901 mod_assign: Check due dates in external save_submission 2016-03-08 00:13:35 +01:00
David Monllao ad67b7eeea MDL-52378 singleview: Using is_disabled instead of is_locked 2016-03-07 23:03:50 +01:00
Travis Noll 5208032b23 MDL-52378 Singleview: Exclude Grade Attribute Permissions
Singleview users must have Manage Grade permission to modify the
Exclude grade attribute.
2016-03-07 23:03:30 +01:00
Juan Leyva 854e7b8ed0 MDL-52808 calendar: Do not return events for hidden activities 2016-03-07 22:35:56 +01:00
David Mudrák ead2dd9c16 MDL-52727 mod_data: Improve output of the form fields values
This issue mostly affects the search form fields. Submitted values for
these fields are typically obtained via optional_param() with
PARAM_NOTAGS specified as the parameter type - see parse_search_field()
methods. Such values themselves are not safe enough to be printed back
directly into the HTML as they might contain malicious code.

While working on the patch, some other places with weak protection were
detected and fixed.

In case of the itemid parameters, explicit clean_param() is added to
make sure we cast the value as an integer. That should make the s()
unnecessary but it was added anyway as an extra protection (just in case
the code flow changes or the parts of the code are re-used elsewhere).
2016-03-07 22:07:38 +01:00
Eloy Lafuente (stronk7) 2e89b87552 Merge branch 'MDL-53061-29' of git://github.com/danpoltawski/moodle into MOODLE_29_STABLE 2016-03-07 16:53:02 +01:00
dg711 77fc63989e MDL-41648 grade: Remove 'error' parameter in grading notification divs 2016-03-06 09:22:56 +05:30
David Mudrák dcf6ffd131 MDL-53351 lti: Do not throw PHP notice when deleting LTI instance
The typeid=0 is a valid and common value representing "Automatic, based
on launch URL" type. In that case, no record in the lti_types table is
found. Thence attempting to access its toolproxyid property used to
throw PHP notice.
2016-03-04 17:03:58 +01:00
Brendan Heywood d8a4ec8e68 MDL-53047 login: Fixed #anchor being lost after login process 2016-03-04 22:54:52 +11:00
John Okely e6cc9e7e7d MDL-50218 lti: Return empty grade when none exists 2016-03-04 16:27:26 +08:00
Dan Poltawski f60f03732e weekly release 2.9.4+ 2016-03-04 10:34:28 +08:00
Dan Poltawski 50d5283cff Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-03-04 10:34:26 +08:00
AMOS bot dc5f068009 Automatically generated installer lang files 2016-03-03 22:24:22 +08:00
AMOS bot 44f63e0f22 Automatically generated installer lang files 2016-03-03 22:24:21 +08:00
Dan Poltawski a1c1726249 MDL-53061 grunt: watch and various improvements
This is a backport of a number of commits from MDL-49817  which
in general are about simplifying and moving to standard 'grunt' things.
2016-03-03 11:45:33 +08:00
Ben Kelada dc1329ff4c MDL-53291 javascript: fix jquery ajax requests when data contains ??
jQuery ajax requests containing multiple '?' get replaced with a
string similar to jQuery152330039032_1231231, this is because it
is processing a stringified data object as jsonp and thinks its a url.
 workaround is to add contenttype
see https://github.com/jquery/jquery/issues/1799
2016-03-03 09:20:29 +11:00
AMOS bot d481dc01e4 Automatically generated installer lang files 2016-03-03 00:04:31 +08:00
Frederic Massart b02a001b6e MDL-52068 repository: Prevent JS errors due to unescaped lang strings 2016-03-02 15:35:16 +08:00
Andrew Nicols 89068f47cf Merge branch 'MDL-53214-29-category-feedback' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE 2016-03-02 14:50:04 +08:00
Cameron Ball f2d1cbfae4 MDL-53214 grades: Fix labels on feedback fields 2016-03-02 14:32:56 +08:00
Dan Poltawski 7db166d2e6 Merge branch 'MDL-52513_29' of https://github.com/rushi963/moodle into MOODLE_29_STABLE 2016-03-02 13:21:41 +08:00
Eloy Lafuente (stronk7) 9a04ae9665 Merge branch 'MDL-52763-29' of git://github.com/danpoltawski/moodle into MOODLE_29_STABLE 2016-03-01 21:40:03 +01:00
Eloy Lafuente (stronk7) aa683c28a8 Merge branch 'wip-mdl-53126-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-03-01 21:35:20 +01:00
Eloy Lafuente (stronk7) 68af175e84 Merge branch 'MDL-53200-29-enfix' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2016-03-01 21:25:30 +01:00
Rushikesh f386e713f1 MDL-49897 Calendar : Calendar day view showing past events 2016-03-01 20:13:07 +05:30
Rex Lorenzo 16d73f6748 MDL-53046 mod_lti: Should prefer site-wide configured key/secret 2016-03-01 14:41:18 +08:00
Dan Poltawski 8dacf05f4b Merge branch '29_MDL-53166' of https://github.com/eugeneventer/moodle-fixes into MOODLE_29_STABLE 2016-03-01 12:55:23 +08:00
Dan Poltawski 7bd521d654 Merge branch 'MDL-46424_29' of https://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-03-01 12:38:52 +08:00
Marina Glancy 463d31a871 MDL-44952 mod_feedback: set value for hidenoselect if disabled 2016-03-01 12:31:29 +08:00
Dan Poltawski b4af6f22fc Merge branch 'MDL-52928-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-03-01 11:38:09 +08:00
Andrew Nicols a72cb6b487 Merge branch 'MDL-53027-29' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE 2016-03-01 10:40:54 +08:00
Andrew Nicols fccf727fd8 Merge branch 'MDL-52936_29_STABLE' of https://github.com/marxjohnson/moodle into MOODLE_29_STABLE 2016-03-01 10:07:45 +08:00
Andrew Nicols 361b0abcc8 Merge branch 'MDL-53214-29' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE 2016-03-01 09:45:10 +08:00
Kevin Bruton 193982441d MDL-52568 core_cohort: added ability to return all cohorts in WS 2016-03-01 01:03:50 +01:00
Rushikesh 1116aded07 MDL-52984 Roles : Logs store newly created role's id 2016-02-29 14:57:20 +05:30
Dan Poltawski 05392ca9aa Merge branch 'MDL-44952-29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2016-02-29 16:34:26 +08:00
Andrew Nicols fc47609b41 Merge branch 'MDL-52965_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-02-29 15:22:12 +08:00
Andrew Nicols fb6d37154a Merge branch 'MDL-53249-29' of git://github.com/merrill-oakland/moodle into MOODLE_29_STABLE 2016-02-29 14:38:46 +08:00
Andrew Nicols 7c5ed224f7 Merge branch 'MDL-53206_29' of https://github.com/mr-russ/moodle into MOODLE_29_STABLE 2016-02-29 13:14:31 +08:00
Russell Smith 257b40c30c MDL-53206 caching: Ensure get_many and set_many dereference objects. 2016-02-29 16:00:08 +11:00
Dan Poltawski cad0fdaad7 Merge branch 'MDL-53154-29' of git://github.com/junpataleta/moodle into MOODLE_29_STABLE 2016-02-29 10:12:41 +08:00
Rushikesh aa3c00934c MDL-46424 Upload: Error message for a file exceeding maxsize 2016-02-29 08:58:27 +08:00
AMOS bot a2808a8e04 Automatically generated installer lang files 2016-02-28 00:04:26 +08:00
Marina Glancy aa7c4bed07 MDL-48307 mod_wiki: protect [edit] section link from nwiki parser 2016-02-26 13:27:54 +08:00
Eric Merrill 87de9d4eae MDL-53249 atto: Make sure all editors see end move event 2016-02-25 21:37:03 -05:00
Helen Foster b125674d97 MDL-53200 lang: Merge English strings from the en_fix language pack 2016-02-25 18:01:32 +01:00
Mark Johnson 1292a65011 MDL-52936 theme_bootstrapbase: Fix link hover bug on iOS 2016-02-25 11:55:50 +00:00
Davo Smith f87e97fa3a MDL-52965 medialib: fix preload attribute 2016-02-25 15:24:32 +08:00
Andrew Nicols 9a1c7bcce4 weekly release 2.9.4+ 2016-02-25 13:52:22 +08:00
Andrew Nicols 53512ca571 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-02-25 13:52:20 +08:00
David Balch 10a6b8a233 MDL-53027 calendar: Fix false empty result from calendar_get_events(). 2016-02-25 11:00:14 +08:00
Rajesh Taneja 040dd3a96e MDL-53126 behat: Fixed radio button in backup step
Rather than calling click and check on radio node
use radio form field to set value
2016-02-25 10:35:00 +08:00
AMOS bot 6579770fee Automatically generated installer lang files 2016-02-25 00:11:43 +08:00
Rushikesh 0986adb745 MDL-52513 Grading : Change in display message after publishing 2016-02-24 18:10:41 +05:30
Marina Glancy 99f7e407f0 MDL-53210 mod_feedback: fixes in check feedback access
1. show only uservisible feedbacks in block_feedback
2. nicer error message when user opens feedback on frontpage instead of from the mapped course
3. corrected cap check in view.php page before displaying link to complete.php
2016-02-24 13:33:26 +08:00
Cameron Ball 4193dd1a33 MDL-53214 grades: Ensure grader report correctly labels fields.
The editable fields for the grader report should have unique labels.
Previously category grade items were not being labelled with the
category name.
2016-02-24 10:45:03 +08:00
AMOS bot dbf9d4ca75 Automatically generated installer lang files 2016-02-24 00:04:41 +08:00
Dan Poltawski f82d9ae3eb Merge branch 'MDL-42460-29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2016-02-23 14:36:56 +00:00
Dan Poltawski 2b8d27b29d Merge branch 'MDL-52958_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-02-23 10:57:54 +00:00
Dan Poltawski d3a379512f Merge branch 'MDL-50312_29' of https://github.com/jinhofer/moodle into MOODLE_29_STABLE 2016-02-23 08:07:10 +00:00
Andrew Nicols 22af3705ce Merge branch 'MDL-49338_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-02-23 13:45:15 +08:00
Marina Glancy 0f94bbec5b MDL-44952 mod_feedback: validate required multichoice 2016-02-23 13:07:37 +08:00
Michael Milette 749e8dbe54 MDL-42460 mod_feedback: Fix markup validation 2016-02-23 12:56:32 +08:00
Davo Smith 104560bcb6 MDL-52371 theme_base: activity chooser - support long names 2016-02-23 11:43:12 +08:00
Kenny McCormack d95934f0ae MDL-52371 theme_bootstrapbase: activity chooser - support long names 2016-02-23 11:43:05 +08:00
Andrew Nicols 12dcda9f4b Merge branch 'MDL-52892-29_STABLE' of https://github.com/dg711/moodle into MOODLE_29_STABLE 2016-02-23 10:20:34 +08:00
Eloy Lafuente (stronk7) 3fe95f7007 Merge branch 'MDL-53065_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-02-22 23:01:22 +01:00
AMOS bot 5f14b92f65 Automatically generated installer lang files 2016-02-23 00:04:52 +08:00
Dan Poltawski b54a69b11f Merge branch 'MDL-44093-29-flowplayer' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2016-02-22 09:04:17 +00:00
Andrew Nicols 38980e2047 Merge branch 'wip-mdl-52970-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-02-22 15:24:01 +08:00
Eugene Venter e6e1210e81 MDL-53166 mod_forum: fix fatal error in backup phpunit test
when running mod_forum_testsuite mod_forum_testsuite
2016-02-22 13:49:32 +13:00
Tim Hunt a602c8023e MDL-53065 quiz redo question: avoid PHP notice in edge case
When selecting the variant of the new question, we need to add the
new question to the usage before trying to select a variant.

Also, we need to acutally use the selected variant number!
2016-02-19 12:11:20 +00:00
Tim Hunt 81ec4cb7d1 MDL-49338 quiz stats: preview urls wrong for question variants 2016-02-19 12:04:00 +00:00
Rajesh Taneja 631ee3b3e3 MDL-52970 behat: Wait for page to be ready after click
After click enusre to wait so text fields are not
use autosize
2016-02-19 15:25:47 +08:00
Rajesh Taneja dea76f367c MDL-52970 behat: Navigation step improvement
If navigation node to expand is a link then first
click on it and navigate to next page where it is
expanded, and then click on link within. This is
needed as some drivers click on link and don't open
the navigation node which are links
2016-02-19 15:25:46 +08:00
Rajesh Taneja f10ac6371f MDL-52970 behat: For single select only click event is enough 2016-02-19 15:25:46 +08:00
Rajesh Taneja 5a1269a629 MDL-52970 behat: don't set select value if already set
In FF 44.0, it fails to click on submit button if
select value is set to the original value
2016-02-19 15:25:45 +08:00
dg711 800b8ebcaf MDL-52892 message: users' pic overrides others
While listing the messages , the logged in users' profile pic used to
override over other users' pics .
2016-02-19 02:29:10 +05:30
David Mudrák b6ea64f734 MDL-44093 flowplayer: Provide information about source code location
Moodle ships with compiled binary code of the flowplayer. This patch
adds information about the source code location according to GNU GPLv3
section 6d and provides the original license for the code from
https://github.com/flowplayer/flash/blob/7c39fbe31ecddc/core/LICENSE.txt
2016-02-18 16:30:44 +01:00
Dan Poltawski cf0ffe26e6 weekly release 2.9.4+ 2016-02-18 09:14:19 +00:00
Dan Poltawski 1fb8c6312f Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-02-18 09:14:18 +00:00
Jun Pataleta 1fe1e78286 MDL-53154 course: Raise PHP time limit when deleting a course 2016-02-18 10:11:05 +08:00
Eloy Lafuente (stronk7) 8f21c6ea96 MDL-52964 Qtype: Small fixes to behat tests
This applies some small changes to proposed behat tests:

- Geting rid of the @javascript tag when it's not needed.
- Adding some missing @_switch_window tags.
- Fixing some scenario names, previously duplicated.
- Fixing some typos and whitespace.
2016-02-18 02:11:06 +01:00
M Kassaei bc2a4e90cd MDL-52964 Qtype: Add behat tests to core question types 2016-02-18 02:10:53 +01:00
Dan Poltawski 52e9efa347 MDL-52342 css: built 2016-02-17 07:34:51 +00:00
Dan Poltawski a69ee4e7d3 Merge branch 'MDL-52342-29-fix2' of github.com:andrewnicols/moodle into MOODLE_29_STABLE 2016-02-17 07:27:28 +00:00
Andrew Nicols e4ccccc799 MDL-52342 theme: Improve display of activity chooser 2016-02-17 15:20:10 +08:00
Marina Glancy ef126dbaff MDL-49807 mod_wiki: section detection regexp fix 2016-02-17 13:11:20 +08:00
David Monllao 11e6e6c8e3 Merge branch 'MDL-48015-29' of git://github.com/junpataleta/moodle into MOODLE_29_STABLE 2016-02-17 09:53:07 +08:00
Eloy Lafuente (stronk7) b33cd6d8ba Merge branch 'MDL-51852-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-02-17 02:04:25 +01:00
Eloy Lafuente (stronk7) 9bbbf76bae Merge branch 'MDL-29506-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-02-16 17:50:41 +01:00
Eloy Lafuente (stronk7) a003bc4710 Merge branch 'MDL-52997-email-threading-MOODLE_29_STABLE' of https://github.com/brendanheywood/moodle into MOODLE_29_STABLE 2016-02-16 17:12:00 +01:00
Eloy Lafuente (stronk7) 0bdea2767e Merge branch 'MDL-52814_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-02-16 16:49:38 +01:00
Dani Palou 15b9554a3b MDL-52993 wiki: Add unit tests for wiki_user_can_edit
Note: amended on integration to fix some comments.
2016-02-16 16:40:14 +01:00
Dani Palou 48426a041d MDL-52993 wiki: Fix wiki_user_can_edit for collab and separate groups 2016-02-16 16:39:11 +01:00
Dan Poltawski f08c3486a7 Merge branch 'MDL-52862_29' of https://github.com/juancs/moodle into MOODLE_29_STABLE 2016-02-16 15:18:49 +00:00
Dan Poltawski c10236355a Merge branch 'MDL-53012-m29' of https://github.com/sammarshallou/moodle into MOODLE_29_STABLE 2016-02-16 10:45:01 +00:00
Dan Poltawski cdd4d84eda Merge branch 'MDL-52879_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-02-16 10:26:02 +00:00
Dan Poltawski 6d7a12e085 Merge branch 'MDL-49612-29' of git://github.com/dpalou/moodle into MOODLE_29_STABLE 2016-02-16 09:30:14 +00:00
Andrew Nicols 4e70e41424 MDL-52342 theme: Correct selector for section title 2016-02-16 09:18:18 +00:00
David Monllao 1401015347 Merge branch 'MDL-51117-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-02-16 13:27:36 +08:00
Eloy Lafuente (stronk7) ad1485c866 Merge branch 'MDL-52511-29' of git://github.com/danpoltawski/moodle into MOODLE_29_STABLE 2016-02-16 02:00:56 +01:00
David Monllao 56044641b0 MDL-52217 repository: Fix upgrade versions 2016-02-16 05:59:25 +08:00
David Monllao d3371a8778 Merge branch 'MDL-52217-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-02-16 05:57:56 +08:00
David Monllao a111eada22 Merge branch 'MDL-51580_29' of git://github.com/stronk7/moodle into MOODLE_29_STABLE 2016-02-16 05:06:38 +08:00
sam marshall 232ad11f86 MDL-53012 Behat: Add step to run scheduled task 2016-02-15 17:39:13 +00:00
Dan Poltawski 533ce6d38d Merge branch 'MDL-53039-29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2016-02-15 15:33:27 +00:00
Dan Poltawski 4a6ce8ace3 Merge branch 'MDL-52342-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-02-15 13:28:18 +00:00
Dan Poltawski d037aee9d3 Merge branch 'MDL-49146_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-02-15 12:13:34 +00:00
Dan Poltawski 9bb6b38dea Merge branch 'wip_MDL-53029_m29' of git://github.com/gjb2048/moodle into MOODLE_29_STABLE 2016-02-15 11:07:36 +00:00
Dan Poltawski c0b2fb25c6 Merge branch 'MDL-44626-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-02-15 10:36:22 +00:00
Andrew Nicols 98b518c17a MDL-52217 repository: prepare_file should use per-request directory
The repository API defaults has a function, prepare_file, which is
responsible for creating a unique file to be used during the current
request.

This is usually used in the repository's get_file() function to store the
file before it is used elsewhere in the API to save the file to the
filestorage API.
It is also sometimes used to temporarily store credentials for the lifetime
of the session.

In all cases, this file is only expected to exist for the duration of the
session.

Switching to use of a per-request directory using make_request_directory()
ensures that the tempdir does not grow without control.

This commit also adds an upgrade step to remove all old temp directories
created by any repository currently installed.
2016-02-15 15:55:51 +08:00
David Monllao 7b04c158a0 Merge branch 'wip-MDL-52566-MOODLE_29_STABLE-2' of https://github.com/cdsmith-umn/moodle into MOODLE_29_STABLE 2016-02-15 15:18:24 +08:00
David Monllao 456c92917f Merge branch 'MDL-49807-29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2016-02-15 15:12:23 +08:00
Juan Segarra Montesinos e86d1aacc0 MDL-52862 mod_forum: format non HTML messages in search results
Override messageformat to FORMAT_HTML before calling forum_print_post
2016-02-15 07:53:42 +01:00
Andrew Nicols 69b8e578ea MDL-29506 forum: Add tests for encode_content_links 2016-02-15 08:09:10 +08:00
Rushikesh 3241582038 MDL-29506 forum: Fix use of ampersand in backup parent links 2016-02-15 08:09:10 +08:00
AMOS bot 325348beda Automatically generated installer lang files 2016-02-13 00:04:36 +08:00
Eloy Lafuente (stronk7) f5bd067fbe MDL-51580 environment: 3.1 requirements added
Only important change is that Moodle 2.7 installed is
required to be able to upgrade to 3.1. See the issue
for opinions, votes and agreed outcomes.
2016-02-11 16:09:09 +01:00
Brendan Heywood d3a744ddf1 MDL-52997 forum: Add more robust threading email headers 2016-02-11 20:38:20 +11:00
David Monllao d6b44eeea2 weekly release 2.9.4+ 2016-02-11 13:58:53 +08:00
David Monllao e090357eb0 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-02-11 13:58:51 +08:00
Andrew Nicols 063642c4cb MDL-44626 files: Show the PHP max upload size instead of 'unlimited'
Even when a user has the appropriate capability to upload any sized files,
they are still restricted to the PHP post_max_size, and upload_max_filesize
values.

Rather than showing a value of "Unlimited', we should always restrict to
this value.
2016-02-11 10:56:42 +08:00
Andrew Nicols c735752066 MDL-44626 repository: Correct error message when uploading large files 2016-02-11 10:56:42 +08:00
Andrew Nicols 0bdb44d34f MDL-51117 JavaScript: Convert alert to M.core.alert in dndupload 2016-02-11 08:44:47 +08:00
Andrew Nicols 4275fb0ebe MDL-52342 theme: Reduce specificity of selector
These selectors were introduced to fix a real issue (highlighted by behat with
Chromedriver) whereby the 'Show section foo' link was partially covered by
another layer.

The fix in that issue was too broad and applied to all content > div areas,
which had some unforseen effects.

Since the original issue only affected activity instances, and sections (and
not content > div regions), I've removed this from the original patch.
2016-02-11 08:28:38 +08:00
Gareth J Barnard 2afba12004 MDL-53029 mod_book: Hidden chapter has markup in alt and title attrs. 2016-02-10 18:02:06 +00:00
Petr Skoda e2f8826fa8 MDL-52511 dml: add support for PostgreSQL 9.5
The default definition behaviour has changed for some int values.
2016-02-10 09:45:53 +00:00
Tim Hunt 8d071293ac MDL-52814 questions: Show extra info in the outcomes area not info
Currently the only use is the quiz Redo question button, and that would
be much better placed in the feedback area, not least for langages where
the button label needs to be longer.
2016-02-10 08:47:49 +00:00
Marina Glancy d1c9a47b04 MDL-49807 mod_wiki: correctly form toc and sections for atto 2016-02-10 13:32:05 +08:00
Andrew Nicols 4339f877d4 MDL-52930 forum: Fix random test failure caused by passing of time 2016-02-10 12:24:45 +08:00
David Monllao b292fa181c Merge branch 'MDL-52766-29-mnet-url-length' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2016-02-10 08:55:33 +08:00
Tim Hunt 93ea68f50d MDL-52879 quiz editing: allow removal of the last question in a quiz
Even though you are not normally allowed to remove the last question
in a section.
2016-02-09 21:49:48 +00:00
AMOS bot ac17792858 Automatically generated installer lang files 2016-02-10 00:04:21 +08:00
Michael Hughes 142c8f08c3 MDL-52763 Assignment: Display Participant Number
Display participant number when user holds mod/assign:viewblinddetails capability.

Backport of MDL-52270
2016-02-09 15:59:38 +00:00
Davo Smith 0a127f2b4e MDL-49620 availability: plugins can have global settings 2016-02-09 10:34:59 +00:00
Juan Leyva 7d3472a753 MDL-53000 mod_assign: Add missing get_file_areas in editpdf subplugin 2016-02-09 11:34:30 +01:00
David Monllao 634d3fd207 Merge branch 'MDL-52930-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-02-09 18:07:07 +08:00
David Monllao 81711b63e4 Merge branch 'MDL-52902-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2016-02-09 16:42:13 +08:00
Marina Glancy fd7218a4c1 MDL-53039 rss: allow guest access to front page forum 2016-02-09 15:56:04 +08:00
Andrew Nicols b28c953839 MDL-52928 message: Correct contact fetching in recent conversations 2016-02-09 13:39:55 +08:00
Jun Pataleta 1e33a8a53b MDL-48015 grade: Fix the display of grade categories 2016-02-09 13:33:14 +08:00
Andrew Nicols 0c34179b52 MDL-51852 mod_forum: Respect timed discussions in emails 2016-02-09 08:37:44 +08:00
Andrew Nicols 642660aa35 MDL-52339 question: Fix question attempt removal for MySQL
Derived table support was altered in MySQL 5.7 changing the way in which
DELETE FROM works in some cases.

This change modifies the way in which deletion occurs by selecting all IDs
and batching them into groups of 1000.
2016-02-09 00:45:58 +01:00
Eloy Lafuente (stronk7) 75f61371a0 Merge branch 'MDL-52938-29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2016-02-09 00:30:57 +01:00
Eloy Lafuente (stronk7) f78700dc47 Merge branch 'MDL-52975-29-mnet-context' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2016-02-08 22:58:12 +01:00
Eloy Lafuente (stronk7) 20d0c2e8ce Merge branch 'MDL-52981-m29' of https://github.com/sammarshallou/moodle into MOODLE_29_STABLE 2016-02-08 22:55:24 +01:00
Eloy Lafuente (stronk7) 9981108170 Merge branch 'MDL-51075_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-02-08 22:45:10 +01:00
Eloy Lafuente (stronk7) d0991e9f02 Merge branch 'MDL-50310-29-random-glossary' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2016-02-08 22:34:39 +01:00
Dan Poltawski 870953541c Merge branch 'MDL-48778-29' of git://github.com/lameze/moodle into MOODLE_29_STABLE 2016-02-08 17:15:45 +00:00
Eloy Lafuente (stronk7) 25c6437296 Merge branch 'MDL-52983_29' of git://github.com/aolley/moodle into MOODLE_29_STABLE 2016-02-08 13:05:46 +01:00
Simey Lameze 5ff2c7d8a6 MDL-48778 mod_assign: behat tests for group submission 2016-02-08 14:23:50 +08:00
Eric Merrill 6ca893ecb2 MDL-48778 assign: Use proper latest attempt for quickgrading prechecks
The code that stored lastmodified in gradingtable used a different
method to produce it than the processor used to generate the check
value. Fix that and also check that the attempt number has not changed.
2016-02-08 14:23:49 +08:00
David Monllao 9876fc13e1 Merge branch 'MDL-50115-29' of git://github.com/danpoltawski/moodle into MOODLE_29_STABLE 2016-02-08 14:11:45 +08:00
Adam Olley 26685f13a0 MDL-52983 excel output: avoid single quote on end of sheet name
This change resolves a problem where a long sheet name, which gets
trimmed down with substr($name, 0, 31), could result in a sheet name
with a single quote on the end because the quote removal was done before
the substr.
2016-02-08 15:18:00 +10:30
David Monllao 5f90d5f42d Merge branch 'MDL-51723-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-02-08 09:03:51 +08:00
Tim Hunt 12b9fad2ed MDL-49146 single-activity course format: key activity must be visible
With a single-activity course, visibility to students is controlled by
course visibility. There is no sense in having the key activity not
visible to students, and, if you did, the symptoms were almost
incomprehensible. It was very hard to work out what you had done wrong.
2016-02-06 14:59:12 +00:00
AMOS bot ec75674961 Automatically generated installer lang files 2016-02-06 00:04:25 +08:00
Andrew Nicols e66281a8b0 MDL-52930 mod_forum: Add get_unmailed_posts tests 2016-02-05 14:41:09 +08:00
Josh Marshall a9745eb95a MDL-52930 forum: Correct get_unmailed_posts logic 2016-02-05 14:41:08 +08:00
David Monllao 92992280ad MDL-52958 medialib: Allow vimeo fullscreen using links
All credit to Henrik Sune Pedersen.
2016-02-05 10:19:41 +08:00
David Monllao a84dfd422a MDL-51075 filter_glossary: Fix popup position when no popups
Thanks to Andrew Nicols for cleaning my eyes.
2016-02-05 09:28:23 +08:00
David Mudrák 211fedbad5 MDL-50310 glossary: Fix restore of random glossary entry block
When restoring the random glossary entry block, we need to check that
the associated glossary has also been included in the backup and is
being restored. If not, we must invalidate the block configuration.

Before this patch, the block configuration was not invalidated.

Additionally, as a result of MDL-20131, the block configuration also
contains the course id of the associated glossary (which by the way does
not seem to be a wise choice, but I may be missing something). So we
need to remap this course id as well to avoid mismatch.
2016-02-05 00:09:20 +01:00
David Mudrák bc3bf84afd MDL-52975 mnet: Set system context on the MNet SSO landing page
Without the context being explicitly set, debugging warning can be
displayed in certain rare situations.
2016-02-04 17:16:33 +01:00
David Mudrák 89d1a3f83b MDL-52766 mnet: Support MNet peer URLs longer than 64 characters
The commonName in SSL certificate is limited to 64 characters as per
RFC 5280 (https://www.ietf.org/rfc/rfc5280.txt). We respect that limit
when generating the CN attribute from the site's $CFG->wwwroot. But then
we did not respect it when comparing the common name with the peer's
URL so the certificate was not considered valid.
2016-02-04 17:12:01 +01:00
Dan Poltawski 5a906c5727 MDL-50115 grunt: add missing jshint configuration
The gruntfile isn't a normal browser environment
2016-02-04 12:04:53 +00:00
Dan Poltawski 8127f39eee MDL-50115 grunt: provide a --root option to set base path
Windows users are not able to run grunt on a subpath due to platform
restrictions. So we provide this option to provide a workaround for that.

Thanks to Ty Delean who proposed this idea.
2016-02-04 12:04:53 +00:00
David Monllao 80b09028d1 weekly release 2.9.4+ 2016-02-04 14:30:10 +08:00
David Monllao f8a00db3b2 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-02-04 14:30:08 +08:00
AMOS bot 070f816bc6 Automatically generated installer lang files 2016-02-04 00:04:31 +08:00
sam marshall 94d07f8ad9 MDL-52981 Unit tests: Reset global after test 2016-02-03 10:30:42 +00:00
David Monllao fec7104bec Merge branch 'MDL-52899_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-02-03 13:45:07 +08:00
David Monllao 008fd8869c Merge branch 'MDL-52873-29-modgradeid' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2016-02-02 12:12:59 +08:00
Marina Glancy b0ab180666 MDL-52938 mod_forum: check global setting to track forum posts 2016-02-02 10:54:51 +08:00
Dan Poltawski f9d8799390 Merge branch 'wip-mdl-52932-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-02-01 10:27:24 +00:00
Dan Poltawski fb52b37e38 Merge branch 'MDL-52940_m29' of git://github.com/markn86/moodle into MOODLE_29_STABLE 2016-02-01 09:49:25 +00:00
David Monllao 41f75a63da Merge branch 'MDL-51704-29' of git://github.com/dpalou/moodle into MOODLE_29_STABLE 2016-02-01 17:21:08 +08:00
David Monllao 55631fe3d4 Merge branch 'MDL-52261_29_file_not_found' of git://github.com/BenKelada/moodle into MOODLE_29_STABLE 2016-02-01 13:56:26 +08:00
David Monllao 3ab2388c5a Merge branch 'MDL-52913_29_STABLE' of git://github.com/marxjohnson/moodle into MOODLE_29_STABLE 2016-02-01 13:46:47 +08:00
Mark Nelson ff2e424d07 MDL-52940 core_backup: prevent always displaying logs 2016-02-01 12:45:11 +08:00
David Monllao 36fe93a53a Merge branch 'wip-mdl-52837' of git://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-02-01 11:38:02 +08:00
David Monllao 1d69dc53ef Merge branch 'MDL-52831-29-emptynames' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2016-02-01 11:31:55 +08:00
Andrew Nicols 2dcf1dabc3 MDL-51723 enrol_ldap: Normalise user objectclass in dn 2016-02-01 10:29:24 +08:00
Rajesh Taneja afeffc0a74 MDL-52932 behat: Restart session if it fails because of some reason 2016-02-01 09:33:01 +08:00
jinhofer c3cd93ddf1 MDL-50312 grade/report/grader: Fixed remaining issue
MDL-49764 fixed the appearance of user cells. However, the window
resize event was still incorrect. This is a fix for the window
resize event for ALL IE versions.
2016-01-29 12:22:22 -06:00
Mark Johnson ba9e80c7c7 MDL-52913 behat: Abort database transactions on exception. 2016-01-29 12:00:15 +00:00
David Monllao 01478c3ae7 weekly release 2.9.4+ 2016-01-29 14:36:57 +08:00
David Monllao b2f5f27afa Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-01-29 14:36:55 +08:00
David Monllao 9f16ba4a76 MDL-52825 atto: Listen to gesturemovestart to discard some events 2016-01-28 12:25:16 +08:00
AMOS bot e54c30d48d Automatically generated installer lang files 2016-01-28 00:04:38 +08:00
Juan Leyva 22b696c5c7 MDL-52902 webservice: Send CORS header before params validation 2016-01-27 10:27:50 +01:00
Rajesh Taneja 75832b8976 MDL-52837 behat: Update mink extension to support Selenium 2.48.x 2016-01-27 17:04:12 +08:00
Eloy Lafuente (stronk7) 2e4b4ac7c2 Merge branch 'MDL-29817_29' of https://github.com/rushi963/moodle into MOODLE_29_STABLE 2016-01-27 00:55:02 +01:00
Eloy Lafuente (stronk7) 0ce1d907e3 MDL-52567 Core: amend existing test to new counting rules 2016-01-27 00:38:32 +01:00
Eloy Lafuente (stronk7) a0d4ebd22a Merge branch 'MDL-52567_M29' of https://github.com/nadavkav/moodle into MOODLE_29_STABLE 2016-01-27 00:37:54 +01:00
Eloy Lafuente (stronk7) 86f762d976 MDL-37739 mod_wiki: test headings being wikilinks (toc and content) 2016-01-27 00:11:22 +01:00
Luca Bösch b5f3ff575b MDL-37739 mod_wiki: Wiki ToC header href remove square double brackets.
When H1, H2 and H3 links in wiki act themselves as hyperlinks, they
were displayed in double brackets. This patch removes [[ and ]] out of
the table of content displayed header hyperlinks.
2016-01-26 23:19:19 +01:00
Dani Palou 900f56bcf2 MDL-51704 survey: Fix display problems in report page 2016-01-26 14:07:12 +01:00
Tim Hunt 86560bedd1 MDL-52899 behat: make PAGE_READY_JS more robust 2016-01-26 11:23:51 +00:00
Dan Poltawski 14dd6d9dcf Merge branch 'MDL-48953_m29v4' of https://github.com/sbourget/moodle into MOODLE_29_STABLE 2016-01-26 11:10:16 +00:00
Rushikesh 7e0eef76d4 MDL-25864 Blog: Confirmation dialog before unregistering 2016-01-26 10:56:25 +00:00
David Monllao 76d2a91004 Merge branch 'MDL-52459-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2016-01-26 18:23:25 +08:00
Dani Palou eea379ed55 MDL-49612 forum: Fix some external_value creation in params declaration 2016-01-26 08:58:09 +01:00
Eloy Lafuente (stronk7) 2b6815b7dd Merge branch 'wip-mdl-52839-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-01-26 00:40:59 +01:00
Eloy Lafuente (stronk7) 66b1d84058 Merge branch 'MDL-52843-29-paramsignup' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2016-01-26 00:38:35 +01:00
AMOS bot f251776434 Automatically generated installer lang files 2016-01-26 00:04:20 +08:00
Dan Poltawski 93c63eefb4 Merge branch 'MDL-52791_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-01-25 14:27:04 +00:00
Dan Poltawski f19e2ee750 Merge branch 'MDL-52835-m29' of git://github.com/deraadt/moodle into MOODLE_29_STABLE 2016-01-25 14:14:53 +00:00
Dan Poltawski d7bb11f148 Merge branch 'MDL-51702_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-01-25 10:29:59 +00:00
Dan Poltawski 95dd0adc3b Merge branch 'MDL-52825_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-01-25 10:26:00 +00:00
David Monllao 117e9a638c Merge branch 'MDL-52682-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-01-25 15:39:38 +08:00
David Monllao 3a8736831c Merge branch 'MDL-52683-29' of git://github.com/s-cenni/moodle into MOODLE_29_STABLE 2016-01-25 15:32:46 +08:00
David Monllao ba120a362c Merge branch 'wip-mdl-52799-m29' of git://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-01-25 14:39:55 +08:00
David Monllao 0935b7f057 Merge branch 'MDL-31635-29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2016-01-25 12:34:08 +08:00
Marina Glancy 51c311b333 MDL-31635 completion: do not show % for the grade
Also show grades with the configured number of decimal points
2016-01-25 10:23:46 +08:00
AMOS bot 55f6a330ba Automatically generated installer lang files 2016-01-25 00:04:24 +08:00
Nadav Kavalerchik 81e264eb35 MDL-52567 Core: remove quotation marks, for proper word count 2016-01-24 00:49:44 +02:00
AMOS bot 4ad98ddd26 Automatically generated installer lang files 2016-01-23 00:04:32 +08:00
Clement Smith 32830571c6 MDL-52566 mod/assign: Fix group submission draft records
When group assignments are submitted by the first student in a group,
the logic that saves the submission is not creating a draft
assignment record in mdl_assign_submission. This leads to problems
when other functions are used that depend on these records, such as
marking workflow. This fixes the issue and correctly creates
draft assignment submission records for the non-submitting students
in the group.
2016-01-22 10:00:57 -06:00
David Mudrák f16385e051 MDL-52873 forms: Generate unique id attributes for modgrade elements
The previous method of generating the id attribute of the elements
within the modgrade group did not take the name of the modgrade field
into account. So if there were multiple fields of the modgrade type
added into a form (not a common case yet still valid), elements created
within the group were assigned same id attributes.

The patch introduces a new method for generating the id attribute of
modgrade elements. The new method takes the name of the modgrade group
into account and returns the id in the format similar to the default one
returned by HTML_QuickForm_element::_generateId().

The patch changes the generated id attribute. Apart from the
block_activity_results' behat feature files, not other places seem to
rely on the exact value.
2016-01-22 14:19:57 +01:00
Andrew Nicols 54fdc12876 MDL-52682 mod_forum: Correct redirect URL when marking posts as read 2016-01-22 08:04:33 +08:00
Michael de Raadt 0168e431aa MDL-52835 mod_data: Correct MIME type for JS template 2016-01-22 10:23:26 +11:00
Rushikesh c45ef8bc2f MDL-29817 Form : advcheckbox allows attributes even without group key 2016-01-21 22:13:27 +05:30
Sara Cenni b68dc98398 MDL-52683 mod_scorm: Fix for Last completed attempt error with Oracle 2016-01-21 17:18:35 +01:00
Rajesh Taneja 7db80d7c10 MDL-52839 behat: Fixed xpath and wait to ensure element is visible 2016-01-21 14:36:54 +08:00
Andrew Nicols aa0b28c5e5 weekly release 2.9.4+ 2016-01-21 13:43:41 +08:00
Andrew Nicols 3804b919c0 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-01-21 13:43:38 +08:00
David Monllao e7e317a5fc MDL-51702 blocks: Allow permission overrides in dashboard 2016-01-21 08:57:35 +08:00
David Mudrák 7802d9187b MDL-52843 users: Fix the PARAM type of the name fields in signup form
If editing the profile, the useredit_shared_definition() function set
the type of all name fields to PARAM_NOTAGS. This patch sets that type
consistently in the user signup form, too.
2016-01-20 11:29:01 +01:00
Eloy Lafuente (stronk7) 8f76e5565b MDL-50083 mod_assign: protect code against not set flags
Yes could have used !empty() but for some reason found
the isset() && condition more clear. Tired brain, surely.
2016-01-20 10:06:53 +08:00
Andrew Nicols 2cf3857c74 Merge branch 'MDL-52435_29' of https://github.com/jinhofer/moodle into MOODLE_29_STABLE 2016-01-20 09:53:54 +08:00
Eloy Lafuente (stronk7) 9d9d8856b8 Merge branch 'm29_MDL-50083' of https://github.com/greg-or/moodle-mod_assign into MOODLE_29_STABLE 2016-01-20 01:36:45 +01:00
jinhofer 8d5d3539f5 MDL-52435 mod/assign: Added and move plagiarism links
Backport of MDL-51693 and MDL-51706
2016-01-19 18:17:59 -06:00
Greg Faller 14156fca7d MDL-50083 mod_assign: unlock submission when adding attempt 2016-01-20 09:28:26 +10:30
David Mudrák 9a27d73d5d MDL-52831 users: Do not delete Mr. and Mrs. Whitespace accounts
Due to imperfect validation of the user registration and profile forms,
we allowed for firstname and lastname be just a whitespace. On MySQL,
such a whitespace is not significant for VARCHAR comparison so these
otherwise valid accounts could be silently deleted.

The patch makes sure that at least one of the checked fields is a real
empty string before deleting such account.
2016-01-19 21:43:08 +01:00
David Mudrák 4c3f695e58 MDL-52831 users: Automatically strip whitespace from name fields
This change prevents from registering and/or saving the profile of a
user with the whitespace instead of the required name.

Additionally, there is accessibility improvement for better error labels
in case of missing values (copied over from signup_form).
2016-01-19 21:43:08 +01:00
Rajesh Taneja ce91756a53 MDL-52721 behat: Exclude links in moodle while finding tests
Parallel run create links within moodle
so avoid searching for tests within links
2016-01-19 14:35:38 +00:00
Dan Poltawski a6218b45e2 Merge branch 'MDL-51123-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2016-01-19 11:01:49 +00:00
Dan Poltawski 03a86c6d0b Merge branch 'MDL-51715_29_invalidweights' of https://github.com/colin-umn/moodle into MOODLE_29_STABLE 2016-01-19 10:40:29 +00:00
David Monllao 2c5bd27b75 MDL-52825 atto: Ignore out of bounds event targets 2016-01-19 15:41:47 +08:00
Andrew Nicols 3541d50ecc Merge branch 'MDL-52673-29' of https://github.com/pauln/moodle into MOODLE_29_STABLE 2016-01-19 11:03:51 +08:00
Rushikesh a34afb637e MDL-52519 Idap tests: use consistent var name 2016-01-19 10:20:49 +08:00
Tim Hunt 71b091caf8 MDL-52784 quiz: unused param in quiz_get_combined_reviewoptions calls 2016-01-19 09:05:56 +08:00
Eloy Lafuente (stronk7) 42c2ceb9ee Merge branch 'MDL-52615_M29' of https://github.com/nadavkav/moodle into MOODLE_29_STABLE 2016-01-19 00:29:46 +01:00
Eloy Lafuente (stronk7) 2362ba8beb Merge branch 'MDL-52693-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-01-18 21:44:43 +01:00
Tim Hunt be38a2b3e8 MDL-52791 quiz editing: handle unknown question types 2016-01-18 17:37:52 +00:00
AMOS bot e4ebb67b46 Automatically generated installer lang files 2016-01-19 00:04:54 +08:00
Dan Poltawski 1b10b7b979 Merge branch 'MDL-52750_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2016-01-18 15:54:46 +00:00
Dan Poltawski 5865d62c35 Merge branch 'wip-mdl-52721-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-01-18 14:39:43 +00:00
Dan Poltawski b7e1c7b48c Merge branch 'MDL-52218_m29_alt' of git://github.com/markn86/moodle into MOODLE_29_STABLE 2016-01-18 14:04:06 +00:00
Dan Poltawski f97d3d2b1b Merge branch 'MDL-52486-29' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE 2016-01-18 11:19:32 +00:00
Rajesh Taneja 6587d7eab1 MDL-52799 unittest: Removed empty if statement 2016-01-18 15:48:22 +08:00
Andrew Nicols bbb76a0ef5 Merge branch 'MDL-45265-29' of git://github.com/danpoltawski/moodle into MOODLE_29_STABLE 2016-01-18 15:19:39 +08:00
Andrew Nicols 85fabe0539 Merge branch 'MDL-52608-29' of https://github.com/xow/moodle into MOODLE_29_STABLE 2016-01-18 14:49:15 +08:00
Andrew Nicols 5dc26908e3 Merge branch 'MDL-52573-29' of git://github.com/danpoltawski/moodle into MOODLE_29_STABLE 2016-01-18 14:44:27 +08:00
Rajesh Taneja 834bce7f5c MDL-52799 phpunit: Truncate records for brokedmysql not empty. 2016-01-18 14:37:56 +08:00
Andrew Nicols 1b829e9ea5 MDL-50915 mod_lesson: Remove js dependencies from behat tests 2016-01-18 10:57:10 +08:00
Andrew Nicols e9ec2b17aa Merge branch 'MDL-50915_m29v5' of https://github.com/sbourget/moodle into MOODLE_29_STABLE 2016-01-18 10:55:34 +08:00
Rajesh Taneja f0121062ef MDL-52721 unittest: Exclude tests in vendor and node_modules 2016-01-18 10:26:15 +08:00
Stephen Bourget 8520046ad2 MDL-48953 choice: Improve chart labels 2016-01-15 13:43:47 -05:00
Tim Hunt db60642ced MDL-52750 quiz reviewQ/comment: add page title & student name 2016-01-15 11:11:11 +00:00
Dan Poltawski 36a826affb MDL-52573 report_grader: only check cap of installed plugins
Previously we were linking to gradebook plugins regardless of whether
they were installed. This should be fixed properly in MDL-52678.
2016-01-14 10:26:13 +00:00
Dan Poltawski 13c88d9b8d weekly release 2.9.4+ 2016-01-14 10:10:00 +00:00
Dan Poltawski bbb2f117c3 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2016-01-14 10:09:58 +00:00
Mark Nelson c99d5f6492 MDL-52218 gradereport_grader: added behat test for switching views 2016-01-13 15:29:23 +08:00
Mark Nelson 5e92d726cb MDL-52218 gradereport_grader: fixed 'grade:viewhidden' related errors
There were two main reasons why there were PHP errors.

1) We were not passing variables as references.
2) When we were restricting the number of items shown in
   the report we were not collecting all of the dependencies
   which were required when a user did *not* have the
   capability 'moodle/grade:viewhidden'. This would cause
   an undefined offset error due to the index missing in
   the dependency array.

This also meant that a user without the capability 'moodle/grade:viewhidden'
could view the course total without hidden items being taken into account
if they were not being displayed. To resolve this we now pass all the grades
and grade items when the user does not have the capability - which also solves
the PHP errors listed above.
2016-01-13 15:29:23 +08:00
Andrew Nicols 8fce1ed876 MDL-43620 mod_chat: Whitespace fix 2016-01-13 10:20:45 +08:00
Andrew Nicols 97921bc354 Merge branch 'MDL-50829-29' of git://github.com/danpoltawski/moodle into MOODLE_29_STABLE 2016-01-13 09:58:50 +08:00
Andrew Nicols e8623f580a Merge branch 'MDL-43620_m29v2' of https://github.com/sbourget/moodle into MOODLE_29_STABLE 2016-01-13 09:45:54 +08:00
Andrew Nicols 247f5bee76 Merge branch 'MDL-51710-29' of git://github.com/FMCorz/moodle into MOODLE_29_STABLE 2016-01-13 09:18:06 +08:00
Andrew Nicols 566abee0a9 Merge branch 'MDL-52507_29' of https://github.com/jinhofer/moodle into MOODLE_29_STABLE 2016-01-13 09:08:18 +08:00
Andrew Nicols f51aafc730 Merge branch 'MDL-52649-29' of git://github.com/junpataleta/moodle into MOODLE_29_STABLE 2016-01-13 09:04:17 +08:00
Joseph Inhofer a0aef397f8 MDL-52507 enrol/manual: Generated a smart zIndex 2016-01-12 12:11:35 -06:00
AMOS bot d454a4ece8 Automatically generated installer lang files 2016-01-13 00:04:17 +08:00
Dan Poltawski 409649db96 Merge branch 'MDL-52400-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2016-01-12 13:13:09 +00:00
Dan Poltawski 2916c971cd Merge branch 'MDL-21912-29' of git://github.com/cameron1729/moodle into MOODLE_29_STABLE 2016-01-12 11:08:15 +00:00
Dan Poltawski 2b2f987725 MDL-52656 mod_forum: remove $SSSION test hack 2016-01-12 10:48:47 +00:00
Dan Poltawski 6c57573b7c Merge branch 'wip-mdl-52656-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2016-01-12 10:48:36 +00:00
Andrew Nicols b74243950e Merge branch 'MOODLE_29_STABLE' of https://github.com/janeklb/moodle into MOODLE_29_STABLE 2016-01-12 15:58:37 +08:00
Andrew Nicols 6850c24a9c Merge branch 'MDL-52585-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2016-01-12 14:37:29 +08:00
Andrew Nicols f809ee9e45 Merge branch 'MDL-52610_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2016-01-12 14:33:53 +08:00
David Monllao d95dbc01e2 MDL-52610 user: Honour allowaccountssameemail in create_users ws
Credit to Dmitriy Kuzevanov.
2016-01-12 13:57:33 +08:00
Andrew Nicols a899a7af13 Merge branch 'MDL-52643_m29v1' of https://github.com/sbourget/moodle into MOODLE_29_STABLE 2016-01-12 13:13:46 +08:00
Andrew Nicols 645816a244 MDL-38020 behat: Correct singleselect usage 2016-01-12 12:24:25 +08:00
Andrew Nicols a176f71a43 Merge branch 'MDL-38020-29' of git://github.com/danpoltawski/moodle into MOODLE_29_STABLE 2016-01-12 12:24:18 +08:00
Andrew Nicols c2c4302d74 Merge branch 'MDL-27840-29' of git://github.com/danpoltawski/moodle into MOODLE_29_STABLE 2016-01-12 11:49:20 +08:00
Jun Pataleta 01989e77ac MDL-52649 user: Add check for potentially undefined variables 2016-01-12 08:56:59 +08:00
Michael Aherne cf9e808967 MDL-52589 cache: Allow unused stores to be uninstalled 2016-01-11 15:33:38 +00:00
Dan Poltawski 65e74ad477 Merge branch 'MDL-52000-29' of git://github.com/andrewnicols/moodle into MOODLE_29_STABLE 2016-01-11 12:21:51 +00:00
Dan Poltawski 576c6bf5c8 Merge branch 'MDL-41531-29' of git://github.com/junpataleta/moodle into MOODLE_29_STABLE 2016-01-11 11:09:10 +00:00
Andrew Nicols 01258058c2 MDL-52693 tests: Backport .travis.yml to 29 2016-01-11 18:57:57 +08:00
Andrew Nicols 0e116ee392 MDL-52000 mod_forum: Respect timed posts in course overview block 2016-01-11 18:56:51 +08:00
Cameron Ball 353d1888aa MDL-52486 JavaScript: Make sure lang codes use underscores.
In some cases, underscores in lang codes get replaced with dashes
which causes some JavaScript to be unhappy. This patch simply reverse
the underscore to dash replacement on the JS side.
2016-01-11 17:02:45 +08:00
Cameron Ball 4a5fb82772 MDL-21912 restore: Add admin setting to restore conflicting admin user 2016-01-11 14:09:38 +08:00
eWallah 4d4ea7647d MDL-41531 enrol_paypal: Fix enrol errors due to non-ASCII characters 2016-01-11 10:49:51 +08:00
AMOS bot ccc259b268 Automatically generated installer lang files 2016-01-11 00:04:26 +08:00
Frederic Massart 3617ae07f3 MDL-51710 repository_s3: Use proxy settings when communicating with S3 2016-01-08 16:54:59 +08:00
Stephen Bourget 13df246e98 MDL-52643 block_blog_menu: Add behat tests 2016-01-07 20:18:52 -05:00
Rajesh Taneja a1cd2000fb MDL-52656 unittest: Reset original session while setting user 2016-01-08 10:50:16 +10:00
John Okely a1409ba644 MDL-52608 core: Use property_exists in fullname
Credit to Dmitriy Kuzevanov for the patch.
2016-01-07 07:39:17 +00:00
Paul Nicholls 81a3c47001 MDL-52673 workshop: fix dndnotsupported message in assessment form
An old CSS rule which doesn't seem to serve any purpose any more was
causing the "drag and drop not supported" message to be displayed (even
when incorrect) in the workshop assessment form when using a list-view
rubric as the grading strategy.
2016-01-07 15:44:33 +13:00
Dan Poltawski 49e4b4922b MDL-45265 behat: tests for admin_bookmarks block 2016-01-06 11:01:44 +00:00
Nadav Kavalerchik 1eb45d6e2b MDL-52615 Workshop: Right align phase status icons, in RTL mode. 2016-01-05 20:36:45 +02:00
Janek Lasocki-Biczysko c0fbed07ee MDL-52504 grunt: fixed scope of jshint when in amd directory 2016-01-05 09:58:55 +00:00
Stephen Bourget a8c51a689d MDL-50915 Lesson: Behat test for overview report 2016-01-04 18:40:26 -05:00
Stephen Bourget a88106bdd9 MDL-50915 Lesson: Fix information on outline report 2016-01-04 18:40:22 -05:00
Stephen Bourget 51ddd51271 MDL-43620 Chat: Behat test for course reset 2016-01-04 11:58:48 -05:00
Stephen Bourget 6d5aecf22e MDL-43620 Chat: Fix error on course reset 2016-01-04 11:58:44 -05:00
Juan Leyva 0e4483cf57 MDL-52400 webservice: Add core_notes_delete_notes to the mobile service 2016-01-04 16:36:15 +01:00
Dan Poltawski fabb658ff6 MDL-38020 behat: for enrollment management from participants page 2015-12-30 15:26:49 +00:00
Dan Poltawski 9a30a23456 MDL-38020 participants: Use consistent link for editing enrollments
Previously the role assignment url was used when a role was selected, but
this page doesn't enrol users into the course (its the old 1.9 way
before we had the enrollments table).
2015-12-30 15:26:49 +00:00
Dan Poltawski 38436bfd65 MDL-27840 course: prevent warnings on half-uninstall mod 2015-12-30 14:13:53 +00:00
Juan Leyva 656808ea40 MDL-51123 mod_scorm: Do not display SCO with invisible = false 2015-12-30 10:17:14 +01:00
Dan Poltawski 680ebf2315 MDL-50829 lang: fix to RTL/LTR bracket confusion
Thanks to ISHIKAWA Takayuki for the initial patch
2015-12-29 12:32:05 +00:00
Juan Leyva bab4badd06 MDL-52459 mod_scorm: Auto-update downloaded packages 2015-12-29 12:44:04 +01:00
Juan Leyva fed63e1d27 MDL-52585 webservices: Return correct invalid login message 2015-12-22 16:59:58 +01:00
Ben Kelada c2176f5451 MDL-52261 filelib: Do login check for files in blocks 2015-12-04 11:03:09 +11:00
Colin Campbell 7bed522217 MDL-51715 lib/grade: Unit test for aggregationweight 2015-11-02 10:09:44 -06:00
Colin Campbell f2f35e85d8 MDL-51715 lib/grade: Zero out aggregationweight for novalue and dropped
set_usedinaggregation was setting aggregationweight to zero in these
cases for non-category grades, but not for category grades.
2015-11-02 10:09:16 -06:00
504 changed files with 13076 additions and 2802 deletions
+4
View File
@@ -0,0 +1,4 @@
**/yui/build/** -diff
**/amd/build/** -diff
theme/bootstrapbase/style/editor.css -diff
theme/bootstrapbase/style/moodle.css -diff
+174
View File
@@ -0,0 +1,174 @@
# PLEASE NOTE: Travis is not currently utilised by the Moodle core integration
# process (which uses our internal CI system) this file is here for the benefit
# of community developers git clones - see MDL-51458.
sudo: false
# We currently disable Travis notifications entirely until https://github.com/travis-ci/travis-ci/issues/4976
# is fixed.
notifications:
email: false
language: php
php:
# We only run the highest and lowest supported versions to reduce the load on travis-ci.org.
- 5.6
# - 5.5
- 5.4
env:
# Although we want to run these jobs and see failures as quickly as possible, we also want to get the slowest job to
# start first so that the total run time is not too high.
#
# We only run MySQL on PHP 5.6, so run that first.
# CI Tests should be second-highest in priority as these only take <= 60 seconds to run under normal circumstances.
# Postgres is significantly is pretty reasonable in its run-time.
# Run unit tests on MySQL
- DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
# Run CI Tests without running PHPUnit.
- DB=none PHPUNIT=false INSTALL=false CITEST=true
# Run unit tests on Postgres
- DB=pgsql PHPUNIT=true INSTALL=false CITEST=false
matrix:
# Enable fast finish.
# This will fail the build if a single job fails (except those in allow_failures).
# It will not stop the jobs from running.
fast_finish: true
exclude:
# MySQL - it's just too slow.
# Exclude it on all versions except for latest.
# - env: DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
# php: 5.6
#
# - env: DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
# php: 5.5
- env: DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
php: 5.4
cache:
directories:
- $HOME/.composer/cache
install:
# Disable xdebug. We aren't generating code coverage, and it has a huge impact upon test performance.
- rm /home/travis/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
# Set the encrypted GITHUB_TOKEN if it's available to raise the API limit.
- if [ -n "$GITHUB_APITOKEN" ]; then composer config github-oauth.github.com $GITHUB_APITOKEN; fi
# Install composer dependencies.
# We need --no-interaction in case we hit API limits for composer. This causes it to fall back to a standard clone.
# Typically it should be able to use the Composer cache if any other job has already completed before we started here.
- travis_retry composer install --prefer-dist --no-interaction
before_script:
- >
if [ "$INSTALL" = 'true' -o "$PHPUNIT" = 'true' ];
then
# Copy generic configuration in place.
cp config-dist.php config.php ;
# Create the moodledata directory.
mkdir -p "$HOME"/roots/base
# The database name and password.
sed -i \
-e "s%= 'moodle'%= 'travis_ci_test'%" \
-e "s%= 'password'%= ''%" \
config.php ;
# The wwwroot and dataroot.
sed -i \
-e "s%http://example.com/moodle%http://localhost%" \
-e "s%/home/example/moodledata%/home/travis/roots/base%" \
config.php ;
if [ "$DB" = 'pgsql' ];
then
# Postgres-specific setup.
sed -i \
-e "s%= 'username'%= 'postgres'%" \
config.php ;
psql -c 'CREATE DATABASE travis_ci_test;' -U postgres;
fi
if [ "$DB" = 'mysqli' ];
then
# MySQL-specific setup.
sed -i \
-e "s%= 'pgsql'%= 'mysqli'%" \
-e "s%= 'username'%= 'travis'%" \
config.php;
mysql -u root -e 'SET GLOBAL innodb_file_format=barracuda;' ;
mysql -u root -e 'SET GLOBAL innodb_file_per_table=ON;' ;
mysql -e 'CREATE DATABASE travis_ci_test DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_bin;' ;
fi
if [ "$PHPUNIT" = 'true' ];
then
# Create a directory for the phpunit dataroot.
mkdir -p "$HOME"/roots/phpunit
# The phpunit dataroot and prefix..
sed -i \
-e "/require_once/i \\\$CFG->phpunit_dataroot = '\/home\/travis\/roots\/phpunit';" \
-e "/require_once/i \\\$CFG->phpunit_prefix = 'p_';" \
config.php ;
# Initialise PHPUnit for Moodle.
php admin/tool/phpunit/cli/init.php
fi
fi
script:
########################################################################
# PHPUnit
########################################################################
- >
if [ "$PHPUNIT" = 'true' ];
then
vendor/bin/phpunit;
fi
########################################################################
# CI Tests
########################################################################
- >
if [ "$CITEST" = 'true' ];
then
# Note - this is deliberately placed in the script section as we
# should not add any code until after phpunit has run.
# The following repositories are required.
# The local_ci repository does the actual checking.
git clone https://github.com/moodlehq/moodle-local_ci.git local/ci
# We need the official upstream for comparison
git remote add upstream https://github.com/moodle/moodle.git;
git fetch upstream MOODLE_29_STABLE;
export GIT_PREVIOUS_COMMIT="`git merge-base FETCH_HEAD $TRAVIS_COMMIT`";
export GIT_COMMIT="$TRAVIS_COMMIT";
export UPSTREAM_FETCH_HEAD=`git rev-parse FETCH_HEAD`
# Variables required by our linter.
export gitcmd=`which git`;
export gitdir="$TRAVIS_BUILD_DIR";
export phpcmd=`which php`;
fi
# Actually run the CI Tests - do this outside of the main test to make output clearer.
- >
if [ "$CITEST" = 'true' ];
then
bash local/ci/php_lint/php_lint.sh;
fi
+137 -135
View 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
@@ -24,31 +25,56 @@
module.exports = function(grunt) {
var path = require('path'),
fs = require('fs'),
tasks = {},
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: ['**/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: {
@@ -61,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'));
// 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.
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.
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');
}
if (options.recursive) {
args.push('--recursive');
}
// 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 (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.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.recursive = false;
} 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 (grunt.option('watch')) {
grunt.fail.fatal('The --watch option has been removed, please use `grunt watch` instead');
}
// Add the stderr option if appropriate
if (grunt.option('verbose')) {
args.push('--lint-stderr');
@@ -120,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();
}
});
};
@@ -142,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() {
@@ -222,7 +207,7 @@ module.exports = function(grunt) {
if (path.basename(path.resolve(cwd, '../../')) == 'yui') {
grunt.task.run('shifter');
// Are we in an AMD directory?
} else if (path.basename(cwd) == 'amd') {
} else if (inAMD) {
grunt.task.run('amd');
} else {
// Run them all!.
@@ -231,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);
+312
View File
@@ -1145,6 +1145,11 @@
<ON_CHECK message="unsupporteddbtablerowformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
<FEEDBACK>
<ON_CHECK message="libcurlwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
<MOODLE version="2.8" requires="2.2">
@@ -1418,6 +1423,11 @@
<ON_CHECK message="unsupporteddbtablerowformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
<FEEDBACK>
<ON_CHECK message="libcurlwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
<MOODLE version="3.0" requires="2.2">
@@ -1434,6 +1444,7 @@
<VENDOR name="oracle" version="10.2" />
</DATABASE>
<PHP version="5.4.4" level="required">
<RESTRICT function="restrict_php_version_71" message="unsupportedphpversion71" />
</PHP>
<PCREUNICODE level="optional">
<FEEDBACK>
@@ -1556,6 +1567,307 @@
<ON_CHECK message="unsupporteddbtablerowformat" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
<FEEDBACK>
<ON_CHECK message="libcurlwarning" />
</FEEDBACK>
</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">
<RESTRICT function="restrict_php_version_71" message="unsupportedphpversion71" />
</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="xmlreader" 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_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
<FEEDBACK>
<ON_CHECK message="libcurlwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
<MOODLE version="3.2" 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.6.5" 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="xmlreader" 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_CHECK file="lib/upgradelib.php" function="check_unoconv_version" level="optional">
<FEEDBACK>
<ON_CHECK message="unoconvwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
<FEEDBACK>
<ON_CHECK message="libcurlwarning" />
</FEEDBACK>
</CUSTOM_CHECK>
</CUSTOM_CHECKS>
</MOODLE>
</COMPATIBILITY_MATRIX>
+1 -1
View File
@@ -201,7 +201,7 @@ if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey() && $de
$event = \core\event\role_capabilities_updated::create(
array(
'context' => $systemcontext,
'objectid' => $roleid
'objectid' => $tableroleid
)
);
$event->set_legacy_logdata(array(SITEID, 'role', $action, 'admin/roles/define.php?action=view&roleid=' . $tableroleid,
+5 -1
View File
@@ -20,7 +20,11 @@ $adminroot = admin_get_root(); // need all settings
$settingspage = $adminroot->locate($section, true);
if (empty($settingspage) or !($settingspage instanceof admin_settingpage)) {
print_error('sectionerror', 'admin', "$CFG->wwwroot/$CFG->admin/");
if (moodle_needs_upgrading()) {
redirect(new moodle_url('/admin/index.php'));
} else {
print_error('sectionerror', 'admin', "$CFG->wwwroot/$CFG->admin/");
}
die;
}
+3
View File
@@ -205,6 +205,9 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
// Create a page for general import configuration and defaults.
$temp = new admin_settingpage('importgeneralsettings', new lang_string('importgeneralsettings', 'backup'), 'moodle/backup:backupcourse');
$temp->add(new admin_setting_configtext('backup/import_general_maxresults', new lang_string('importgeneralmaxresults', 'backup'), new lang_string('importgeneralmaxresults_desc', 'backup'), 10));
$temp->add(new admin_setting_configcheckbox('backup/import_general_duplicate_admin_allowed',
new lang_string('importgeneralduplicateadminallowed', 'backup'),
new lang_string('importgeneralduplicateadminallowed_desc', 'backup'), 0));
$ADMIN->add('backups', $temp);
// Create a page for automated backups configuration and defaults.
+4 -5
View File
@@ -18,11 +18,10 @@ $ADMIN->add('server', $temp);
// "supportcontact" settingpage
$temp = new admin_settingpage('supportcontact', new lang_string('supportcontact','admin'));
if (isloggedin()) {
global $USER;
$primaryadminemail = $USER->email;
$primaryadminname = fullname($USER, true);
$primaryadmin = get_admin();
if ($primaryadmin) {
$primaryadminemail = $primaryadmin->email;
$primaryadminname = fullname($primaryadmin, true);
} else {
// no defaults during installation - admin user must be created first
$primaryadminemail = NULL;
-2
View File
@@ -27,7 +27,6 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
And I add "User Three (three@example.com)" user to "CH1" cohort members
And I follow "Browse list of users"
@javascript
Scenario: Filter user accounts by role and cohort
When I set the following fields to these values:
| courserole_rl | Student |
@@ -51,7 +50,6 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
And I should see "User Three"
And I should see "User Four"
@javascript
Scenario: Filter user accounts by confirm and authentication method
When I set the following fields to these values:
| Confirmed | No |
+12 -7
View File
@@ -120,8 +120,8 @@ $tags = '';
if ($options['profile']) {
$profile = $options['profile'];
if (!isset($CFG->behat_config[$profile])) {
echo "Invalid profile passed: " . $profile;
if (!isset($CFG->behat_config[$profile]) && !isset($CFG->behat_profiles[$profile])) {
echo "Invalid profile passed: " . $profile . PHP_EOL;
exit(1);
}
$extraopts[] = '--profile="' . $profile . '"';
@@ -226,22 +226,27 @@ $exitcodes = print_combined_run_output($processes, $stoponfail);
$time = round(microtime(true) - $time, 1);
echo "Finished in " . gmdate("G\h i\m s\s", $time) . PHP_EOL . PHP_EOL;
ksort($exitcodes);
// Print exit info from each run.
$status = false;
// Status bits contains pass/fail status of parallel runs.
$status = 0;
$processcounter = 0;
foreach ($exitcodes as $exitcode) {
$status = (bool)$status || (bool)$exitcode;
if ($exitcode) {
$status |= (1 << $processcounter);
}
$processcounter++;
}
// Run finished. Show exit code and output from individual process.
$verbose = empty($options['verbose']) ? false : true;
$verbose = $verbose || $status;
$verbose = $verbose || !empty($status);
// Show exit code from each process, if any process failed.
if ($verbose) {
// Echo exit codes.
echo "Exit codes for each behat run: " . PHP_EOL;
ksort($exitcodes);
foreach ($exitcodes as $run => $exitcode) {
echo $run . ": " . $exitcode . PHP_EOL;
}
@@ -263,7 +268,7 @@ print_each_process_info($processes, $verbose);
// Remove site symlink if necessary.
behat_config_manager::drop_parallel_site_links();
exit((int) $status);
exit($status);
/**
* Signal handler for terminal exit.
+1
View File
@@ -173,6 +173,7 @@ if ($options['install']) {
// This is only displayed once for parallel install.
if (empty($options['run'])) {
$runtestscommand = behat_command::get_behat_command(true, !empty($options['run']));
$runtestscommand .= ' --config ' . behat_config_manager::get_behat_cli_config_filepath();
@@ -0,0 +1,34 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Display environment used for running behat.
*
* This file is used for behat testing to ensure cli and apache
* version of environment is same.
*
* @package tool_behat
* @copyright 2016 onwards Rajesh Taneja
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__.'/../../../../../../config.php');
// Only continue for behat site.
defined('BEHAT_SITE_RUNNING') || die();
require_once($CFG->libdir.'/behat/classes/util.php');
echo json_encode(behat_util::get_environment(), true);
+1 -1
View File
@@ -176,7 +176,7 @@ echo html_writer::end_tag('td');
$options = array();
foreach ($availablelangs as $alang) {
if (!empty($alang[0]) and trim($alang[0]) !== 'en' and !$controller->is_installed_lang($alang[0], $alang[1])) {
$options[$alang[0]] = $alang[2].' ('.$alang[0].')';
$options[$alang[0]] = $alang[2].' &lrm;('.$alang[0].')&lrm;';
}
}
if (!empty($options)) {
@@ -52,8 +52,7 @@ class logstore_database_store_testcase extends advanced_testcase {
$this->assertCount(0, $stores);
// Fake the settings, we will abuse the standard plugin table here...
$parts = explode('_', get_class($DB));
set_config('dbdriver', $parts[1] . '/' . $parts[0], 'logstore_database');
set_config('dbdriver', $CFG->dblibrary . '/' . $CFG->dbtype, 'logstore_database');
set_config('dbhost', $CFG->dbhost, 'logstore_database');
set_config('dbuser', $CFG->dbuser, 'logstore_database');
set_config('dbpass', $CFG->dbpass, 'logstore_database');
@@ -898,7 +898,7 @@ class manager {
$userfrom->customheaders[] = 'In-Reply-To: ' . $messageid;
// The message will be sent from the intended user.
$eventdata->userfrom = \core_user::get_noreply_user();
$eventdata->userfrom = \core_user::get_support_user();
$eventdata->userto = $USER;
$eventdata->subject = $this->get_reply_subject($this->currentmessagedata->envelope->subject);
$eventdata->fullmessage = get_string('invalidrecipientdescription', 'tool_messageinbound', $this->currentmessagedata);
@@ -140,6 +140,10 @@ class eventobservers {
$subscriptions = subscription_manager::get_subscriptions_by_event($eventobj);
$idstosend = array();
foreach ($subscriptions as $subscription) {
// Only proceed to fire events and notifications if the subscription is active.
if (!subscription_manager::subscription_is_active($subscription)) {
continue;
}
$starttime = $now - $subscription->timewindow;
$starttime = ($starttime > $subscription->lastnotificationsent) ? $starttime : $subscription->lastnotificationsent;
if ($subscription->courseid == 0) {
@@ -82,15 +82,16 @@ class notification_task extends \core\task\adhoc_task {
$template = $subscription->template;
$template = $this->replace_placeholders($template, $subscription, $eventobj, $context);
$htmlmessage = format_text($template, $subscription->templateformat, array('context' => $context));
$msgdata = new \stdClass();
$msgdata->component = 'tool_monitor'; // Your component name.
$msgdata->name = 'notification'; // This is the message name from messages.php.
$msgdata->userfrom = \core_user::get_noreply_user();
$msgdata->userto = $user;
$msgdata->subject = $subscription->get_name($context);
$msgdata->fullmessage = format_text($template, $subscription->templateformat, array('context' => $context));
$msgdata->fullmessageformat = $subscription->templateformat;
$msgdata->fullmessagehtml = format_text($template, $subscription->templateformat, array('context' => $context));
$msgdata->fullmessage = html_to_text($htmlmessage);
$msgdata->fullmessageformat = FORMAT_PLAIN;
$msgdata->fullmessagehtml = $htmlmessage;
$msgdata->smallmessage = '';
$msgdata->notification = 1; // This is only set to 0 for personal messages between users.
+11 -2
View File
@@ -55,17 +55,26 @@ class subscription {
* Magic get method.
*
* @param string $prop property to get.
*
* @return mixed
* @throws \coding_exception
*/
public function __get($prop) {
if (property_exists($this->subscription, $prop)) {
if (isset($this->subscription->$prop)) {
return $this->subscription->$prop;
}
throw new \coding_exception('Property "' . $prop . '" doesn\'t exist');
}
/**
* Magic isset method.
*
* @param string $prop the property to get.
* @return bool true if the property is set, false otherwise.
*/
public function __isset($prop) {
return property_exists($this->subscription, $prop);
}
/**
* Get a human readable name for instances associated with this subscription.
*
@@ -35,6 +35,10 @@ defined('MOODLE_INTERNAL') || die();
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class subscription_manager {
/** @const Period of time, in days, after which an inactive subscription will be removed completely.*/
const INACTIVE_SUBSCRIPTION_LIFESPAN_IN_DAYS = 30;
/**
* Subscribe a user to a given rule.
*
@@ -456,4 +460,78 @@ class subscription_manager {
return false;
}
/**
* Activates a group of subscriptions based on an input array of ids.
*
* @since 2.9.7
* @param array $ids of subscription ids.
* @return bool true if the operation was successful, false otherwise.
*/
public static function activate_subscriptions(array $ids) {
global $DB;
if (!empty($ids)) {
list($sql, $params) = $DB->get_in_or_equal($ids);
$success = $DB->set_field_select('tool_monitor_subscriptions', 'inactivedate', '0', 'id ' . $sql, $params);
return $success;
}
return false;
}
/**
* Deactivates a group of subscriptions based on an input array of ids.
*
* @since 2.9.7
* @param array $ids of subscription ids.
* @return bool true if the operation was successful, false otherwise.
*/
public static function deactivate_subscriptions(array $ids) {
global $DB;
if (!empty($ids)) {
$inactivedate = time();
list($sql, $params) = $DB->get_in_or_equal($ids);
$success = $DB->set_field_select('tool_monitor_subscriptions', 'inactivedate', $inactivedate, 'id ' . $sql,
$params);
return $success;
}
return false;
}
/**
* Deletes subscriptions which have been inactive for a period of time.
*
* @since 2.9.7
* @param int $userid if provided, only this user's stale subscriptions will be deleted.
* @return bool true if the operation was successful, false otherwise.
*/
public static function delete_stale_subscriptions($userid = 0) {
global $DB;
// Get the expiry duration, in days.
$cutofftime = strtotime("-" . self::INACTIVE_SUBSCRIPTION_LIFESPAN_IN_DAYS . " days", time());
if (!empty($userid)) {
// Remove any stale subscriptions for the desired user only.
$success = $DB->delete_records_select('tool_monitor_subscriptions',
'userid = ? AND inactivedate < ? AND inactivedate <> 0',
array($userid, $cutofftime));
} else {
// Remove all stale subscriptions.
$success = $DB->delete_records_select('tool_monitor_subscriptions',
'inactivedate < ? AND inactivedate <> 0',
array($cutofftime));
}
return $success;
}
/**
* Check whether a subscription is active.
*
* @since 2.9.7
* @param \tool_monitor\subscription $subscription instance.
* @return bool true if the subscription is active, false otherwise.
*/
public static function subscription_is_active(subscription $subscription) {
return empty($subscription->inactivedate);
}
}
@@ -0,0 +1,274 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_monitor\task;
use tool_monitor\subscription;
use tool_monitor\subscription_manager;
/**
* Simple task class responsible for activating, deactivating and removing subscriptions.
*
* Activation/deactivation is managed by looking at the same access rules used to determine whether a user can
* subscribe to the rule in the first place.
*
* Removal occurs when a subscription has been inactive for a period of time exceeding the lifespan, as set by
* subscription_manager::get_inactive_subscription_lifespan().
*
* I.e.
* - Activation: If a user can subscribe currently, then an existing subscription should be made active.
* - Deactivation: If a user cannot subscribe currently, then an existing subscription should be made inactive.
* - Removal: If a user has a subscription that has been inactive for longer than the prescribed period, then
* delete the subscription entirely.
*
* @since 2.9.7
* @package tool_monitor
* @copyright 2016 Jake Dallimore <jrhdallimore@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class check_subscriptions extends \core\task\scheduled_task {
/** @var array 1d static cache, indexed by userid, storing whether or not the user has been fully set up.*/
protected $userssetupcache = array();
/** @var array 2d static cache, indexed by courseid and userid, storing whether a user can access the course with
* the 'tool/monitor:subscribe' capability.
*/
protected $courseaccesscache = array();
/**
* Get a descriptive name for this task.
*
* @since 2.9.7
* @return string name of the task.
*/
public function get_name() {
return get_string('taskchecksubscriptions', 'tool_monitor');
}
/**
* Checks all course-level rule subscriptions and activates/deactivates based on current course access.
*
* The ordering of checks within the task is important for optimisation purposes. The aim is to be able to make a decision
* about whether to activate/deactivate each subscription without making unnecessary checks. The ordering roughly follows the
* context model, starting with system and user checks and moving down to course and course-module only when necessary.
*
* For example, if the user is suspended, then any active subscription is made inactive right away. I.e. there is no need to
* check site-level, course-level or course-module-level permissions. Likewise, if a subscriptions is site-level, there is no
* need to check course-level and course-module-level permissions.
*
* The task performs the following checks, in this order:
* 1. Check for a suspended user, breaking if suspended.
* 2. Check for an incomplete (not set up) user, breaking if not fully set up.
* 3. Check for the required capability in the relevant context, breaking if the capability is not found.
* 4. Check whether the subscription is site-context, breaking if true.
* 5. Check whether the user has course access, breaking only if the subscription is not also course-module-level.
* 6. Check whether the user has course-module access.
*
* @since 2.9.7
*/
public function execute() {
global $DB;
if (!get_config('tool_monitor', 'enablemonitor')) {
return; // The tool is disabled. Nothing to do.
}
$toactivate = array(); // Store the ids of subscriptions to be activated upon completion.
$todeactivate = array(); // Store the ids of subscriptions to be deactivated upon completion.
// Resultset rows are ordered by userid and courseid to work nicely with get_fast_modinfo() caching.
$sql = "SELECT u.id AS userid, u.firstname AS userfirstname, u.lastname AS userlastname, u.suspended AS usersuspended,
u.email AS useremail, c.visible as coursevisible, c.cacherev as coursecacherev, s.courseid AS subcourseid,
s.userid AS subuserid, s.cmid AS subcmid, s.inactivedate AS subinactivedate, s.id AS subid
FROM {user} u
JOIN {tool_monitor_subscriptions} s ON (s.userid = u.id)
LEFT JOIN {course} c ON (c.id = s.courseid)
WHERE u.id = s.userid
ORDER BY s.userid, s.courseid";
$rs = $DB->get_recordset_sql($sql);
foreach ($rs as $row) {
// Create skeleton records from the result. This should be enough to use in subsequent access calls and avoids DB hits.
$sub = $this->get_subscription_from_rowdata($row);
$sub = new subscription($sub);
if (!isset($user) || $user->id != $sub->userid) {
$user= $this->get_user_from_rowdata($row);
}
if ((!isset($course) || $course->id != $sub->courseid) && !empty($sub->courseid)) {
$course = $this->get_course_from_rowdata($row);
}
// The user is suspended at site level, so deactivate any active subscriptions.
if ($user->suspended) {
if (subscription_manager::subscription_is_active($sub)) {
$todeactivate[] = $sub->id;
}
continue;
}
// Is the user fully set up? As per require_login on the subscriptions page.
if (!$this->is_user_setup($user)) {
if (subscription_manager::subscription_is_active($sub)) {
$todeactivate[] = $sub->id;
}
continue;
}
// Determine the context, based on the subscription course id.
$sitelevelsubscription = false;
if (empty($sub->courseid)) {
$context = \context_system::instance();
$sitelevelsubscription = true;
} else {
$context = \context_course::instance($sub->courseid);
}
// Check capability in the context.
if (!has_capability('tool/monitor:subscribe', $context, $user)) {
if (subscription_manager::subscription_is_active($sub)) {
$todeactivate[] = $sub->id;
}
continue;
}
// If the subscription is site-level, then we've run all the checks required to make an access decision.
if ($sitelevelsubscription) {
if (!subscription_manager::subscription_is_active($sub)) {
$toactivate[] = $sub->id;
}
continue;
}
// Check course access.
if (!$this->user_can_access_course($user, $course, 'tool/monitor:subscribe')) {
if (subscription_manager::subscription_is_active($sub)) {
$todeactivate[] = $sub->id;
}
continue;
}
// If the subscription has no course module relationship.
if (empty($sub->cmid)) {
if (!subscription_manager::subscription_is_active($sub)) {
$toactivate[] = $sub->id;
}
continue;
}
// Otherwise, check the course module info. We use the same checks as on the subscription page.
$modinfo = get_fast_modinfo($course, $sub->userid);
$cm = $modinfo->get_cm($sub->cmid);
if (!$cm || !$cm->uservisible || !$cm->available) {
if (subscription_manager::subscription_is_active($sub)) {
$todeactivate[] = $sub->id;
}
continue;
}
// The course module is available and visible, so make a decision.
if (!subscription_manager::subscription_is_active($sub)) {
$toactivate[] = $sub->id;
}
}
$rs->close();
// Activate/deactivate/delete relevant subscriptions.
subscription_manager::activate_subscriptions($toactivate);
subscription_manager::deactivate_subscriptions($todeactivate);
subscription_manager::delete_stale_subscriptions();
}
/**
* Determines whether a user is fully set up, using cached results where possible.
*
* @since 2.9.7
* @param \stdClass $user the user record.
* @return bool true if the user is fully set up, false otherwise.
*/
protected function is_user_setup($user) {
if (!isset($this->userssetupcache[$user->id])) {
$this->userssetupcache[$user->id] = !user_not_fully_set_up($user);
}
return $this->userssetupcache[$user->id];
}
/**
* Determines a user's access to a course with a given capability, using cached results where possible.
*
* @since 2.9.7
* @param \stdClass $user the user record.
* @param \stdClass $course the course record.
* @param string $capability the capability to check.
* @return bool true if the user can access the course with the specified capability, false otherwise.
*/
protected function user_can_access_course($user, $course, $capability) {
if (!isset($this->courseaccesscache[$course->id][$user->id][$capability])) {
$this->courseaccesscache[$course->id][$user->id][$capability] = can_access_course($course, $user, $capability, true);
}
return $this->courseaccesscache[$course->id][$user->id][$capability];
}
/**
* Returns a partial subscription record, created from properties of the supplied recordset row object.
* Intended to return a minimal record for specific use within this class and in subsequent access control calls only.
*
* @since 2.9.7
* @param \stdClass $rowdata the row object.
* @return \stdClass a partial subscription record.
*/
protected function get_subscription_from_rowdata($rowdata) {
$sub = new \stdClass();
$sub->id = $rowdata->subid;
$sub->userid = $rowdata->subuserid;
$sub->courseid = $rowdata->subcourseid;
$sub->cmid = $rowdata->subcmid;
$sub->inactivedate = $rowdata->subinactivedate;
return $sub;
}
/**
* Returns a partial course record, created from properties of the supplied recordset row object.
* Intended to return a minimal record for specific use within this class and in subsequent access control calls only.
*
* @since 2.9.7
* @param \stdClass $rowdata the row object.
* @return \stdClass a partial course record.
*/
protected function get_course_from_rowdata($rowdata) {
$course = new \stdClass();
$course->id = $rowdata->subcourseid;
$course->visible = $rowdata->coursevisible;
$course->cacherev = $rowdata->coursecacherev;
return $course;
}
/**
* Returns a partial user record, created from properties of the supplied recordset row object.
* Intended to return a minimal record for specific use within this class and in subsequent access control calls only.
*
* @since 2.9.7
* @param \stdClass $rowdata the row object.
* @return \stdClass a partial user record.
*/
protected function get_user_from_rowdata($rowdata) {
$user = new \stdClass();
$user->id = $rowdata->userid;
$user->firstname = $rowdata->userfirstname;
$user->lastname = $rowdata->userlastname;
$user->email = $rowdata->useremail;
$user->suspended = $rowdata->usersuspended;
return $user;
}
}
+1
View File
@@ -38,6 +38,7 @@
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="User id of the subscriber"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Timestamp of when this subscription was created"/>
<FIELD NAME="lastnotificationsent" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Timestamp of the time when a notification was last sent for this subscription."/>
<FIELD NAME="inactivedate" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+9
View File
@@ -32,5 +32,14 @@ $tasks = array(
'day' => '*',
'dayofweek' => '*',
'month' => '*'
),
array(
'classname' => 'tool_monitor\task\check_subscriptions',
'blocking' => 0,
'minute' => 'R',
'hour' => 'R',
'day' => '*',
'dayofweek' => '*',
'month' => '*'
)
);
+15
View File
@@ -56,5 +56,20 @@ function xmldb_tool_monitor_upgrade($oldversion) {
// Moodle v2.9.0 release upgrade line.
// Put any upgrade step following this.
if ($oldversion < 2015051101) {
// Define field inactivedate to be added to tool_monitor_subscriptions.
$table = new xmldb_table('tool_monitor_subscriptions');
$field = new xmldb_field('inactivedate', XMLDB_TYPE_INTEGER, '10', null, true, null, 0, 'lastnotificationsent');
// Conditionally launch add field inactivedate.
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
// Monitor savepoint reached.
upgrade_plugin_savepoint(true, 2015051101, 'tool', 'monitor');
}
return true;
}
@@ -99,4 +99,5 @@ $string['subhelp'] = 'Subscription details';
$string['subhelp_help'] = 'This subscription listens for when the event \'{$a->eventname}\' has been triggered in \'{$a->moduleinstance}\' {$a->frequency} time(s) in {$a->minutes} minute(s).';
$string['subscribeto'] = 'Subscribe to rule "{$a}"';
$string['taskcleanevents'] = 'Removes any unnecessary event monitor events';
$string['taskchecksubscriptions'] = 'Activate/deactivate invalid rule subscriptions';
$string['unsubscribe'] = 'Unsubscribe';
+5 -3
View File
@@ -103,10 +103,12 @@ function tool_monitor_get_user_courses() {
if (has_capability('tool/monitor:subscribe', context_system::instance())) {
$options[0] = get_string('site');
}
if ($courses = get_user_capability_course('tool/monitor:subscribe', null, true, 'fullname', $orderby)) {
if ($courses = get_user_capability_course('tool/monitor:subscribe', null, true, 'fullname, visible', $orderby)) {
foreach ($courses as $course) {
$options[$course->id] = format_string($course->fullname, true,
array('context' => context_course::instance($course->id)));
$coursectx = context_course::instance($course->id);
if ($course->visible || has_capability('moodle/course:viewhiddencourses', $coursectx)) {
$options[$course->id] = format_string($course->fullname, true, array('context' => $coursectx));
}
}
}
// If there are no courses and there is no site permission then return false.
@@ -1,10 +1,9 @@
@javascript @tool @tool_monitor
@tool @tool_monitor
Feature: Enable/disable managment of the event monitor
In order to manage event monitoring
As an admin
I need to enable/disable it
@javascript
Scenario: Tool is disabled by default.
Given I log in as "admin"
When I navigate to "Event monitoring rules" node in "Site administration > Reports"
@@ -467,7 +467,13 @@ class tool_monitor_eventobservers_testcase extends advanced_testcase {
$rulerecord->eventname = '\mod_book\event\course_module_viewed';
$rulerecord->cmid = $book->cmid;
$rulerecord->frequency = 1;
$rulerecord->template = '{link} {modulelink} {rulename} {description} {eventname}';
$rulerecord->template = '## {link} ##
* {modulelink}
* __{rulename}__
* {description}
* {eventname}';
$rulerecord->templateformat = FORMAT_MARKDOWN;
$rule = $toolgenerator->create_rule($rulerecord);
@@ -491,13 +497,21 @@ class tool_monitor_eventobservers_testcase extends advanced_testcase {
$msg = array_pop($msgs);
$modurl = new moodle_url('/mod/book/view.php', array('id' => $book->cmid));
$expectedmsg = $event->get_url()->out() . ' ' .
$modurl->out() . ' ' .
$rule->get_name($context) . ' ' .
$rule->get_description($context) . ' ' .
$rule->get_event_name();
$this->assertEquals($expectedmsg, $msg->fullmessage);
$this->assertContains('<h2>'.$event->get_url()->out().'</h2>', $msg->fullmessagehtml);
$this->assertContains('<li>'.$modurl->out().'</li>', $msg->fullmessagehtml);
$this->assertContains('<li><strong>'.$rule->get_name($context).'</strong></li>', $msg->fullmessagehtml);
$this->assertContains('<li>'.$rule->get_description($context).'</li>', $msg->fullmessagehtml);
$this->assertContains('<li>'.$rule->get_event_name().'</li>', $msg->fullmessagehtml);
$this->assertEquals(FORMAT_PLAIN, $msg->fullmessageformat);
$this->assertNotContains('<h2>', $msg->fullmessage);
$this->assertNotContains('##', $msg->fullmessage);
$this->assertContains(strtoupper($event->get_url()->out()), $msg->fullmessage);
$this->assertContains('* '.$modurl->out(), $msg->fullmessage);
$this->assertContains('* '.strtoupper($rule->get_name($context)), $msg->fullmessage);
$this->assertContains('* '.$rule->get_description($context), $msg->fullmessage);
$this->assertContains('* '.$rule->get_event_name(), $msg->fullmessage);
}
/**
@@ -0,0 +1,65 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || exit();
/**
* Unit tests for the subscription class.
* @since 2.9.7
*
* @package tool_monitor
* @category test
* @copyright 2016 Jake Dallimore <jrhdallimore@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_monitor_subscription_testcase extends advanced_testcase {
/**
* @var \tool_monitor\subscription $subscription object.
*/
private $subscription;
/**
* Test set up.
*/
public function setUp() {
$this->resetAfterTest(true);
// Create the mock subscription.
$sub = new stdClass();
$sub->id = 100;
$sub->name = 'My test rule';
$sub->courseid = 20;
$this->subscription = $this->getMock('\tool_monitor\subscription',null, array($sub));
}
/**
* Test for the magic __isset method.
*/
public function test_magic_isset() {
$this->assertEquals(true, isset($this->subscription->name));
$this->assertEquals(true, isset($this->subscription->courseid));
$this->assertEquals(false, isset($this->subscription->ruleid));
}
/**
* Test for the magic __get method.
*/
public function test_magic_get() {
$this->assertEquals(20, $this->subscription->courseid);
$this->setExpectedException('coding_exception');
$this->subscription->ruleid;
}
}
@@ -0,0 +1,364 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || exit();
/**
* Unit tests for the tool_monitor clean events task.
* @since 2.9.7
*
* @package tool_monitor
* @category test
* @copyright 2016 Jake Dallimore <jrhdallimore@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_monitor_task_check_subscriptions_testcase extends advanced_testcase {
private $course;
private $user;
private $rule;
private $subscription;
private $teacherrole;
private $studentrole;
/**
* Test set up.
*/
public function setUp() {
global $DB;
set_config('enablemonitor', 1, 'tool_monitor');
$this->resetAfterTest(true);
// All tests defined herein need a user, course, rule and subscription, so set these up.
$this->user = $this->getDataGenerator()->create_user();
$this->course = $this->getDataGenerator()->create_course();
$rule = new stdClass();
$rule->userid = 2; // Rule created by admin.
$rule->courseid = $this->course->id;
$rule->plugin = 'mod_book';
$rule->eventname = '\mod_book\event\course_module_viewed';
$rule->timewindow = 500;
$monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
$this->rule = $monitorgenerator->create_rule($rule);
$sub = new stdClass();
$sub->courseid = $this->course->id;
$sub->userid = $this->user->id;
$sub->ruleid = $this->rule->id;
$this->subscription = $monitorgenerator->create_subscription($sub);
// Also set up a student and a teacher role for use in some tests.
$this->teacherrole = $DB->get_record('role', array('shortname' => 'teacher'));
$this->studentrole = $DB->get_record('role', array('shortname' => 'student'));
}
/**
* Reloads the subscription object from the DB.
*
* @return void.
*/
private function reload_subscription() {
global $DB;
$sub = $DB->get_record('tool_monitor_subscriptions', array('id' => $this->subscription->id));
$this->subscription = new \tool_monitor\subscription($sub);
}
/**
* Test to confirm the task is named correctly.
*/
public function test_task_name() {
$task = new \tool_monitor\task\check_subscriptions();
$this->assertEquals(get_string('taskchecksubscriptions', 'tool_monitor'), $task->get_name());
}
/**
* Test to confirm that site level subscriptions are activated and deactivated according to system capabilities.
*/
public function test_site_level_subscription() {
// Create a site level subscription.
$monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
$sub = new stdClass();
$sub->userid = $this->user->id;
$sub->ruleid = $this->rule->id;
$this->subscription = $monitorgenerator->create_subscription($sub);
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should be inactive as the user doesn't have the capability. Pass in the id only to refetch the data.
$this->reload_subscription();
$this->assertEquals(false, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Now, assign the user as a teacher role at system context.
$this->getDataGenerator()->role_assign($this->teacherrole->id, $this->user->id, context_system::instance());
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should be active now. Pass in the id only to refetch the data.
$this->reload_subscription();
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
}
/**
* Test to confirm that if the module is disabled, no changes are made to active subscriptions.
*/
public function test_module_disabled() {
set_config('enablemonitor', 0, 'tool_monitor');
// Subscription should be active to start with.
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Run the task. Note, we never enrolled the user.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should still be active. Pass in the id only to refetch the data.
$this->reload_subscription();
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
}
/**
* Test to confirm an active, valid subscription stays active once the scheduled task is run.
*/
public function test_active_unaffected() {
// Enrol the user as a teacher. This role should have the required capability.
$this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, $this->teacherrole->id);
// Subscription should be active to start with.
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should still be active. Pass in the id only to refetch the data.
$this->reload_subscription();
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
}
/**
* Test to confirm that a subscription for a user without an enrolment to the course is made inactive.
*/
public function test_course_enrolment() {
// Subscription should be active until deactivated by the scheduled task. Remember, by default the test setup
// doesn't enrol the user, so the first run of the task should deactivate it.
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should NOT be active. Pass in the id only to refetch the data.
$this->reload_subscription();
$this->assertEquals(false, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Enrol the user.
$this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, $this->teacherrole->id);
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// Subscription should now be active again.
$this->reload_subscription();
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
}
/**
* Test to confirm that subscriptions for enrolled users without the required capability are made inactive.
*/
public function test_enrolled_user_with_no_capability() {
// Enrol the user. By default, students won't have the required capability.
$this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, $this->studentrole->id);
// The subscription should be active to start with. Pass in the id only to refetch the data.
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should NOT be active. Pass in the id only to refetch the data.
$this->reload_subscription();
$this->assertEquals(false, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
}
/**
* Test to confirm that subscriptions for users who fail can_access_course(), are deactivated.
*/
public function test_can_access_course() {
// Enrol the user as a teacher. This role should have the required capability.
$this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, $this->teacherrole->id);
// Strip the ability to see hidden courses, so we'll fail the check_subscriptions->user_can_access_course call.
$context = \context_course::instance($this->course->id);
assign_capability('moodle/course:viewhiddencourses', CAP_PROHIBIT, $this->teacherrole->id, $context);
// Subscription should be active to start with.
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Hide the course.
course_change_visibility($this->course->id, false);
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should be inactive. Pass in the id only to refetch the data.
$this->reload_subscription();
$this->assertEquals(false, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
}
/**
* Test to confirm that subscriptions for enrolled users who don't have CM access, are deactivated.
*/
public function test_cm_access() {
// Enrol the user as a student but grant to ability to subscribe. Students cannot view hidden activities.
$context = \context_course::instance($this->course->id);
assign_capability('tool/monitor:subscribe', CAP_ALLOW, $this->studentrole->id, $context);
$this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, $this->studentrole->id);
// Generate a course module.
$book = $this->getDataGenerator()->create_module('book', array('course' => $this->course->id));
// And add a subscription to it.
$sub = new stdClass();
$sub->courseid = $this->course->id;
$sub->userid = $this->user->id;
$sub->ruleid = $this->rule->id;
$sub->cmid = $book->cmid;
$monitorgenerator = $this->getDataGenerator()->get_plugin_generator('tool_monitor');
$this->subscription = $monitorgenerator->create_subscription($sub);
// The subscription should be active to start with. Pass in the id only to refetch the data.
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should still be active. Pass in the id only to refetch the data.
$this->reload_subscription();
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Make the course module invisible, which should in turn make the subscription inactive.
set_coursemodule_visible($book->cmid, false);
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should NOT be active. Pass in the id only to refetch the data.
$this->reload_subscription();
$this->assertEquals(false, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Make the course module visible again.
set_coursemodule_visible($book->cmid, true);
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should be active. Pass in the id only to refetch the data.
$this->reload_subscription();
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
}
/**
* Test to confirm that long term inactive subscriptions are removed entirely.
*/
public function test_stale_subscription_removal() {
global $DB;
// Manually set the inactivedate to 1 day older than the limit allowed.
$daysold = 1 + \tool_monitor\subscription_manager::INACTIVE_SUBSCRIPTION_LIFESPAN_IN_DAYS;
$inactivedate = strtotime("-$daysold days", time());
$DB->set_field('tool_monitor_subscriptions', 'inactivedate', $inactivedate, array('id' => $this->subscription->id));
// Subscription should be inactive to start with.
$this->reload_subscription();
$this->assertEquals(false, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// Subscription should now not exist at all.
$this->assertEquals(false, $DB->record_exists('tool_monitor_subscriptions', array('id' => $this->subscription->id)));
}
/**
* Test to confirm that subscriptions for a partially set up user are deactivated.
*/
public function test_user_not_fully_set_up() {
global $DB;
// Enrol the user as a teacher.
$this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, $this->teacherrole->id);
// The subscription should be active to start.
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Unset the user's email address, so we fail the check_subscriptions->is_user_setup() call.
$DB->set_field('user', 'email', '', array('id' => $this->user->id));
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should now be inactive.
$this->reload_subscription();
$this->assertEquals(false, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
}
/**
* Test to confirm that a suspended user's subscriptions are deactivated properly.
*/
public function test_suspended_user() {
global $DB;
// Enrol the user as a teacher. This role should have the required capability.
$this->getDataGenerator()->enrol_user($this->user->id, $this->course->id, $this->teacherrole->id);
// Subscription should be active to start with.
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Suspend the user.
$DB->set_field('user', 'suspended', '1', array('id' => $this->user->id));
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should now be inactive.
$this->reload_subscription();
$this->assertEquals(false, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
// Unsuspend the user.
$DB->set_field('user', 'suspended', '0', array('id' => $this->user->id));
// Run the task.
$task = new \tool_monitor\task\check_subscriptions();
$task->execute();
// The subscription should now be active again.
$this->reload_subscription();
$this->assertEquals(true, \tool_monitor\subscription_manager::subscription_is_active($this->subscription));
}
}
+1 -1
View File
@@ -26,6 +26,6 @@
defined('MOODLE_INTERNAL') || die;
$plugin->version = 2015051100; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2015051101; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2015050500; // Requires this Moodle version.
$plugin->component = 'tool_monitor'; // Full name of the plugin (used for diagnostics).
+16 -3
View File
@@ -567,8 +567,18 @@ if ($formdata = $mform2->is_cancelled()) {
}
if ($existinguser->$column !== $user->$column) {
if ($column === 'email') {
if ($DB->record_exists('user', array('email'=>$user->email))) {
if ($noemailduplicates) {
$select = $DB->sql_like('email', ':email', false, true, false, '|');
$params = array('email' => $DB->sql_like_escape($user->email, '|'));
if ($DB->record_exists_select('user', $select , $params)) {
$changeincase = core_text::strtolower($existinguser->$column) === core_text::strtolower(
$user->$column);
if ($changeincase) {
// If only case is different then switch to lower case and carry on.
$user->$column = core_text::strtolower($user->$column);
continue;
} else if ($noemailduplicates) {
$upt->track('email', $stremailduplicate, 'error');
$upt->track('status', $strusernotupdated, 'error');
$userserrors++;
@@ -1177,7 +1187,10 @@ while ($linenum <= $previewrows and $fields = $cir->next()) {
if (!validate_email($rowcols['email'])) {
$rowcols['status'][] = get_string('invalidemail');
}
if ($DB->record_exists('user', array('email'=>$rowcols['email']))) {
$select = $DB->sql_like('email', ':email', false, true, false, '|');
$params = array('email' => $DB->sql_like_escape($rowcols['email'], '|'));
if ($DB->record_exists_select('user', $select , $params)) {
$rowcols['status'][] = $stremailduplicate;
}
}
+28
View File
@@ -328,6 +328,7 @@ class auth_plugin_db extends auth_plugin_base {
$updateuser = new stdClass();
$updateuser->id = $user->id;
$updateuser->suspended = 1;
$updateuser = $this->clean_data($updateuser);
user_update_user($updateuser, false);
$trace->output(get_string('auth_dbsuspenduser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)), 1);
}
@@ -414,6 +415,7 @@ class auth_plugin_db extends auth_plugin_base {
$updateuser = new stdClass();
$updateuser->id = $olduser->id;
$updateuser->suspended = 0;
$updateuser = $this->clean_data($updateuser);
user_update_user($updateuser);
$trace->output(get_string('auth_dbreviveduser', 'auth_db', array('name' => $username,
'id' => $olduser->id)), 1);
@@ -436,6 +438,7 @@ class auth_plugin_db extends auth_plugin_base {
$trace->output(get_string('auth_dbinsertuserduplicate', 'auth_db', array('username'=>$user->username, 'auth'=>$collision->auth)), 1);
continue;
}
$user = $this->clean_data($user);
try {
$id = user_create_user($user, false); // It is truly a new user.
$trace->output(get_string('auth_dbinsertuser', 'auth_db', array('name'=>$user->username, 'id'=>$id)), 1);
@@ -577,6 +580,7 @@ class auth_plugin_db extends auth_plugin_base {
}
if ($needsupdate) {
require_once($CFG->dirroot . '/user/lib.php');
$updateuser = $this->clean_data($updateuser);
user_update_user($updateuser);
}
return $DB->get_record('user', array('id'=>$userid, 'deleted'=>0));
@@ -906,6 +910,30 @@ class auth_plugin_db extends auth_plugin_base {
error_reporting($CFG->debug);
ob_end_flush();
}
/**
* Clean the user data that comes from an external database.
*
* @param array $user the user data to be validated against properties definition.
* @return stdClass $user the cleaned user data.
*/
public function clean_data($user) {
if (empty($user)) {
return $user;
}
foreach ($user as $field => $value) {
// Get the property parameter type and do the cleaning.
try {
$property = core_user::get_property_definition($field);
$user->$field = clean_param($value, $property['type']);
} catch (coding_exception $e) {
debugging("The property '$field' could not be cleaned.", DEBUG_DEVELOPER);
}
}
return $user;
}
}
+1 -1
View File
@@ -45,7 +45,7 @@ $string['auth_dbname'] = 'Name of the database itself. Leave empty if using an O
$string['auth_dbname_key'] = 'DB name';
$string['auth_dbpass'] = 'Password matching the above username';
$string['auth_dbpass_key'] = 'Password';
$string['auth_dbpasstype'] = '<p>Specify the format that the password field is using. MD5 hashing is useful for connecting to other common web applications like PostNuke.</p> <p>Use \'internal\' if you want to the external DB to manage usernames &amp; email addresses, but Moodle to manage passwords. If you use \'internal\', you <i>must</i> provide a populated email address field in the external DB, and you must execute both admin/cron.php and auth/db/cli/sync_users.php regularly. Moodle will send an email to new users with a temporary password.</p>';
$string['auth_dbpasstype'] = '<p>Specify the format that the password field is using. MD5 hashing is useful for connecting to other common web applications like PostNuke.</p> <p>Use \'internal\' if you want the external database to manage usernames and email addresses, but Moodle to manage passwords. If you use \'internal\', you <i>must</i> provide a populated email address field in the external database, and you must execute both admin/cron.php and auth/db/cli/sync_users.php regularly. Moodle will send an email to new users with a temporary password.</p>';
$string['auth_dbpasstype_key'] = 'Password format';
$string['auth_dbreviveduser'] = 'Revived user {$a->name} id {$a->id}';
$string['auth_dbrevivedusererror'] = 'Error reviving user {$a}';
+73
View File
@@ -381,4 +381,77 @@ class auth_db_testcase extends advanced_testcase {
$this->cleanup_auth_database();
}
/**
* Testing the clean_data() method.
*/
public function test_clean_data() {
global $DB;
$this->resetAfterTest(false);
$this->preventResetByRollback();
$this->init_auth_database();
$auth = get_auth_plugin('db');
$auth->db_init();
// Create users on external table.
$extdbuser1 = (object)array('name'=>'u1', 'pass'=>'heslo', 'email'=>'u1@example.com');
$extdbuser1->id = $DB->insert_record('auth_db_users', $extdbuser1);
// User with malicious data on the name.
$extdbuser2 = (object)array('name'=>'user<script>alert(1);</script>xss', 'pass'=>'heslo', 'email'=>'xssuser@example.com');
$extdbuser2->id = $DB->insert_record('auth_db_users', $extdbuser2);
$trace = new null_progress_trace();
// Let's test user sync make sure still works as expected..
$auth->sync_users($trace, true);
// Get the user on moodle user table.
$user2 = $DB->get_record('user', array('email'=> $extdbuser2->email, 'auth'=>'db'));
// The malicious code should be sanitized.
$this->assertEquals($user2->username, 'userscriptalert1scriptxss');
$this->assertNotEquals($user2->username, $extdbuser2->name);
// User with correct data, should be equal to external db.
$user1 = $DB->get_record('user', array('email'=> $extdbuser1->email, 'auth'=>'db'));
$this->assertEquals($extdbuser1->name, $user1->username);
$this->assertEquals($extdbuser1->email, $user1->email);
// Now, let's update the name.
$extdbuser2->name = 'user no xss anymore';
$DB->update_record('auth_db_users', $extdbuser2);
// Run sync again to update the user data.
$auth->sync_users($trace, true);
// The user information should be updated.
$user2 = $DB->get_record('user', array('username' => 'usernoxssanymore', 'auth' => 'db'));
// The spaces should be removed, as it's the username.
$this->assertEquals($user2->username, 'usernoxssanymore');
// Now let's test just the clean_data() method isolated.
// Testing PARAM_USERNAME, PARAM_NOTAGS, PARAM_RAW_TRIMMED and others.
$user3 = new stdClass();
$user3->firstname = 'John <script>alert(1)</script> Doe';
$user3->username = 'john%#&~%*_doe';
$user3->email = ' john@testing.com ';
$user3->deleted = 'no';
$user3->description = '<b>A description about myself.</b>';
$user3cleaned = $auth->clean_data($user3);
// Expected results.
$this->assertEquals($user3cleaned->firstname, 'John alert(1) Doe');
$this->assertEquals($user3cleaned->email, 'john@testing.com');
$this->assertEquals($user3cleaned->deleted, 0);
$this->assertEquals($user3->description, '<b>A description about myself.</b>');
$this->assertEquals($user3->username, 'john_doe');
// Try to clean an invalid property (fullname).
$user3->fullname = 'John Doe';
$auth->clean_data($user3);
$this->assertDebuggingCalled("The property 'fullname' could not be cleaned.");
$this->cleanup_auth_database();
}
}
+1 -1
View File
@@ -56,7 +56,7 @@ $string['auth_ldap_gracelogins_desc'] = 'Enable LDAP gracelogin support. After p
$string['auth_ldap_gracelogins_key'] = 'Grace logins';
$string['auth_ldap_groupecreators'] = 'List of groups or contexts whose members are allowed to create groups. Separate multiple groups with \';\'. Usually something like \'cn=teachers,ou=staff,o=myorg\'';
$string['auth_ldap_groupecreators_key'] = 'Group creators';
$string['auth_ldap_host_url'] = 'Specify LDAP host in URL-form like \'ldap://ldap.myorg.com/\' or \'ldaps://ldap.myorg.com/\' Separate multipleservers with \';\' to get failover support.';
$string['auth_ldap_host_url'] = 'Specify LDAP host in URL-form like \'ldap://ldap.myorg.com/\' or \'ldaps://ldap.myorg.com/\'. Separate multiple servers with \';\' to get failover support.';
$string['auth_ldap_host_url_key'] = 'Host URL';
$string['auth_ldap_changepasswordurl_key'] = 'Password-change URL';
$string['auth_ldap_ldap_encoding'] = 'Specify encoding used by LDAP server. Most probably utf-8, MS AD v2 uses default platform encoding such as cp1252, cp1250, etc.';
+1
View 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();
+2 -1
View File
@@ -23,6 +23,7 @@ if (!is_enabled_auth('shibboleth')) {
}
// Front channel logout.
$inputstream = file_get_contents("php://input");
if ($action == 'logout' && !empty($redirect)) {
if ($USER->auth == 'shibboleth') {
@@ -32,7 +33,7 @@ if ($action == 'logout' && !empty($redirect)) {
redirect($redirect);
}
} else if (!empty($HTTP_RAW_POST_DATA)) {
} else if (!empty($inputstream)) {
// Back channel logout.
// Set SOAP header.
+14 -70
View File
@@ -47,34 +47,15 @@ class behat_auth extends behat_base {
* @Given /^I log in as "(?P<username_string>(?:[^"]|\\")*)"$/
*/
public function i_log_in_as($username) {
// Visit login page.
$this->getSession()->visit($this->locate_path('login/index.php'));
// Running this step using the API rather than a chained step because
// we need to see if the 'Log in' link is available or we need to click
// the dropdown to expand the navigation bar before.
$this->getSession()->visit($this->locate_path('/'));
// Enter username and password.
$this->execute('behat_forms::i_set_the_field_to', array('Username', $this->escape($username)));
$this->execute('behat_forms::i_set_the_field_to', array('Password', $this->escape($username)));
// Generic steps (we will prefix them later expanding the navigation dropdown if necessary).
$steps = array(
new Given('I click on "' . get_string('login') . '" "link" in the ".logininfo" "css_element"'),
new Given('I set the field "' . get_string('username') . '" to "' . $this->escape($username) . '"'),
new Given('I set the field "' . get_string('password') . '" to "'. $this->escape($username) . '"'),
new Given('I press "' . get_string('login') . '"')
);
// If Javascript is disabled we have enough with these steps.
if (!$this->running_javascript()) {
return $steps;
}
// Wait for the homepage to be ready.
$this->getSession()->wait(self::TIMEOUT * 1000, self::PAGE_READY_JS);
// If it is needed, it expands the navigation bar with the 'Log in' link.
if ($clicknavbar = $this->get_expand_navbar_step()) {
array_unshift($steps, $clicknavbar);
}
return $steps;
// Press log in button, no need to check for exceptions as it will checked after this step execution.
$this->execute('behat_forms::press_button', get_string('login'));
}
/**
@@ -83,53 +64,16 @@ class behat_auth extends behat_base {
* @Given /^I log out$/
*/
public function i_log_out() {
$steps = array(new When('I follow "' . get_string('logout') . '"'));
// No need to check anything else if we run without JS.
if (!$this->running_javascript()) {
return $steps;
}
// There is no longer any need to worry about whether the navigation
// bar needs to be expanded; user_menu now lives outside the
// hamburger.
// However, the user menu *always* needs to be expanded.
$xpath = "//div[@class='usermenu']//a[contains(concat(' ', @class, ' '), ' toggle-display ')]";
array_unshift($steps, new When('I click on "'.$xpath.'" "xpath_element"'));
return $steps;
}
/**
* Returns a step to open the navigation bar if it is needed.
*
* The top log in and log out links are hidden when middle or small
* size windows (or devices) are used. This step returns a step definition
* clicking to expand the navbar if it is hidden.
*
* @return Given|bool A step definition or false if there is no need to show the navbar.
*/
protected function get_expand_navbar_step() {
// Checking if we need to click the navbar button to show the navigation menu, it
// is hidden by default when using clean theme and a medium or small screen size.
// The DOM and the JS should be all ready and loaded. Running without spinning
// as this is a widely used step and we can not spend time here trying to see
// a DOM node that is not always there (at the moment clean is not even the
// default theme...).
$navbuttonjs = "return (
Y.one('.btn-navbar') &&
Y.one('.btn-navbar').getComputedStyle('display') !== 'none'
)";
// Adding an extra click we need to show the 'Log in' link.
if (!$this->getSession()->getDriver()->evaluateScript($navbuttonjs)) {
return false;
// However, the user menu *always* needs to be expanded. if running JS.
if ($this->running_javascript()) {
$xpath = "//div[@class='usermenu']//a[contains(concat(' ', @class, ' '), ' toggle-display ')]";
$this->execute('behat_general::i_click_on', array($xpath, "xpath_element"));
}
return new Given('I click on ".btn-navbar" "css_element"');
// No need to check for exceptions as it will checked after this step execution.
$this->execute('behat_general::click_link', get_string('logout'));
}
}
+3 -1
View 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();
+35 -8
View File
@@ -1700,27 +1700,54 @@ class restore_course_structure_step extends restore_structure_step {
*/
public function process_course($data) {
global $CFG, $DB;
$context = context::instance_by_id($this->task->get_contextid());
$userid = $this->task->get_userid();
$target = $this->get_task()->get_target();
$isnewcourse = $target != backup::TARGET_CURRENT_ADDING && $target != backup::TARGET_EXISTING_ADDING;
// When restoring to a new course we can set all the things except for the ID number.
$canchangeidnumber = $isnewcourse || has_capability('moodle/course:changeidnumber', $context, $userid);
$canchangeshortname = $isnewcourse || has_capability('moodle/course:changeshortname', $context, $userid);
$canchangefullname = $isnewcourse || has_capability('moodle/course:changefullname', $context, $userid);
$canchangesummary = $isnewcourse || has_capability('moodle/course:changesummary', $context, $userid);
$data = (object)$data;
$data->id = $this->get_courseid();
$fullname = $this->get_setting_value('course_fullname');
$shortname = $this->get_setting_value('course_shortname');
$startdate = $this->get_setting_value('course_startdate');
// Calculate final course names, to avoid dupes
// Calculate final course names, to avoid dupes.
list($fullname, $shortname) = restore_dbops::calculate_course_names($this->get_courseid(), $fullname, $shortname);
// Need to change some fields before updating the course record
$data->id = $this->get_courseid();
$data->fullname = $fullname;
$data->shortname= $shortname;
if ($canchangefullname) {
$data->fullname = $fullname;
} else {
unset($data->fullname);
}
if ($canchangeshortname) {
$data->shortname = $shortname;
} else {
unset($data->shortname);
}
if (!$canchangesummary) {
unset($data->summary);
unset($data->summaryformat);
}
// Only allow the idnumber to be set if the user has permission and the idnumber is not already in use by
// another course on this site.
$context = context::instance_by_id($this->task->get_contextid());
if (!empty($data->idnumber) && has_capability('moodle/course:changeidnumber', $context, $this->task->get_userid()) &&
$this->task->is_samesite() && !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
if (!empty($data->idnumber) && $canchangeidnumber && $this->task->is_samesite()
&& !$DB->record_exists('course', array('idnumber' => $data->idnumber))) {
// Do not reset idnumber.
} else if (!$isnewcourse) {
// Prevent override when restoring as merge.
unset($data->idnumber);
} else {
$data->idnumber = '';
}
+3 -1
View 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";');
+34 -5
View File
@@ -1287,7 +1287,11 @@ abstract class restore_dbops {
* 1F - None of the above, return true => User needs to be created
*
* if restoring from another site backup (cannot match by id here, replace it by email/firstaccess combination):
* 2A - Normal check: If match by username and mnethost and (email or non-zero firstaccess) => ok, return target user
* 2A - Normal check:
* 2A1 - If match by username and mnethost and (email or non-zero firstaccess) => ok, return target user
* 2A2 - Exceptional handling (MDL-21912): Match "admin" username. Then, if import_general_duplicate_admin_allowed is
* enabled, attempt to map the admin user to the user 'admin_[oldsiteid]' if it exists. If not,
* the user 'admin_[oldsiteid]' will be created in precheck_included users
* 2B - Handle users deleted in DB and "alive" in backup file:
* 2B1 - If match by mnethost and user is deleted in DB and not empty email = md5(username) and
* (username LIKE 'backup_email.%' or non-zero firstaccess) => ok, return target user
@@ -1305,7 +1309,7 @@ abstract class restore_dbops {
* Note: for DB deleted users md5(username) is stored *sometimes* in the email field,
* hence we are looking there for usernames if not empty. See delete_user()
*/
protected static function precheck_user($user, $samesite) {
protected static function precheck_user($user, $samesite, $siteid = null) {
global $CFG, $DB;
// Handle checks from same site backups
@@ -1376,7 +1380,7 @@ abstract class restore_dbops {
// Handle checks from different site backups
} else {
// 2A - If match by username and mnethost and
// 2A1 - If match by username and mnethost and
// (email or non-zero firstaccess) => ok, return target user
if ($rec = $DB->get_record_sql("SELECT *
FROM {user} u
@@ -1393,6 +1397,14 @@ abstract class restore_dbops {
return $rec; // Matching user found, return it
}
// 2A2 - If we're allowing conflicting admins, attempt to map user to admin_[oldsiteid].
if (get_config('backup', 'import_general_duplicate_admin_allowed') && $user->username === 'admin' && $siteid
&& $user->mnethostid == $CFG->mnet_localhost_id) {
if ($rec = $DB->get_record('user', array('username' => 'admin_' . $siteid))) {
return $rec;
}
}
// 2B - Handle users deleted in DB and "alive" in backup file
// Note: for DB deleted users email is stored in username field, hence we
// are looking there for emails. See delete_user()
@@ -1500,6 +1512,9 @@ abstract class restore_dbops {
// Calculate the context we are going to use for capability checking
$context = context_course::instance($courseid);
// When conflicting users are detected we may need original site info.
$restoreinfo = restore_controller_dbops::load_controller($restoreid)->get_info();
// Calculate if we have perms to create users, by checking:
// to 'moodle/restore:createuser' and 'moodle/restore:userinfo'
// and also observe $CFG->disableusercreationonrestore
@@ -1535,14 +1550,28 @@ abstract class restore_dbops {
}
// Now, precheck that user and, based on returned results, annotate action/problem
$usercheck = self::precheck_user($user, $samesite);
$usercheck = self::precheck_user($user, $samesite, $restoreinfo->original_site_identifier_hash);
if (is_object($usercheck)) { // No problem, we have found one user in DB to be mapped to
// Annotate it, for later process. Set newitemid to mapping user->id
self::set_backup_ids_record($restoreid, 'user', $recuser->itemid, $usercheck->id);
} else if ($usercheck === false) { // Found conflict, report it as problem
$problems[] = get_string('restoreuserconflict', '', $user->username);
if (!get_config('backup', 'import_general_duplicate_admin_allowed')) {
$problems[] = get_string('restoreuserconflict', '', $user->username);
} else if ($user->username == 'admin') {
if (!$cancreateuser) {
$problems[] = get_string('restorecannotcreateuser', '', $user->username);
}
if ($user->mnethostid != $CFG->mnet_localhost_id) {
$problems[] = get_string('restoremnethostidmismatch', '', $user->username);
}
if (!$problems) {
// Duplicate admin allowed, append original site idenfitier to username.
$user->username .= '_' . $restoreinfo->original_site_identifier_hash;
self::set_backup_ids_record($restoreid, 'user', $recuser->itemid, 0, null, (array)$user);
}
}
} else if ($usercheck === true) { // User needs to be created, check if we are able
if ($cancreateuser) { // Can create user, set newitemid to 0 so will be created later
+2 -2
View File
@@ -172,8 +172,8 @@ class behat_backup extends behat_base {
"/descendant::tr[contains(., $fromcourse)]" .
"/descendant::input[@type='radio']";
$radionode = $this->find('xpath', $xpath, $exception);
$radionode->check();
$radionode->click();
$radiofield = new behat_form_field($this->getSession(), $radionode);
$radiofield->set_value(1);
$this->find_button(get_string('continue'))->press();
$this->wait();
@@ -4,7 +4,6 @@ Feature: Import course's contents into another course
As a teacher
I need to import a course contents into another course selecting what I want to import
@javascript
Scenario: Import course's contents to another course
Given the following "courses" exist:
| fullname | shortname | category |
@@ -28,7 +28,6 @@ Feature: Option to include groups and groupings when importing a course to anoth
And I follow "Course 1"
And I turn editing mode on
@javascript
Scenario: Include groups and groupings when importing a course to another course
When I import "Course 1" course into "Course 2" course using this options:
| Initial | Include groups and groupings | 1 |
@@ -40,7 +39,6 @@ Feature: Option to include groups and groupings when importing a course to anoth
And I should see "Grouping 1"
And I should see "Grouping 2"
@javascript
Scenario: Do not include groups and groupings when importing a course to another course
When I import "Course 1" course into "Course 2" course using this options:
| Initial | Include groups and groupings | 0 |
+2 -8
View File
@@ -45,13 +45,7 @@ function core_badges_myprofile_navigation(\core_user\output\myprofile\tree $tree
// Add category. This node should appear after 'contact' so that administration block appears towards the end. Refer MDL-49928.
$category = new core_user\output\myprofile\category('badges', get_string('badges', 'badges'), 'contact');
$tree->add_category($category);
// Determine context.
if (isloggedin()) {
$context = context_user::instance($USER->id);
} else {
$context = context_system::instance();
}
$context = context_user::instance($user->id);
$courseid = empty($course) ? 0 : $course->id;
if ($USER->id == $user->id || has_capability('moodle/badges:viewotherbadges', $context)) {
@@ -78,4 +72,4 @@ function core_badges_myprofile_navigation(\core_user\output\myprofile\tree $tree
}
}
}
}
}
+7 -10
View File
@@ -221,16 +221,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_cron_task"
And I wait "1" seconds
And I run the scheduled task "core\task\completion_cron_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"
@@ -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"
@@ -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
@@ -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"
@@ -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
@@ -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"
@@ -0,0 +1,36 @@
@block @block_admin_bookmarks
Feature: Add a bookmarks to an admin pages
In order to speed up common tasks
As an admin
I need to add and access pages through bookmarks
Background:
Given I log in as "admin"
And I navigate to "Scheduled tasks" node in "Site administration > Server"
And I click on "Bookmark this page" "link" in the "Admin bookmarks" "block"
And I log out
# Test bookmark functionality using the "User profile fields" page as our bookmark.
Scenario: Admin page can be bookmarked
Given I log in as "admin"
And I navigate to "User profile fields" node in "Site administration > Users > Accounts"
When I click on "Bookmark this page" "link" in the "Admin bookmarks" "block"
Then I should see "User profile fields" in the "Admin bookmarks" "block"
# See the existing bookmark is there too.
And I should see "Scheduled tasks" in the "Admin bookmarks" "block"
Scenario: Admin page can be accessed through bookmarks block
Given I log in as "admin"
And I navigate to "Notifications" node in "Site administration"
And I click on "Scheduled tasks" "link" in the "Admin bookmarks" "block"
# Verify that we are on the right page.
Then I should see "Scheduled tasks" in the "h1" "css_element"
Scenario: Admin page can be removed from bookmarks
Given I log in as "admin"
And I navigate to "Notifications" node in "Site administration"
And I click on "Scheduled tasks" "link" in the "Admin bookmarks" "block"
When I click on "Unbookmark this page" "link" in the "Admin bookmarks" "block"
Then I should see "Bookmark deleted"
And I wait to be redirected
And I should not see "Scheduled tasks" in the "Admin bookmarks" "block"
@@ -0,0 +1,81 @@
@block @block_blog_menu
Feature: Enable Block blog menu in a course
In order to enable the blog menu in a course
As a teacher
I can add blog menu block to a course
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
Scenario: Add the block to a the course when blogs are disabled
Given I log in as "admin"
And the following config values are set as admin:
| enableblogs | 0 |
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
When I add the "Blog menu" block
Then I should see "Blogging is disabled!" in the "Blog menu" "block"
Scenario: Add the block to a the course when blog associations are disabled
Given I log in as "admin"
And the following config values are set as admin:
| useblogassociations | 0 |
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
When I add the "Blog menu" block
Then I should see "Blog entries" in the "Blog menu" "block"
And I should see "Add a new entry" in the "Blog menu" "block"
And I should not see "View all entries for this course" in the "Blog menu" "block"
And I should not see "View my entries about this course" in the "Blog menu" "block"
And I should not see "Add an entry about this course" in the "Blog menu" "block"
Scenario: Add the block to a the course when blog associations are enabled
Given I log in as "admin"
And the following config values are set as admin:
| useblogassociations | 1 |
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
When I add the "Blog menu" block
Then I should see "Blog entries" in the "Blog menu" "block"
And I should see "Add a new entry" in the "Blog menu" "block"
And I should see "View all entries for this course" in the "Blog menu" "block"
And I should see "View my entries about this course" in the "Blog menu" "block"
And I should see "Add an entry about this course" in the "Blog menu" "block"
Scenario: Add the block to a the course when RSS is disabled
Given I log in as "admin"
And the following config values are set as admin:
| enablerssfeeds | 0 |
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
When I add the "Blog menu" block
Then I should not see "Blog RSS feed" in the "Blog menu" "block"
And I should see "Add a new entry" in the "Blog menu" "block"
Scenario: Add the block to a the course when RSS is enabled
Given I log in as "admin"
And the following config values are set as admin:
| enablerssfeeds | 1 |
And I log out
And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
When I add the "Blog menu" block
Then I should see "Blog RSS feed" in the "Blog menu" "block"
And I should see "Add a new entry" in the "Blog menu" "block"
@@ -0,0 +1,222 @@
@block @block_blog_menu
Feature: Enable Block blog menu in an activity
In order to enable the blog menu in an activity
As a teacher
I can add blog menu block to a course
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I add a "Assignment" to section "1" and I fill the form with:
| Assignment name | Test assignment 1 |
| Description | Offline text |
| assignsubmission_file_enabled | 0 |
And I follow "Test assignment 1"
And I add the "Blog menu" block
And I log out
Scenario: Students use the blog menu block to post blogs
Given I log in as "student1"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add a new entry"
When I set the following fields to these values:
| Entry title | S1 First Blog |
| Blog entry body | This is my awesome blog! |
And I press "Save changes"
Then I should see "S1 First Blog"
And I should see "This is my awesome blog!"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Blog entries"
And I should see "S1 First Blog"
And I should see "This is my awesome blog!"
Scenario: Students use the blog menu block to view their blogs about the activity
Given I log in as "student1"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add an entry about this Assignment"
And I set the following fields to these values:
| Entry title | S1 First Blog |
| Blog entry body | This is my awesome blog about this Assignment! |
And I press "Save changes"
And I should see "S1 First Blog"
And I should see "This is my awesome blog about this Assignment!"
And I should see "Associated Assignment: Test assignment 1"
And I log out
And I log in as "student2"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | S2 Second Blog |
| Blog entry body | My unrelated blog! |
And I press "Save changes"
And I should see "S2 Second Blog"
And I should see "My unrelated blog!"
And I should not see "Associated Assignment: Test assignment 1"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add an entry about this Assignment"
And I set the following fields to these values:
| Entry title | S2 First Blog |
| Blog entry body | My course blog is better! |
And I press "Save changes"
And I should see "S2 First Blog"
And I should see "My course blog is better!"
And I should see "Associated Assignment: Test assignment 1"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Test assignment 1"
When I follow "View my entries about this Assignment"
Then I should see "S2 First Blog"
And I should not see "S2 Second Blog"
And I should not see "S1 First Blog"
Scenario: Students use the blog menu block to view all blogs about the assignment
Given I log in as "student1"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add an entry about this Assignment"
And I set the following fields to these values:
| Entry title | S1 First Blog |
| Blog entry body | This is my awesome blog about this Assignment! |
And I press "Save changes"
And I should see "S1 First Blog"
And I should see "This is my awesome blog about this Assignment!"
And I should see "Associated Assignment: Test assignment 1"
And I log out
And I log in as "student2"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | S2 Second Blog |
| Blog entry body | My unrelated blog! |
And I press "Save changes"
And I should see "S2 Second Blog"
And I should see "My unrelated blog!"
And I should not see "Associated Assignment: Test assignment 1"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add an entry about this Assignment"
And I set the following fields to these values:
| Entry title | S2 First Blog |
| Blog entry body | My course blog is better! |
And I press "Save changes"
And I should see "S2 First Blog"
And I should see "My course blog is better!"
And I should see "Associated Assignment: Test assignment 1"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Test assignment 1"
When I follow "View all entries about this Assignment"
Then I should see "S1 First Blog"
And I should see "S2 First Blog"
And I should not see "S2 Second Blog"
Scenario: Students use the blog menu block to view all their blog entries
Given I log in as "student1"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add an entry about this Assignment"
And I set the following fields to these values:
| Entry title | S1 First Blog |
| Blog entry body | This is my awesome blog about this Assignment! |
And I press "Save changes"
And I should see "S1 First Blog"
And I should see "This is my awesome blog about this Assignment!"
And I should see "Associated Assignment: Test assignment 1"
And I log out
And I log in as "student2"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | S2 Second Blog |
| Blog entry body | My unrelated blog! |
And I press "Save changes"
And I should see "S2 Second Blog"
And I should see "My unrelated blog!"
And I should not see "Associated Assignment: Test assignment 1"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add an entry about this Assignment"
And I set the following fields to these values:
| Entry title | S2 First Blog |
| Blog entry body | My course blog is better! |
And I press "Save changes"
And I should see "S2 First Blog"
And I should see "My course blog is better!"
And I should see "Associated Assignment: Test assignment 1"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Test assignment 1"
When I follow "Blog entries"
Then I should see "S2 First Blog"
And I should see "S2 Second Blog"
And I should not see "S1 First Blog"
Scenario: Teacher searches for student blogs
Given I log in as "student1"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add an entry about this Assignment"
And I set the following fields to these values:
| Entry title | S1 First Blog |
| Blog entry body | This is my awesome blog about this Assignment! |
And I press "Save changes"
And I should see "S1 First Blog"
And I should see "This is my awesome blog about this Assignment!"
And I should see "Associated Assignment: Test assignment 1"
And I log out
And I log in as "student2"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | S2 Second Blog |
| Blog entry body | My unrelated blog! |
And I press "Save changes"
And I should see "S2 Second Blog"
And I should see "My unrelated blog!"
And I should not see "Associated Assignment: Test assignment 1"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Test assignment 1"
And I follow "Add an entry about this Assignment"
And I set the following fields to these values:
| Entry title | S2 First Blog |
| Blog entry body | My course blog is better! |
And I press "Save changes"
And I should see "S2 First Blog"
And I should see "My course blog is better!"
And I should see "Associated Assignment: Test assignment 1"
And I log out
When I log in as "teacher1"
And I follow "Course 1"
And I follow "Test assignment 1"
And I set the field "blogsearchquery" to "First"
And I press "Search"
Then I should see "S1 First Blog"
And I should see "S2 First Blog"
And I should not see "S2 Second Blog"
@@ -0,0 +1,199 @@
@block @block_blog_menu
Feature: Enable Block blog menu in a course
In order to enable the blog menu in a course
As a teacher
I can add blog menu block to a course
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | T1 |
| student1 | Student | 1 | student1@example.com | S1 |
| student2 | Student | 2 | student2@example.com | S2 |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
And I log in as "teacher1"
And I follow "Course 1"
And I turn editing mode on
And I add the "Blog menu" block
And I log out
Scenario: Students use the blog menu block to post blogs
Given I log in as "student1"
And I follow "Course 1"
And I follow "Add a new entry"
When I set the following fields to these values:
| Entry title | S1 First Blog |
| Blog entry body | This is my awesome blog! |
And I press "Save changes"
Then I should see "S1 First Blog"
And I should see "This is my awesome blog!"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Blog entries"
And I should see "S1 First Blog"
And I should see "This is my awesome blog!"
Scenario: Students use the blog menu block to view their blogs about the course
Given I log in as "student1"
And I follow "Course 1"
And I follow "Add an entry about this course"
And I set the following fields to these values:
| Entry title | S1 First Blog |
| Blog entry body | This is my awesome blog about this course! |
And I press "Save changes"
And I should see "S1 First Blog"
And I should see "This is my awesome blog about this course!"
And I should see "Associated Course: C1"
And I log out
And I log in as "student2"
And I follow "Course 1"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | S2 Second Blog |
| Blog entry body | My unrelated blog! |
And I press "Save changes"
And I should see "S2 Second Blog"
And I should see "My unrelated blog!"
And I should not see "Associated Course: C1"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Add an entry about this course"
And I set the following fields to these values:
| Entry title | S2 First Blog |
| Blog entry body | My course blog is better! |
And I press "Save changes"
And I should see "S2 First Blog"
And I should see "My course blog is better!"
And I should see "Associated Course: C1"
And I follow "Dashboard"
And I follow "Course 1"
When I follow "View my entries about this course"
Then I should see "S2 First Blog"
And I should not see "S2 Second Blog"
And I should not see "S1 First Blog"
Scenario: Students use the blog menu block to view all blogs about the course
Given I log in as "student1"
And I follow "Course 1"
And I follow "Add an entry about this course"
And I set the following fields to these values:
| Entry title | S1 First Blog |
| Blog entry body | This is my awesome blog about this course! |
And I press "Save changes"
And I should see "S1 First Blog"
And I should see "This is my awesome blog about this course!"
And I should see "Associated Course: C1"
And I log out
And I log in as "student2"
And I follow "Course 1"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | S2 Second Blog |
| Blog entry body | My unrelated blog! |
And I press "Save changes"
And I should see "S2 Second Blog"
And I should see "My unrelated blog!"
And I should not see "Associated Course: C1"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Add an entry about this course"
And I set the following fields to these values:
| Entry title | S2 First Blog |
| Blog entry body | My course blog is better! |
And I press "Save changes"
And I should see "S2 First Blog"
And I should see "My course blog is better!"
And I should see "Associated Course: C1"
And I follow "Dashboard"
And I follow "Course 1"
When I follow "View all entries for this course"
Then I should see "S1 First Blog"
And I should see "S2 First Blog"
And I should not see "S2 Second Blog"
Scenario: Students use the blog menu block to view all their blog entries
Given I log in as "student1"
And I follow "Course 1"
And I follow "Add an entry about this course"
And I set the following fields to these values:
| Entry title | S1 First Blog |
| Blog entry body | This is my awesome blog about this course! |
And I press "Save changes"
And I should see "S1 First Blog"
And I should see "This is my awesome blog about this course!"
And I should see "Associated Course: C1"
And I log out
And I log in as "student2"
And I follow "Course 1"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | S2 Second Blog |
| Blog entry body | My unrelated blog! |
And I press "Save changes"
And I should see "S2 Second Blog"
And I should see "My unrelated blog!"
And I should not see "Associated Course: C1"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Add an entry about this course"
And I set the following fields to these values:
| Entry title | S2 First Blog |
| Blog entry body | My course blog is better! |
And I press "Save changes"
And I should see "S2 First Blog"
And I should see "My course blog is better!"
And I should see "Associated Course: C1"
And I follow "Dashboard"
And I follow "Course 1"
When I follow "Blog entries"
Then I should see "S2 First Blog"
And I should see "S2 Second Blog"
And I should not see "S1 First Blog"
Scenario: Teacher searches for student blogs
Given I log in as "student1"
And I follow "Course 1"
And I follow "Add an entry about this course"
And I set the following fields to these values:
| Entry title | S1 First Blog |
| Blog entry body | This is my awesome blog about this course! |
And I press "Save changes"
And I should see "S1 First Blog"
And I should see "This is my awesome blog about this course!"
And I should see "Associated Course: C1"
And I log out
And I log in as "student2"
And I follow "Course 1"
And I follow "Add a new entry"
And I set the following fields to these values:
| Entry title | S2 Second Blog |
| Blog entry body | My unrelated blog! |
And I press "Save changes"
And I should see "S2 Second Blog"
And I should see "My unrelated blog!"
And I should not see "Associated Course: C1"
And I follow "Dashboard"
And I follow "Course 1"
And I follow "Add an entry about this course"
And I set the following fields to these values:
| Entry title | S2 First Blog |
| Blog entry body | My course blog is better! |
And I press "Save changes"
And I should see "S2 First Blog"
And I should see "My course blog is better!"
And I should see "Associated Course: C1"
And I log out
When I log in as "teacher1"
And I follow "Course 1"
And I set the field "blogsearchquery" to "First"
And I press "Search"
Then I should see "S1 First Blog"
And I should see "S2 First Blog"
And I should not see "S2 Second Blog"
@@ -0,0 +1,30 @@
@block @block_blog_menu
Feature: Enable Block blog menu on the frontpage
In order to enable the blog menu on the frontpage
As an admin
I can add blog menu block to the frontpage
Background:
Given the following "users" exist:
| username | firstname | lastname | email | idnumber |
| student1 | Student | 1 | student1@example.com | S1 |
And I log in as "admin"
And I am on site homepage
And I navigate to "Turn editing on" node in "Front page settings"
And I add the "Blog menu" block
And I log out
Scenario: Students use the blog menu block to post blogs
Given I log in as "student1"
And I am on site homepage
And I follow "Add a new entry"
When I set the following fields to these values:
| Entry title | S1 First Blog |
| Blog entry body | This is my awesome blog! |
And I press "Save changes"
Then I should see "S1 First Blog"
And I should see "This is my awesome blog!"
And I am on site homepage
And I follow "Blog entries"
And I should see "S1 First Blog"
And I should see "This is my awesome blog!"
+12 -9
View File
@@ -325,7 +325,7 @@ class block_course_overview_renderer extends plugin_renderer_base {
* @return string html string for welcome area.
*/
public function welcome_area($msgcount) {
global $USER;
global $CFG, $USER;
$output = $this->output->box_start('welcome_area');
$picture = $this->output->user_picture($USER, array('size' => 75, 'class' => 'welcome_userpicture'));
@@ -334,16 +334,19 @@ class block_course_overview_renderer extends plugin_renderer_base {
$output .= $this->output->box_start('welcome_message');
$output .= $this->output->heading(get_string('welcome', 'block_course_overview', $USER->firstname));
$plural = 's';
if ($msgcount > 0) {
$output .= get_string('youhavemessages', 'block_course_overview', $msgcount);
if ($msgcount == 1) {
$plural = '';
if (!empty($CFG->messaging)) {
$plural = 's';
if ($msgcount > 0) {
$output .= get_string('youhavemessages', 'block_course_overview', $msgcount);
if ($msgcount == 1) {
$plural = '';
}
} else {
$output .= get_string('youhavenomessages', 'block_course_overview');
}
} else {
$output .= get_string('youhavenomessages', 'block_course_overview');
$output .= html_writer::link(new moodle_url('/message/index.php'),
get_string('message'.$plural, 'block_course_overview'));
}
$output .= html_writer::link(new moodle_url('/message/index.php'), get_string('message'.$plural, 'block_course_overview'));
$output .= $this->output->box_end();
$output .= $this->output->box('', 'flush');
$output .= $this->output->box_end();
@@ -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));
}
}
}
+1
View File
@@ -49,6 +49,7 @@
.block_navigation .block_tree .tree_item.hasicon .item-content-wrap {
display: inline-block;
white-space: normal;
width: calc(100% - 21px);
}
.block_navigation .block_tree ul {
@@ -524,9 +524,9 @@ BRANCH.prototype = {
branchicon.setAttribute('title', icon.title);
}
if (icon.classes) {
for (var i in icon.classes) {
branchicon.addClass(icon.classes[i]);
}
icon.classes.forEach(function(element) {
branchicon.addClass(element);
});
}
}
File diff suppressed because one or more lines are too long
@@ -523,9 +523,9 @@ BRANCH.prototype = {
branchicon.setAttribute('title', icon.title);
}
if (icon.classes) {
for (var i in icon.classes) {
branchicon.addClass(icon.classes[i]);
}
icon.classes.forEach(function(element) {
branchicon.addClass(element);
});
}
}
+3 -3
View File
@@ -522,9 +522,9 @@ BRANCH.prototype = {
branchicon.setAttribute('title', icon.title);
}
if (icon.classes) {
for (var i in icon.classes) {
branchicon.addClass(icon.classes[i]);
}
icon.classes.forEach(function(element) {
branchicon.addClass(element);
});
}
}
+7 -3
View File
@@ -63,9 +63,13 @@ if ($id) {
$sitecontext = context_system::instance();
$usercontext = context_user::instance($userid);
$PAGE->set_context($usercontext);
$blognode = $PAGE->settingsnav->find('blogadd', null);
$blognode->make_active();
if ($modid) {
$PAGE->set_context($sitecontext);
} else {
$PAGE->set_context($usercontext);
$blognode = $PAGE->settingsnav->find('blogadd', null);
$blognode->make_active();
}
require_login($courseid);
+5 -3
View File
@@ -94,14 +94,16 @@ if (!empty($blogs)) {
$editurl = new moodle_url('/blog/external_blog_edit.php', array('id' => $blog->id));
$editicon = $OUTPUT->action_icon($editurl, new pix_icon('t/edit', get_string('editexternalblog', 'blog')));
$deletelink = new moodle_url('/blog/external_blogs.php', array('delete' => $blog->id, 'sesskey'=>sesskey()));
$deleteicon = $OUTPUT->action_icon($deletelink, new pix_icon('t/delete', get_string('deleteexternalblog', 'blog')));
$deletelink = new moodle_url('/blog/external_blogs.php', array('delete' => $blog->id, 'sesskey' => sesskey()));
$action = new confirm_action(get_string('externalblogdeleteconfirm', 'blog'));
$deleteicon = $OUTPUT->action_icon($deletelink, new pix_icon('t/delete', get_string('deleteexternalblog', 'blog')),
$action);
$table->data[] = new html_table_row(array($blog->name,
$blog->url,
userdate($blog->timefetched),
$validicon,
$editicon . '&nbsp'. $deleteicon));
$editicon . $deleteicon));
}
echo html_writer::table($table);
}
+1 -1
View File
@@ -63,7 +63,7 @@ if ($entryid and !isset($userid)) {
$userid = $entry->userid;
}
if (isset($userid) && empty($courseid)) {
if (isset($userid) && empty($courseid) && empty($modid)) {
$context = context_user::instance($userid);
} else if (!empty($courseid) && $courseid != SITEID) {
$context = context_course::instance($courseid);
+5 -1
View File
@@ -330,7 +330,11 @@ class cache_config {
if (!file_exists($cachefile)) {
throw new cache_exception('Default cache config could not be found. It should have already been created by now.');
}
include($cachefile);
if (!include($cachefile)) {
throw new cache_exception('Unable to load the cache configuration file');
}
if (!is_array($configuration)) {
throw new cache_exception('Invalid cache configuration file');
}
+2 -2
View File
@@ -190,9 +190,9 @@ class cachestore_dummy extends cache_store {
foreach ($keyvaluearray as $pair) {
$this->store[$pair['key']] = $pair['value'];
}
return count($keyvaluearray);
}
return 0;
return count($keyvaluearray);
}
/**
+13
View File
@@ -450,6 +450,13 @@ class cache implements cache_loader {
// Create an array with the original keys and the found values. This will be what we return.
$fullresult = array();
foreach ($result as $key => $value) {
if (!is_scalar($value)) {
// If data is an object it will be a reference.
// If data is an array if may contain references.
// We want to break references so that the cache cannot be modified outside of itself.
// Call the function to unreference it (in the best way possible).
$value = $this->unref($value);
}
$fullresult[$parsedkeys[$key]] = $value;
}
unset($result);
@@ -1922,6 +1929,12 @@ class cache_session extends cache {
if ($value instanceof cache_cached_object) {
/* @var cache_cached_object $value */
$value = $value->restore_object();
} else if (!is_scalar($value)) {
// If data is an object it will be a reference.
// If data is an array if may contain references.
// We want to break references so that the cache cannot be modified outside of itself.
// Call the function to unreference it (in the best way possible).
$value = $this->unref($value);
}
$return[$key] = $value;
if ($value === false) {
+27 -1
View File
@@ -407,7 +407,7 @@ class core_cache_testcase extends advanced_testcase {
$this->assertEquals('pork', $var->subobj->subobj->key);
$this->assertTrue($cache->delete('obj'));
// Death reference test... basicaly we don't want this to die.
// Death reference test... basically we don't want this to die.
$obj = new stdClass;
$obj->key = 'value';
$obj->self =& $obj;
@@ -433,6 +433,32 @@ class core_cache_testcase extends advanced_testcase {
$this->assertTrue($cache->delete('obj'));
// Death reference test on get_many... basically we don't want this to die.
$obj = new stdClass;
$obj->key = 'value';
$obj->self =& $obj;
$this->assertEquals(1, $cache->set_many(array('obj' => $obj)));
$var = $cache->get_many(array('obj'));
$this->assertInstanceOf('stdClass', $var['obj']);
$this->assertEquals('value', $var['obj']->key);
// Reference test after retrieve.
$obj = new stdClass;
$obj->key = 'value';
$this->assertEquals(1, $cache->set_many(array('obj' => $obj)));
$var1 = $cache->get_many(array('obj'));
$this->assertInstanceOf('stdClass', $var1['obj']);
$this->assertEquals('value', $var1['obj']->key);
$var1['obj']->key = 'eulav';
$this->assertEquals('eulav', $var1['obj']->key);
$var2 = $cache->get_many(array('obj'));
$this->assertInstanceOf('stdClass', $var2['obj']);
$this->assertEquals('value', $var2['obj']->key);
$this->assertTrue($cache->delete('obj'));
// Test strictness exceptions.
try {
$cache->get('exception', MUST_EXIST);
+8 -8
View File
@@ -227,21 +227,21 @@ class core_calendar_external extends external_api {
$params['options']['timeend'] = PHP_INT_MAX;
}
// Event list does not check visibility and permissions, we'll check that later.
$eventlist = calendar_get_events($params['options']['timestart'], $params['options']['timeend'], $funcparam['users'], $funcparam['groups'],
$funcparam['courses'], true, $params['options']['ignorehidden']);
// WS expects arrays.
$events = array();
foreach ($eventlist as $id => $event) {
$events[$id] = (array) $event;
}
// We need to get events asked for eventids.
$eventsbyid = calendar_get_events_by_id($params['events']['eventids']);
foreach ($eventsbyid as $eventid => $eventobj) {
if ($eventsbyid = calendar_get_events_by_id($params['events']['eventids'])) {
$eventlist += $eventsbyid;
}
foreach ($eventlist as $eventid => $eventobj) {
$event = (array) $eventobj;
if (isset($events[$eventid])) {
continue;
}
if ($hassystemcap) {
// User can see everything, no further check is needed.
$events[$eventid] = $event;
+2 -2
View File
@@ -693,8 +693,8 @@ function calendar_get_events($tstart, $tend, $users, $groups, $courses, $withdur
$whereclause = '';
$params = array();
// Quick test
if(is_bool($users) && is_bool($groups) && is_bool($courses)) {
// Quick test.
if (empty($users) && empty($groups) && empty($courses)) {
return array();
}
+1
View File
@@ -96,6 +96,7 @@ class behat_calendar extends behat_base {
$dayofmonth = "a[{$daycontains}]";
return array(
new Given('I hover "//' . $currentmonth . '/descendant::' . $daycell . '/' . $dayofmonth . '" "xpath_element"'),
new Given('I wait until the page is ready'),
);
}
+24
View File
@@ -370,6 +370,30 @@ class core_calendar_externallib_testcase extends externallib_advanced_testcase {
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
$this->assertEquals(1, count($events['events']));
$this->assertEquals(0, count($events['warnings']));
// Now, create an activity event.
$this->setAdminUser();
$nexttime = time() + DAYSECS;
$assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'duedate' => $nexttime));
$this->setUser($user);
$paramevents = array ('courseids' => array($course->id));
$options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + WEEKSECS);
$events = core_calendar_external::get_calendar_events($paramevents, $options);
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
$this->assertCount(5, $events['events']);
// Hide the assignment.
set_coursemodule_visible($assign->cmid, 0);
// Empty all the caches that may be affected by this change.
accesslib_clear_all_caches_for_unit_testing();
course_modinfo::clear_instance_cache();
$events = core_calendar_external::get_calendar_events($paramevents, $options);
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
// Expect one less.
$this->assertCount(4, $events['events']);
}
/**
+12 -11
View File
@@ -53,27 +53,28 @@ $time = optional_param('time', 0, PARAM_INT);
$url = new moodle_url('/calendar/view.php');
if ($courseid != SITEID) {
$url->param('course', $courseid);
}
if ($view !== 'upcoming') {
$url->param('view', $view);
}
// If a day, month and year were passed then convert it to a timestamp. If these were passed
// then we can assume the day, month and year are passed as Gregorian, as no where in core
// should we be passing these values rather than the time. This is done for BC.
if (!empty($day) && !empty($mon) && !empty($year)) {
if (checkdate($mon, $day, $year)) {
$time = make_timestamp($year, $mon, $day);
} else {
$time = time();
}
} else if (empty($time)) {
}
if (empty($time)) {
$time = time();
}
if ($courseid != SITEID) {
$url->param('course', $courseid);
}
if ($view !== 'upcoming') {
$time = usergetmidnight($time);
$url->param('view', $view);
}
$url->param('time', $time);
$PAGE->set_url($url);
+12 -9
View File
@@ -208,7 +208,7 @@ class core_cohort_external extends external_api {
return new external_function_parameters(
array(
'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'Cohort ID')
, 'List of cohort id. A cohort id is an integer.'),
, 'List of cohort id. A cohort id is an integer.', VALUE_DEFAULT, array()),
)
);
}
@@ -220,16 +220,19 @@ class core_cohort_external extends external_api {
* @return array of cohort objects (id, courseid, name)
* @since Moodle 2.5
*/
public static function get_cohorts($cohortids) {
public static function get_cohorts($cohortids = array()) {
global $DB;
$params = self::validate_parameters(self::get_cohorts_parameters(), array('cohortids' => $cohortids));
$cohorts = array();
foreach ($params['cohortids'] as $cohortid) {
// Validate params.
$cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
if (empty($cohortids)) {
$cohorts = $DB->get_records('cohort');
} else {
$cohorts = $DB->get_records_list('cohort', 'id', $params['cohortids']);
}
$cohortsinfo = array();
foreach ($cohorts as $cohort) {
// Now security checks.
$context = context::instance_by_id($cohort->contextid, MUST_EXIST);
if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
@@ -244,12 +247,12 @@ class core_cohort_external extends external_api {
external_format_text($cohort->description, $cohort->descriptionformat,
$context->id, 'cohort', 'description', $cohort->id);
$cohorts[] = (array) $cohort;
$cohortsinfo[] = (array) $cohort;
}
return $cohorts;
return $cohortsinfo;
}
/**
* Returns description of method result value
*
@@ -44,12 +44,11 @@ Feature: Access visible and hidden cohorts
| user | course | role |
| teacher | C1 | editingteacher |
@javascript
Scenario: Teacher can see visible cohorts defined in the above contexts
When I log in as "teacher"
And I follow "Course 1"
And I navigate to "Enrolment methods" node in "Course administration > Users"
And I set the field "Add method" to "Cohort sync"
And I select "Cohort sync" from the "Add method" singleselect
Then the "Cohort" select box should contain "Cohort in category 1"
And the "Cohort" select box should contain "System cohort"
And the "Cohort" select box should not contain "Cohort hidden in category 1"
@@ -71,13 +70,12 @@ Feature: Access visible and hidden cohorts
And the "Select members from cohort" select box should not contain "Cohort empty in category 1"
And the "Select members from cohort" select box should not contain "System empty cohort"
@javascript
Scenario: System manager can see all cohorts defined in the above contexts
When I log in as "user1"
And I am on site homepage
And I follow "Course 1"
And I navigate to "Enrolment methods" node in "Course administration > Users"
And I set the field "Add method" to "Cohort sync"
And I select "Cohort sync" from the "Add method" singleselect
Then the "Cohort" select box should contain "Cohort in category 1"
And the "Cohort" select box should contain "System cohort"
And the "Cohort" select box should contain "Cohort hidden in category 1"
@@ -99,13 +97,12 @@ Feature: Access visible and hidden cohorts
And the "Select members from cohort" select box should not contain "Cohort empty in category 1"
And the "Select members from cohort" select box should not contain "System empty cohort"
@javascript
Scenario: Category manager can see all cohorts defined in his category and visible cohorts defined above
When I log in as "user2"
And I am on site homepage
And I follow "Course 1"
And I navigate to "Enrolment methods" node in "Course administration > Users"
And I set the field "Add method" to "Cohort sync"
And I select "Cohort sync" from the "Add method" singleselect
Then the "Cohort" select box should contain "Cohort in category 1"
And the "Cohort" select box should contain "System cohort"
And the "Cohort" select box should contain "Cohort hidden in category 1"
-3
View File
@@ -21,7 +21,6 @@ Feature: Add cohorts of users
| Description | Test cohort description |
And I press "Save changes"
@javascript
Scenario: Add a cohort
When I follow "Cohorts"
Then I should see "Test cohort name"
@@ -29,7 +28,6 @@ Feature: Add cohorts of users
And I should see "Test cohort description"
And I should see "Created manually"
@javascript
Scenario: Add users to a cohort selecting them from the system users list
When I add "First User (first@example.com)" user to "333" cohort members
And I add "Second User (second@example.com)" user to "333" cohort members
@@ -39,7 +37,6 @@ Feature: Add cohorts of users
And the "Current users" select box should contain "Second User (second@example.com)"
And the "Current users" select box should not contain "Forth User (forth@example.com)"
@javascript
Scenario: Add users to a cohort using a bulk user action
When I follow "Bulk user actions"
And I set the field "Available" to "Third User"
+10 -23
View File
@@ -59,29 +59,16 @@ class behat_cohort extends behat_base {
if (!$this->getSession()->getPage()->find('css', 'input#cohort_search_q')) {
// With JS enabled we should expand a few tree nodes.
if ($this->running_javascript()) {
$parentnodes = get_string('administrationsite') . ' > ' .
get_string('users', 'admin') . ' > ' .
get_string('accounts', 'admin');
$steps = array_merge(
array(
new Given('I am on homepage'),
new Given('I navigate to "' . get_string('cohorts', 'cohort') . '" node in "' . $parentnodes . '"')
),
$steps
);
} else {
// JS disabled.
$steps = array_merge(
array(
new Given('I am on homepage'),
new Given('I follow "' . get_string('administrationsite') . '" node'),
new Given('I follow "' . get_string('cohorts', 'cohort') . '"')
),
$steps
);
}
$parentnodes = get_string('administrationsite') . ' > ' .
get_string('users', 'admin') . ' > ' .
get_string('accounts', 'admin');
$steps = array_merge(
array(
new Given('I am on homepage'),
new Given('I navigate to "' . get_string('cohorts', 'cohort') . '" node in "' . $parentnodes . '"')
),
$steps
);
}
return $steps;
-3
View File
@@ -27,7 +27,6 @@ Feature: View cohort list
| user1 | manager | System | |
| user2 | manager | Category | CAT1 |
@javascript
Scenario: Admin can see system cohorts and all cohorts
When I log in as "admin"
And I navigate to "Cohorts" node in "Site administration > Users > Accounts"
@@ -40,7 +39,6 @@ Feature: View cohort list
And I should see "Cohort in category 3"
And I log out
@javascript
Scenario: Manager can see system cohorts and all cohorts
When I log in as "user1"
And I navigate to "Cohorts" node in "Site administration > Users > Accounts"
@@ -53,7 +51,6 @@ Feature: View cohort list
And I should see "Cohort in category 3"
And I log out
@javascript
Scenario: Manager in category can see cohorts in the category
When I log in as "user2"
And I follow "Courses"
+4
View File
@@ -1,6 +1,10 @@
This files describes API changes in /cohort/ information provided here is intended
especially for developers.
=== 2.9.5 ===
* The Webservice core_cohort_get_cohorts now has the added functionality of getting all cohorts
by not passing any parameters
=== 2.6 ===
* Webservice core_cohort_update_cohorts was incorrectly specifiying float as the parameter type
for cohort id. This field is actually int and input is now reported and processed as such.
@@ -65,11 +65,13 @@ class completion_criteria_grade extends completion_criteria {
$mform->addElement('text', 'criteria_grade_value', get_string('graderequired', 'completion'));
$mform->disabledIf('criteria_grade_value', 'criteria_grade');
$mform->setType('criteria_grade_value', PARAM_RAW); // Uses unformat_float.
$mform->setDefault('criteria_grade_value', format_float($data));
// Grades are stored in Moodle with 5 decimal points, make sure we do not accidentally round them
// when setting the form value.
$mform->setDefault('criteria_grade_value', format_float($data, 5));
if ($this->id) {
$mform->setDefault('criteria_grade', 1);
$mform->setDefault('criteria_grade_value', format_float($this->gradepass));
$mform->setDefault('criteria_grade_value', format_float($this->gradepass, 5));
}
}
@@ -141,7 +143,10 @@ class completion_criteria_grade extends completion_criteria {
* @return string
*/
public function get_title_detailed() {
$graderequired = round($this->gradepass, 2).'%';
global $CFG;
require_once($CFG->libdir . '/gradelib.php');
$decimalpoints = grade_get_setting($this->course, 'decimalpoints', $CFG->grade_decimalpoints);
$graderequired = format_float($this->gradepass, $decimalpoints);
return get_string('gradexrequired', 'completion', $graderequired);
}
@@ -161,11 +166,15 @@ class completion_criteria_grade extends completion_criteria {
* @return string
*/
public function get_status($completion) {
global $CFG;
require_once($CFG->libdir . '/gradelib.php');
$decimalpoints = grade_get_setting($this->course, 'decimalpoints', $CFG->grade_decimalpoints);
$grade = $this->get_grade($completion);
$graderequired = $this->get_title_detailed();
if ($grade) {
$grade = round($grade, 2).'%';
$grade = format_float($grade, $decimalpoints);
} else {
$grade = get_string('nograde');
}
@@ -235,15 +244,19 @@ class completion_criteria_grade extends completion_criteria {
* type, criteria, requirement, status
*/
public function get_details($completion) {
global $CFG;
require_once($CFG->libdir . '/gradelib.php');
$decimalpoints = grade_get_setting($this->course, 'decimalpoints', $CFG->grade_decimalpoints);
$details = array();
$details['type'] = get_string('coursegrade', 'completion');
$details['criteria'] = get_string('graderequired', 'completion');
$details['requirement'] = round($this->gradepass, 2).'%';
$details['requirement'] = format_float($this->gradepass, $decimalpoints);
$details['status'] = '';
$grade = round($this->get_grade($completion), 2);
$grade = format_float($this->get_grade($completion), $decimalpoints);
if ($grade) {
$details['status'] = $grade.'%';
$details['status'] = $grade;
}
return $details;
+1 -1
View File
@@ -8,6 +8,6 @@
"require-dev": {
"phpunit/phpunit": "3.7.*",
"phpunit/dbUnit": "1.2.*",
"moodlehq/behat-extension": "1.29.7"
"moodlehq/behat-extension": "1.29.8"
}
}
Generated
+679 -627
View File
File diff suppressed because it is too large Load Diff
+14
View File
@@ -690,6 +690,20 @@ $CFG->admin = 'admin';
// )
// )
// );
// You can also use the following config to override default Moodle configuration for Behat.
// This config is limited to default suite and will be supported in later versions.
// It will have precedence over $CFG->behat_config.
// $CFG->behat_profiles = array(
// 'phantomjs' => array(
// 'browser' => 'phantomjs',
// 'tags' => '~@_file_upload&&~@_alert&&~@_bug_phantomjs',
// 'wd_host' => 'http://127.0.0.1:4443/wd/hub',
// 'capabilities' => array(
// 'platform' => 'Linux',
// 'version' => 2.1
// )
// ),
// );
//
// You can force the browser session (not user's sessions) to restart after N seconds. This could
// be useful if you are using a cloud-based service with time restrictions in the browser side.
+2
View File
@@ -61,6 +61,8 @@ if ($delete === md5($course->timemodified)) {
echo $OUTPUT->header();
echo $OUTPUT->heading($strdeletingcourse);
// This might take a while. Raise the execution time limit.
core_php_time_limit::raise();
// We do this here because it spits out feedback as it goes.
delete_course($course);
echo $OUTPUT->heading( get_string("deletedcourse", "", $courseshortname) );
+7 -5
View File
@@ -743,7 +743,9 @@ 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: "'" + file.name + "' " + M.util.get_string('filetoolarge', 'moodle')
});
return;
}
@@ -777,11 +779,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 +1004,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')});
}
}
};
+8
View 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);
}
+1
View File
@@ -3093,6 +3093,7 @@ class course_request {
$data->visible = $courseconfig->visible;
$data->visibleold = $data->visible;
$data->lang = $courseconfig->lang;
$data->enablecompletion = $courseconfig->enablecompletion;
$course = create_course($data);
$context = context_course::instance($course->id, MUST_EXIST);
+1
View 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') . '"')
);
+324
View File
@@ -0,0 +1,324 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Course restore tests.
*
* @package core_course
* @copyright 2016 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
require_once($CFG->dirroot . '/backup/util/includes/restore_includes.php');
/**
* Course restore testcase.
*
* @package core_course
* @copyright 2016 Frédéric Massart - FMCorz.net
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_restore_backup_testcase extends advanced_testcase {
/**
* Backup a course and return its backup ID.
*
* @param int $courseid The course ID.
* @param int $userid The user doing the backup.
* @return string
*/
protected function backup_course($courseid, $userid = 2) {
globaL $CFG;
$packer = get_file_packer('application/vnd.moodle.backup');
$bc = new backup_controller(backup::TYPE_1COURSE, $courseid, backup::FORMAT_MOODLE, backup::INTERACTIVE_NO,
backup::MODE_GENERAL, $userid);
$bc->execute_plan();
$results = $bc->get_results();
$results['backup_destination']->extract_to_pathname($packer, "$CFG->tempdir/backup/core_course_testcase");
$bc->destroy();
unset($bc);
return 'core_course_testcase';
}
/**
* Create a role with capabilities and permissions.
*
* @param string|array $caps Capability names.
* @param int $perm Constant CAP_* to apply to the capabilities.
* @return int The new role ID.
*/
protected function create_role_with_caps($caps, $perm) {
$caps = (array) $caps;
$dg = $this->getDataGenerator();
$roleid = $dg->create_role();
foreach ($caps as $cap) {
assign_capability($cap, $perm, $roleid, context_system::instance()->id, true);
}
accesslib_clear_all_caches_for_unit_testing();
return $roleid;
}
/**
* Restore a course.
*
* @param int $backupid The backup ID.
* @param int $courseid The course ID to restore in, or 0.
* @param int $userid The ID of the user performing the restore.
* @return stdClass The updated course object.
*/
protected function restore_course($backupid, $courseid, $userid) {
global $DB;
$target = backup::TARGET_CURRENT_ADDING;
if (!$courseid) {
$target = backup::TARGET_NEW_COURSE;
$categoryid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}");
$courseid = restore_dbops::create_new_course('Tmp', 'tmp', $categoryid);
}
$rc = new restore_controller($backupid, $courseid, backup::INTERACTIVE_NO, backup::MODE_GENERAL, $userid, $target);
$target == backup::TARGET_NEW_COURSE ?: $rc->get_plan()->get_setting('overwrite_conf')->set_value(true);
$rc->execute_precheck();
$rc->execute_plan();
$course = $DB->get_record('course', array('id' => $rc->get_courseid()));
$rc->destroy();
unset($rc);
return $course;
}
/**
* Restore a course to an existing course.
*
* @param int $backupid The backup ID.
* @param int $courseid The course ID to restore in.
* @param int $userid The ID of the user performing the restore.
* @return stdClass The updated course object.
*/
protected function restore_to_existing_course($backupid, $courseid, $userid = 2) {
return $this->restore_course($backupid, $courseid, $userid);
}
/**
* Restore a course to a new course.
*
* @param int $backupid The backup ID.
* @param int $userid The ID of the user performing the restore.
* @return stdClass The new course object.
*/
protected function restore_to_new_course($backupid, $userid = 2) {
return $this->restore_course($backupid, 0, $userid);
}
public function test_restore_existing_idnumber_in_new_course() {
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['idnumber' => 'ABC']);
$backupid = $this->backup_course($c1->id);
$c2 = $this->restore_to_new_course($backupid);
// The ID number is set empty.
$this->assertEquals('', $c2->idnumber);
}
public function test_restore_non_existing_idnumber_in_new_course() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['idnumber' => 'ABC']);
$backupid = $this->backup_course($c1->id);
$c1->idnumber = 'BCD';
$DB->update_record('course', $c1);
// The ID number changed.
$c2 = $this->restore_to_new_course($backupid);
$this->assertEquals('ABC', $c2->idnumber);
}
public function test_restore_existing_idnumber_in_existing_course() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['idnumber' => 'ABC']);
$c2 = $dg->create_course(['idnumber' => 'DEF']);
$backupid = $this->backup_course($c1->id);
// The ID number does not change.
$c2 = $this->restore_to_existing_course($backupid, $c2->id);
$this->assertEquals('DEF', $c2->idnumber);
$c1 = $DB->get_record('course', array('id' => $c1->id));
$this->assertEquals('ABC', $c1->idnumber);
}
public function test_restore_non_existing_idnumber_in_existing_course() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['idnumber' => 'ABC']);
$c2 = $dg->create_course(['idnumber' => 'DEF']);
$backupid = $this->backup_course($c1->id);
$c1->idnumber = 'XXX';
$DB->update_record('course', $c1);
// The ID number has changed.
$c2 = $this->restore_to_existing_course($backupid, $c2->id);
$this->assertEquals('ABC', $c2->idnumber);
}
public function test_restore_idnumber_in_existing_course_without_permissions() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$u1 = $dg->create_user();
$managers = get_archetype_roles('manager');
$manager = array_shift($managers);
$roleid = $this->create_role_with_caps('moodle/course:changeidnumber', CAP_PROHIBIT);
$dg->role_assign($manager->id, $u1->id);
$dg->role_assign($roleid, $u1->id);
$c1 = $dg->create_course(['idnumber' => 'ABC']);
$c2 = $dg->create_course(['idnumber' => 'DEF']);
$backupid = $this->backup_course($c1->id);
$c1->idnumber = 'XXX';
$DB->update_record('course', $c1);
// The ID number does not change.
$c2 = $this->restore_to_existing_course($backupid, $c2->id, $u1->id);
$this->assertEquals('DEF', $c2->idnumber);
}
public function test_restore_course_info_in_new_course() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['shortname' => 'SN', 'fullname' => 'FN', 'summary' => 'DESC', 'summaryformat' => FORMAT_MOODLE]);
$backupid = $this->backup_course($c1->id);
// The information is restored but adapted because names are already taken.
$c2 = $this->restore_to_new_course($backupid);
$this->assertEquals('SN_1', $c2->shortname);
$this->assertEquals('FN copy 1', $c2->fullname);
$this->assertEquals('DESC', $c2->summary);
$this->assertEquals(FORMAT_MOODLE, $c2->summaryformat);
}
public function test_restore_course_info_in_existing_course() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course(['shortname' => 'SN', 'fullname' => 'FN', 'summary' => 'DESC', 'summaryformat' => FORMAT_MOODLE]);
$c2 = $dg->create_course(['shortname' => 'A', 'fullname' => 'B', 'summary' => 'C', 'summaryformat' => FORMAT_PLAIN]);
$backupid = $this->backup_course($c1->id);
// The information is restored but adapted because names are already taken.
$c2 = $this->restore_to_existing_course($backupid, $c2->id);
$this->assertEquals('SN_1', $c2->shortname);
$this->assertEquals('FN copy 1', $c2->fullname);
$this->assertEquals('DESC', $c2->summary);
$this->assertEquals(FORMAT_MOODLE, $c2->summaryformat);
}
public function test_restore_course_shortname_in_existing_course_without_permissions() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$u1 = $dg->create_user();
$managers = get_archetype_roles('manager');
$manager = array_shift($managers);
$roleid = $this->create_role_with_caps('moodle/course:changeshortname', CAP_PROHIBIT);
$dg->role_assign($manager->id, $u1->id);
$dg->role_assign($roleid, $u1->id);
$c1 = $dg->create_course(['shortname' => 'SN', 'fullname' => 'FN', 'summary' => 'DESC', 'summaryformat' => FORMAT_MOODLE]);
$c2 = $dg->create_course(['shortname' => 'A1', 'fullname' => 'B1', 'summary' => 'C1', 'summaryformat' => FORMAT_PLAIN]);
// The shortname does not change.
$backupid = $this->backup_course($c1->id);
$restored = $this->restore_to_existing_course($backupid, $c2->id, $u1->id);
$this->assertEquals($c2->shortname, $restored->shortname);
$this->assertEquals('FN copy 1', $restored->fullname);
$this->assertEquals('DESC', $restored->summary);
$this->assertEquals(FORMAT_MOODLE, $restored->summaryformat);
}
public function test_restore_course_fullname_in_existing_course_without_permissions() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$u1 = $dg->create_user();
$managers = get_archetype_roles('manager');
$manager = array_shift($managers);
$roleid = $this->create_role_with_caps('moodle/course:changefullname', CAP_PROHIBIT);
$dg->role_assign($manager->id, $u1->id);
$dg->role_assign($roleid, $u1->id);
$c1 = $dg->create_course(['shortname' => 'SN', 'fullname' => 'FN', 'summary' => 'DESC', 'summaryformat' => FORMAT_MOODLE]);
$c2 = $dg->create_course(['shortname' => 'A1', 'fullname' => 'B1', 'summary' => 'C1', 'summaryformat' => FORMAT_PLAIN]);
// The fullname does not change.
$backupid = $this->backup_course($c1->id);
$restored = $this->restore_to_existing_course($backupid, $c2->id, $u1->id);
$this->assertEquals('SN_1', $restored->shortname);
$this->assertEquals($c2->fullname, $restored->fullname);
$this->assertEquals('DESC', $restored->summary);
$this->assertEquals(FORMAT_MOODLE, $restored->summaryformat);
}
public function test_restore_course_summary_in_existing_course_without_permissions() {
global $DB;
$this->resetAfterTest();
$dg = $this->getDataGenerator();
$u1 = $dg->create_user();
$managers = get_archetype_roles('manager');
$manager = array_shift($managers);
$roleid = $this->create_role_with_caps('moodle/course:changesummary', CAP_PROHIBIT);
$dg->role_assign($manager->id, $u1->id);
$dg->role_assign($roleid, $u1->id);
$c1 = $dg->create_course(['shortname' => 'SN', 'fullname' => 'FN', 'summary' => 'DESC', 'summaryformat' => FORMAT_MOODLE]);
$c2 = $dg->create_course(['shortname' => 'A1', 'fullname' => 'B1', 'summary' => 'C1', 'summaryformat' => FORMAT_PLAIN]);
// The summary and format do not change.
$backupid = $this->backup_course($c1->id);
$restored = $this->restore_to_existing_course($backupid, $c2->id, $u1->id);
$this->assertEquals('SN_1', $restored->shortname);
$this->assertEquals('FN copy 1', $restored->fullname);
$this->assertEquals($c2->summary, $restored->summary);
$this->assertEquals($c2->summaryformat, $restored->summaryformat);
}
}
+29 -3
View 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,6 +66,26 @@ class enrol_ldap_plugin extends enrol_plugin {
unset($ldap_usertypes);
$default = ldap_getdefaults();
// 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 = $default['objectclass'][$this->get_config('user_type')];
if (empty($this->userobjectclass)) {
// Can't send empty filter.
$this->userobjectclass = '(objectClass=*)';
} else if (stripos($this->userobjectclass, 'objectClass=') === 0) {
// Value is 'objectClass=some-string-here', so just add ()
// around the value (filter _must_ have them).
$this->userobjectclass = '(' . $this->userobjectclass . ')';
} else if (stripos($this->userobjectclass, '(') !== 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->userobjectclass = '(objectClass=' . $this->userobjectclass . ')';
}
// Remove the objectclass default, as the values specified there are for
// users, and we are dealing with groups here.
unset($default['objectclass']);
@@ -490,7 +517,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 +865,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'));
}
+1 -1
View File
@@ -83,7 +83,7 @@ class enrol_ldap_testcase extends advanced_testcase {
$enrol->set_config('start_tls', 0);
$enrol->set_config('ldap_version', 3);
$enrol->set_config('ldapencoding', 'utf-8');
$enrol->set_config('page_size', '2');
$enrol->set_config('pagesize', '2');
$enrol->set_config('bind_dn', TEST_ENROL_LDAP_BIND_DN);
$enrol->set_config('bind_pw', TEST_ENROL_LDAP_BIND_PW);
$enrol->set_config('course_search_sub', 0);
+7
View File
@@ -291,6 +291,13 @@ YUI.add('moodle-enrol_manual-quickenrolment', function(Y) {
y = parseInt(base.get('winHeight'))*0.1;
}
base.setXY([x,y]);
var zindex = 0;
Y.all('.moodle-has-zindex').each(function() {
if (parseInt(this.getComputedStyle('zIndex'), 10) > zindex) {
zindex = parseInt(this.getComputedStyle('zIndex'), 10);
}
});
base.setStyle('zIndex', zindex + 1);
if (this.get(UEP.USERS)===null) {
this.search(e, false);
+3 -1
View File
@@ -58,7 +58,7 @@ $data = new stdClass();
foreach ($_POST as $key => $value) {
$req .= "&$key=".urlencode($value);
$data->$key = $value;
$data->$key = fix_utf8($value);
}
$custom = explode('-', $data->custom);
@@ -211,6 +211,8 @@ if (strlen($result) > 0) {
die;
}
// Use the queried course's full name for the item_name field.
$data->item_name = $course->fullname;
// ALL CLEAR !
@@ -0,0 +1,35 @@
@core_enrol
Feature: Manage enrollments from participants page
In order to manage course participants
As a teacher
In need to get to the enrolment page from the course participants page
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Student | 1 | student1@example.com |
| student2 | Student | 2 | student2@example.com |
| teacher1 | teacher | 1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | format |
| Course 1 | C1 | topics |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| student2 | C1 | student |
| teacher1 | C1 | editingteacher |
And I log in as "teacher1"
And I follow "Course 1"
And I navigate to "Participants" node in "Current course > C1"
Scenario: Check the participants link when "All partipants" selected
Given I select "All participants" from the "roleid" singleselect
When I follow "Edit"
Then I should see "Enrolled users" in the "h2" "css_element"
And the field "Role" matches value "All"
Scenario: Check the participants link when "Student" selected
Given I select "Student" from the "roleid" singleselect
When I follow "Edit"
Then I should see "Enrolled users" in the "h2" "css_element"
And the field "Role" matches value "Student"
+1 -1
View File
@@ -136,7 +136,7 @@ class core_enrollib_testcase extends advanced_testcase {
// Make sure sorting and columns work.
$basefields = array('id', 'category', 'sortorder', 'shortname', 'fullname', 'idnumber',
'startdate', 'visible', 'groupmode', 'groupmodeforce');
'startdate', 'visible', 'groupmode', 'groupmodeforce', 'defaultgroupingid');
$courses = enrol_get_all_users_courses($user2->id, true);
$course = reset($courses);
@@ -68,7 +68,6 @@ Y.extend(AUTOLINKER, Y.Base, {
alertpanelid,
definition,
position;
var self = this;
try {
data = Y.JSON.parse(content);
if (data.success){
@@ -83,7 +82,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)){
@@ -112,8 +111,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,
@@ -1 +1 @@
YUI.add("moodle-filter_glossary-autolinker",function(e,t){var n="Glossary filter autolinker",r="width",i="height",s="menubar",o="location",u="scrollbars",a="resizable",f="toolbar",l="status",c="directories",h="fullscreen",p="dependent",d;d=function(){d.superclass.constructor.apply(this,arguments)},e.extend(d,e.Base,{overlay:null,alertpanels:{},initializer:function(){var t=this;e.delegate("click",function(n){n.preventDefault();var r="",i=e.Node.create('<div id="glossaryfilteroverlayprogress"><img src="'+M.cfg.loadingicon+'" class="spinner" />'+"</div>"),s=new e.Overlay({headerContent:r,bodyContent:i}),o,u;t.overlay=s,s.render(e.one(document.body)),o=this.getAttribute("href").replace("showentry.php","showentry_ajax.php"),u={method:"get",context:t,on:{success:function(e,t){this.display_callback(t.responseText)},failure:function(e,t){var n=t.statusText;M.cfg.developerdebug&&(t.statusText+=" ("+o+")"),this.display_callback("bodyContent",n)}}},e.io(o,u)},e.one(document.body),"a.glossary.autolink.concept")},display_callback:function(t){var n,r,i,s,o,u,a=this;try{n=e.JSON.parse(t);if(n.success){this.overlay.hide();for(r in n.entries)o=n.entries[r].definition+n.entries[r].attachments,i=new M.core.alert({title:n.entries[r].concept,draggable:!0,message:o,modal:!1,yesLabel:M.util.get_string("ok","moodle")}),e.fire(M.core.event.FILTER_CONTENT_UPDATED,{nodes:new e.NodeList(i.get("boundingBox"))}),e.Node.one("#id_yuialertconfirm-"+i.get("COUNT")).focus(),s="#moodle-dialogue-"+i.get("COUNT"),i.on("complete",this._deletealertpanel(a.alertpanels,s)),e.Object.isEmpty(this.alertpanels)||(u=this._getLatestWindowPosition(),e.Node.one(s).setXY([u[0]+10,u[1]+10])),this.alertpanels[s]=e.Node.one(s).getXY();return!0}n.error&&new M.core.ajaxException(n)}catch(f){new M.core.exception(f)}return!1},_getLatestWindowPosition:function(){var t=[0,0];return e.Object.each(this.alertpanels,function(e){e[0]>t[0]&&(t=e)}),t},_deletealertpanel:function(e,t){delete e[t]}},{NAME:n,ATTRS:{url:{validator:e.Lang.isString,value:M.cfg.wwwroot+"/mod/glossary/showentry.php"},name:{validator:e.Lang.isString,value:"glossaryconcept"},options:{getter:function(){return{width:this.get(r),height:this.get(i),menubar:this.get(s),location:this.get(o),scrollbars:this.get(u),resizable:this.get(a),toolbar:this.get(f),status:this.get(l),directories:this.get(c),fullscreen:this.get(h),dependent:this.get(p)}},readOnly:!0},width:{value:600},height:{value:450},menubar:{value:!1},location:{value:!1},scrollbars:{value:!0},resizable:{value:!0},toolbar:{value:!0},status:{value:!0},directories:{value:!1},fullscreen:{value:!1},dependent:{value:!0}}}),M.filter_glossary=M.filter_glossary||{},M.filter_glossary.init_filter_autolinking=function(e){return new d(e)}},"@VERSION@",{requires:["base","node","io-base","json-parse","event-delegate","overlay","moodle-core-event","moodle-core-notification-alert","moodle-core-notification-exception","moodle-core-notification-ajaxexception"]});
YUI.add("moodle-filter_glossary-autolinker",function(e,t){var n="Glossary filter autolinker",r="width",i="height",s="menubar",o="location",u="scrollbars",a="resizable",f="toolbar",l="status",c="directories",h="fullscreen",p="dependent",d;d=function(){d.superclass.constructor.apply(this,arguments)},e.extend(d,e.Base,{overlay:null,alertpanels:{},initializer:function(){var t=this;e.delegate("click",function(n){n.preventDefault();var r="",i=e.Node.create('<div id="glossaryfilteroverlayprogress"><img src="'+M.cfg.loadingicon+'" class="spinner" />'+"</div>"),s=new e.Overlay({headerContent:r,bodyContent:i}),o,u;t.overlay=s,s.render(e.one(document.body)),o=this.getAttribute("href").replace("showentry.php","showentry_ajax.php"),u={method:"get",context:t,on:{success:function(e,t){this.display_callback(t.responseText)},failure:function(e,t){var n=t.statusText;M.cfg.developerdebug&&(t.statusText+=" ("+o+")"),this.display_callback("bodyContent",n)}}},e.io(o,u)},e.one(document.body),"a.glossary.autolink.concept")},display_callback:function(t){var n,r,i,s,o,u;try{n=e.JSON.parse(t);if(n.success){this.overlay.hide();for(r in n.entries)o=n.entries[r].definition+n.entries[r].attachments,i=new M.core.alert({title:n.entries[r].concept,draggable:!0,message:o,modal:!1,yesLabel:M.util.get_string("ok","moodle")}),e.fire(M.core.event.FILTER_CONTENT_UPDATED,{nodes:new e.NodeList(i.get("boundingBox"))}),e.Node.one("#id_yuialertconfirm-"+i.get("COUNT")).focus(),s="#moodle-dialogue-"+i.get("COUNT"),i.on("complete",this._deletealertpanel,this,s),e.Object.isEmpty(this.alertpanels)||(u=this._getLatestWindowPosition(),e.Node.one(s).setXY([u[0]+10,u[1]+10])),this.alertpanels[s]=e.Node.one(s).getXY();return!0}n.error&&new M.core.ajaxException(n)}catch(a){new M.core.exception(a)}return!1},_getLatestWindowPosition:function(){var t=[0,0];return e.Object.each(this.alertpanels,function(e){e[0]>t[0]&&(t=e)}),t},_deletealertpanel:function(e,t){delete this.alertpanels[t]}},{NAME:n,ATTRS:{url:{validator:e.Lang.isString,value:M.cfg.wwwroot+"/mod/glossary/showentry.php"},name:{validator:e.Lang.isString,value:"glossaryconcept"},options:{getter:function(){return{width:this.get(r),height:this.get(i),menubar:this.get(s),location:this.get(o),scrollbars:this.get(u),resizable:this.get(a),toolbar:this.get(f),status:this.get(l),directories:this.get(c),fullscreen:this.get(h),dependent:this.get(p)}},readOnly:!0},width:{value:600},height:{value:450},menubar:{value:!1},location:{value:!1},scrollbars:{value:!0},resizable:{value:!0},toolbar:{value:!0},status:{value:!0},directories:{value:!1},fullscreen:{value:!1},dependent:{value:!0}}}),M.filter_glossary=M.filter_glossary||{},M.filter_glossary.init_filter_autolinking=function(e){return new d(e)}},"@VERSION@",{requires:["base","node","io-base","json-parse","event-delegate","overlay","moodle-core-event","moodle-core-notification-alert","moodle-core-notification-exception","moodle-core-notification-ajaxexception"]});

Some files were not shown because too many files have changed in this diff Show More