Compare commits

..

319 Commits

Author SHA1 Message Date
David Monllao ab9936962e Moodle release 3.4rc3 2017-11-10 15:15:37 +01:00
David Monllao d39fcc420e Merge branch 'install_master' of https://git.in.moodle.com/amosbot/moodle-install 2017-11-10 15:15:35 +01:00
David Monllao 08641175b3 Merge branch 'MDL-60764' of git://github.com/stronk7/moodle 2017-11-10 10:20:25 +01:00
Eloy Lafuente (stronk7) 66aee746e3 MDL-60764 versions: remove some outdated releases in requires 2017-11-10 09:45:56 +01:00
Damyon Wiese f738fc8efd Merge branch 'MDL-60763-master' of git://github.com/andrewnicols/moodle 2017-11-10 13:57:04 +08:00
Andrew Nicols 27973b545c MDL-60763 calendar: Use PHP concat, not JS 2017-11-10 13:56:39 +08:00
Damyon Wiese 3192438075 Merge branch 'MDL-60763-master' of git://github.com/andrewnicols/moodle 2017-11-10 13:47:05 +08:00
Andrew Nicols 41b7375c07 MDL-60763 core_calendar: Deprecate calendar_get_upcoming 2017-11-10 13:45:32 +08:00
Jun Pataleta cb04dcf4ce Merge branch 'MDL-60771-master' of git://github.com/lameze/moodle 2017-11-10 18:03:49 +13:00
Jun Pataleta c3925187ed Merge branch 'MDL-60758_master' of git://github.com/dmonllao/moodle 2017-11-10 17:21:15 +13:00
Damyon Wiese 4ceece6ea1 Merge branch 'MDL-60749-master' of git://github.com/sarjona/moodle 2017-11-10 12:05:46 +08:00
Jun Pataleta cfbc820e1b Merge branch 'MDL-60766-master' of git://github.com/ryanwyllie/moodle 2017-11-10 17:02:41 +13:00
Simey Lameze fbbcf45ef2 MDL-60771 mod_scorm: typecast score to integer 2017-11-10 12:00:17 +08:00
Andrew Nicols 6e2d8c121b Merge branch 'MDL-52838-master' of git://github.com/damyon/moodle 2017-11-10 11:38:13 +08:00
Damyon Wiese 6b2a9a6fb8 Merge branch 'MDL-60765-master' of git://github.com/andrewnicols/moodle 2017-11-10 10:55:09 +08:00
Andrew Nicols fb5bbf1424 MDL-60765 theme: Make inplace-autocomplete rule more specific
This change was intended to fix an issue with the autocomplete in RTL,
but was applied to all inplace-editables.
2017-11-10 10:29:11 +08:00
Damyon Wiese ce225e1c5e MDL-52838 workshop: Each criterion > 0 levels
Add validation to the edit assessment form so each criterion in a rubric requires at least one level.
2017-11-10 10:22:27 +08:00
Ryan Wyllie 08b7558483 MDL-60766 block_calendar_upcoming: stop summary modal not logged in
Stopped the JS from running on the block when the user is not logged in
because it attempts to load a summary modal when an event is clicked on
which results in a failed call to a webservice.
2017-11-10 02:20:32 +00:00
Andrew Nicols 9dead25fd5 MDL-60763 core_calendar: Revert removal of calendar_get_upcoming
This reverts part of commit 522b84be04.
2017-11-10 10:11:42 +08:00
Ryan Wyllie eac88b955f MDL-60766 block_calendar_month: hide nav when not logged in 2017-11-10 02:07:50 +00:00
Eloy Lafuente (stronk7) 438c98cc98 MDL-60764 versions: main version bump 2017-11-10 02:56:14 +01:00
Eloy Lafuente (stronk7) ba854606e6 MDL-60764 versions: bump all versions and requires near release
version = 2017111300 release version
requires= 2017110800 current rc2 version
2017-11-10 02:52:53 +01:00
Jake Dallimore f5b63fc829 Merge branch 'MDL-60760_master' of git://github.com/dmonllao/moodle 2017-11-10 09:32:17 +08:00
Andrew Nicols 6996fbaa0e MDL-60763 core_calendar: Revert removal of calendar_get_upcoming
Revert "MDL-60092 core_calendar: remove unused calendar_get_upcoming method"

This reverts commit 4259387ebb.
2017-11-10 08:11:36 +08:00
David Monllao 20305a8a8f MDL-60758 tool_analytics: Skip guess start if higher than guess end 2017-11-09 17:11:34 +01:00
David Monllao 5da020169e MDL-60760 tool_analytics: No onlycli link for managers 2017-11-09 17:05:08 +01:00
Sara Arjona 2f673d8b6a MDL-60749 scorm: Remove   from files when downloading 2017-11-09 10:15:03 +01:00
Sara Arjona 4bcb0a9a1d MDL-60550 user: Add more restrictions in keyword searches
Original patch provided by Tim Schroeder.
2017-11-09 16:29:29 +08:00
David Monllao a4e0b7468c Merge branch 'MDL-60718-master' of git://github.com/sarjona/moodle 2017-11-09 09:27:01 +01:00
David Monllao 7fdcdc04ff Merge branch 'MDL-60615-master' of git://github.com/damyon/moodle 2017-11-09 08:48:48 +01:00
Damyon Wiese bef5a8ca10 Merge branch 'MDL-60752-master' of git://github.com/andrewnicols/moodle 2017-11-09 15:08:11 +08:00
Damyon Wiese 246698e779 MDL-60615 imscc: string to array fix
Sloppy typing in the imscc converter is causing errors on php7.1

Variable is initialised as a string and then used as an array.
2017-11-09 15:05:36 +08:00
Jake Dallimore 4f3262fede Merge branch 'MDL-60753_master' of git://github.com/markn86/moodle 2017-11-09 14:47:23 +08:00
Andrew Nicols f169f4fd21 MDL-60752 lti: Compare text in types_config properly 2017-11-09 14:25:51 +08:00
Mark Nelson d48d1ba19a MDL-60753 report_competency: fixed dialogue failing to show 2017-11-09 14:11:24 +08:00
Jun Pataleta 7a571b813a Merge branch 'MDL-60628-master' of git://github.com/lameze/moodle 2017-11-09 17:08:46 +13:00
Simey Lameze 754016ab33 MDL-60628 calendar: amend web service unit test 2017-11-09 11:43:49 +08:00
Simey Lameze 10c17dcc10 MDL-60628 calendar: support category events on get_calendar_events ws 2017-11-09 11:29:07 +08:00
Andrew Nicols 5518a32de5 Merge branch 'MDL-60579-master-fix2' of https://github.com/damyon/moodle 2017-11-09 11:18:14 +08:00
Damyon Wiese 56f05f23c6 MDL-60579 user: Don't lose text filters
When replacing a group filter with a different group filter - don't forget all the current text filters that have
been applied.
2017-11-09 11:06:30 +08:00
Damyon Wiese bb869f05e8 MDL-60579 user: Move defines into library
Entry page user/index.php was defining constants that were used by the renderer.
This means the renderer was tied to user/index.php.
2017-11-09 11:06:30 +08:00
Andrew Nicols 7cf4331a6f MDL-60579 user: Correct PARAM type for filters
Damyon pointed out during the integration of this fixset, that the
PARAM type is incorrect.
2017-11-09 10:07:13 +08:00
Andrew Nicols 762f8dc1db MDL-60579 user: Add missing case breaks 2017-11-09 09:07:34 +08:00
Andrew Nicols a997dc9da5 MDL-60579 user: Correct search for strings 2017-11-09 09:07:21 +08:00
Andrew Nicols 446b21b512 MDL-60579 user: Check filter strings have correct part count 2017-11-09 09:07:02 +08:00
Andrew Nicols 3968d2ca7e MDL-60579 user: Prevent behat from interacting til setup complete 2017-11-09 09:05:22 +08:00
AMOS bot 68c580c903 Automatically generated installer lang files 2017-11-09 00:05:00 +00:00
Sara Arjona 0c0d460e8b MDL-60718 analytics: Avoid duplicates for users with 2 enrolments 2017-11-08 19:12:59 +01:00
David Monllao ed0e2cea00 Merge branch 'MDL-60732-master' of git://github.com/damyon/moodle 2017-11-08 17:48:07 +01:00
David Monllao 7effd6dd79 Merge branch 'MDL-60720-master' of https://github.com/sammarshallou/moodle 2017-11-08 17:27:15 +01:00
David Monllao 29adfbc3c8 Merge branch 'MDL-58699-master' of git://github.com/damyon/moodle 2017-11-08 15:56:25 +01:00
David Monllao 4e73acf3cf Merge branch 'MDL-60579-master' of https://github.com/mihailges/moodle 2017-11-08 12:16:20 +01:00
David Monllao fcafb22c22 MDL-60733 oauth: Remove outdated comment 2017-11-08 12:04:31 +01:00
David Monllao 6463a047a2 Merge branch 'MDL-60733-master' of git://github.com/damyon/moodle 2017-11-08 12:03:43 +01:00
David Monllao ccf7578373 Moodle release 3.4rc2 2017-11-08 09:47:39 +01:00
David Monllao 68ba214c65 Merge branch 'install_master' of https://git.in.moodle.com/amosbot/moodle-install 2017-11-08 09:47:38 +01:00
Damyon Wiese a471bc4971 MDL-60732 core_user: Show group filters
Always show the group filters, even if the course is in NO_GROUPS mode.
2017-11-08 16:45:42 +08:00
Damyon Wiese b6319f70bd Merge branch 'MDL-60590-master' of git://github.com/andrewnicols/moodle 2017-11-08 15:46:44 +08:00
Damyon Wiese d3882ea4a3 MDL-60733 core: B/C for google_oauth
The google_oauth class extends oauth2client which was modified to send "Accept" headers.

The "Accept" headers break picasa and could break any other plugin that was using google_oauth.
2017-11-08 15:41:53 +08:00
Andrew Nicols e759c9ed83 MDL-60590 enrol_manual: Fix for race condition in button calculation 2017-11-08 15:31:10 +08:00
Jun Pataleta c9f995872f Merge branch 'MDL-60700-master-fix' of git://github.com/andrewnicols/moodle 2017-11-08 15:17:25 +13:00
Andrew Nicols 2e36c42625 MDL-60700 calendar: Update behat test or new normal 2017-11-08 10:13:20 +08:00
Jun Pataleta 7a2300fd82 Merge branch 'MDL-60717-master-enfix' of git://github.com/mudrd8mz/moodle 2017-11-08 14:43:15 +13:00
AMOS bot f3342e1010 Automatically generated installer lang files 2017-11-08 00:05:03 +00:00
David Mudrák ea90412944 MDL-60717 lang: Reflect the string change in behat scenario file 2017-11-07 21:49:18 +01:00
Helen Foster 8d64443452 MDL-60717 lang: Merge English strings from the en_fix language pack
Significant string changes:

- needbcmath,auth_ldap - 'grace logins' changed to 'expired password
  checking'
2017-11-07 21:30:14 +01:00
sam marshall 4b0facc984 MDL-60720 core_search: Indexing halts on failed get_document
The recordsets used for search indexing sometimes return results
which are invalid (e.g. cannot be found in database). When this
happens, the result in the iterator for the recordset will be
false. Due to a bug, the iterator used to stop when it encountered
a false value, which prevented indexing from getting past the
problematic record.

In addition, the iterator that skips future data resulted in the
current() function of its parent indicator being called twice per
entry, which meant that search indexing called get_document()
twice as many times.
2017-11-07 16:36:37 +00:00
David Monllao d6d2cec4a0 Merge branch 'MDL-59758_notes-fix' of git://github.com/dmonllao/moodle 2017-11-07 14:01:35 +01:00
David Monllao 57c9b7fc37 MDL-59758 user: Notes publish state adapted to ws 2017-11-07 13:53:21 +01:00
David Monllao cae37299f3 Merge branch 'MDL-59758-master' of git://github.com/damyon/moodle 2017-11-07 12:37:30 +01:00
Mihail Geshoski c835126185 MDL-60579 enrolments: Applied filters lost on certain actions
AMOS BEGIN
    CPY [invalidrequest,enrol_lti],[invalidrequest,enrol]
AMOS END
2017-11-07 16:17:00 +08:00
Jake Dallimore 5243e93661 Merge branch 'MDL-59256_master' of git://github.com/dmonllao/moodle 2017-11-07 16:03:43 +08:00
Jake Dallimore b135c42a17 Merge branch 'MDL-60700-int-fix-1' of github.com:ryanwyllie/moodle 2017-11-07 15:44:12 +08:00
Ryan Wyllie ec8f488f30 MDL-60700 clean: add course link to activity event summary modal 2017-11-07 07:36:49 +00:00
David Monllao aa30dc8860 MDL-59256 analytics: Respect activities specific access conditions 2017-11-07 08:14:53 +01:00
David Monllao 76f98c3bd5 MDL-59256 analytics: Move get_activities method to CoI scope
CoI = community of inquiry model
2017-11-07 08:14:49 +01:00
Jake Dallimore 7783fd0ec1 Merge branch 'MDL-57772-master' of git://github.com/damyon/moodle 2017-11-07 15:01:31 +08:00
Damyon Wiese a6943ebb59 MDL-59758 core_user: Pluralise bulk actions
Don't say 1 people.
2017-11-07 14:39:04 +08:00
Jake Dallimore eaa43a132c Merge branch 'MDL-60700-master' of git://github.com/ryanwyllie/moodle 2017-11-07 14:23:50 +08:00
Damyon Wiese 81aa5e196f MDL-59758 core_user: Clean up user renderer
These functions are not used anywhere by anything.
2017-11-07 14:18:54 +08:00
Damyon Wiese b5b81de3d6 MDL-59758 core_user: Replace old bulk actions
The participants page has some clunky multi page forms for bulk actions. Replaces it with an ajax alternative.
2017-11-07 14:18:49 +08:00
Ryan Wyllie f0fc8a194a MDL-60700 calendar: remove bottom margin for description in summary 2017-11-07 06:03:01 +00:00
Andrew Nicols 03561ea899 Merge branch 'MDL-60062-master-2' of git://github.com/ryanwyllie/moodle 2017-11-07 13:49:47 +08:00
Ryan Wyllie 6688ae2ba2 MDL-60062 calendar: prevent drag and drop of override events 2017-11-07 05:47:18 +00:00
Jake Dallimore b44bc9bf6c Merge branch 'MDL-60686-master' of git://github.com/damyon/moodle 2017-11-07 13:39:33 +08:00
Damyon Wiese 65c52e05d1 MDL-58699 mod_quiz: Require javascript for popup
If any of the access rules require the attempt to open in a new window, assume we
require javascript to attempt the quiz. This makes it harder to bypass the javascript
pseudo security restrictions.
2017-11-07 12:48:21 +08:00
Damyon Wiese 1ccc9f1953 Merge branch 'MDL-60590_master-fix' of git://github.com/markn86/moodle 2017-11-07 11:59:49 +08:00
Damyon Wiese efe2681894 MDL-57772 chat: BEEP is back baby! 2017-11-07 11:25:02 +08:00
Mark Nelson e3a6d44845 MDL-60590 core_enrol: fixed failing Behat scenarios 2017-11-07 11:24:34 +08:00
Damyon Wiese 8aa01fcf61 Merge branch 'MDL-60671-master' of https://github.com/sammarshallou/moodle 2017-11-07 11:05:43 +08:00
Jake Dallimore 8072eb1384 Merge branch 'MDL-60705-master' of https://github.com/sammarshallou/moodle 2017-11-07 10:50:53 +08:00
Damyon Wiese b9ae53f86b MDL-59758 js: auto_rows module easier to use
Allow passing the direct text area, or a container.
Trigger change events on the text area, not the container.
Properly handle starting with rows > 1
2017-11-07 10:36:13 +08:00
Damyon Wiese 5616a31987 MDL-60686 core_users: Reorder filters by utility
Order the list of filters on the participant page from most useful to least useful.
2017-11-07 10:12:45 +08:00
Ryan Wyllie 8926030555 MDL-60700 calendar: normalise event type in summmary modal render 2017-11-07 02:08:00 +00:00
Jun Pataleta 13b19e40cb Merge branch 'wip-MDL-60391-master' of git://github.com/marinaglancy/moodle 2017-11-07 14:30:58 +13:00
Ryan Wyllie 478b1d194f MDL-60062 calendar: remove validate_event_timestart callback 2017-11-07 01:25:33 +00:00
Ryan Wyllie 9aac9f7074 MDL-60062 quiz: add support for drag drop of calendar events 2017-11-07 01:25:32 +00:00
Jun Pataleta 3a0951f027 Merge branch 'MDL-60361-master' of git://github.com/andrewnicols/moodle 2017-11-07 13:37:52 +13:00
Andrew Nicols 7d416f9c2c MDL-60361 calendar: Update behat test lang 2017-11-07 08:36:29 +08:00
Jun Pataleta 589b602be3 Merge branch 'MDL-60611-master-fix' of git://github.com/junpataleta/moodle 2017-11-07 11:31:45 +13:00
Jun Pataleta 8001199766 MDL-60611 calendar: Remove usage of deprecated setExpectedException() 2017-11-07 11:21:29 +13:00
Jun Pataleta a56833d49d Merge branch 'MDL-60611' of git://github.com/stronk7/moodle 2017-11-07 10:14:24 +13:00
David Monllao be88f0993d Merge branch 'MDL-60638-master' of git://github.com/lameze/moodle 2017-11-06 21:45:14 +01:00
sam marshall 11e60032be MDL-60671 core_search: Cron output should use mtrace
The mtrace function is preferable for plain text logging/progress
output because it can be redirected if necessary. By convention it
is normally used in cron and can be used in CLI tasks if required.

This change makes the text_progress_trace class use mtrace instead
of echo and then flush. (Default behaviour of mtrace is to do
exactly that, but it can be redirected too.)

Before this change, if anybody is relying on mtrace behaviour to
redirect logs of cron output, this will fail for some parts of the
search cron output (and some other places like auth plugins).
2017-11-06 11:55:29 +00:00
sam marshall 401710883b MDL-60705 core_search: Unit tests get time wrong by factor 1 million 2017-11-06 11:50:43 +00:00
Damyon Wiese 40f05d2312 Merge branch 'MDL-60590_master' of git://github.com/markn86/moodle 2017-11-06 14:18:40 +08:00
Andrew Nicols 3602df58b2 Merge branch 'MDL-60667_master' of git://github.com/dmonllao/moodle 2017-11-06 13:27:11 +08:00
Andrew Nicols f3743b3041 Merge branch 'MDL-60626-master' of git://github.com/damyon/moodle 2017-11-06 12:43:24 +08:00
Mark Nelson e2d635bbaf MDL-60590 core_user: added Behat test for cohort list presence 2017-11-06 12:39:31 +08:00
Mark Nelson a764855641 MDL-60590 core_cohort: removed unused variables from search_cohorts() 2017-11-06 12:39:31 +08:00
Mark Nelson 9b0f29239b MDL-60590 enrol_manual: button title depends on cohort list existence
Also added a SELECTORS object to tidy the code by keeping the
selectors in a central location.
2017-11-06 12:35:05 +08:00
Mark Nelson 8ce86ebba3 MDL-60590 enrol_manual: check cohorts exist before displaying select 2017-11-06 12:35:05 +08:00
Damyon Wiese 30890c2971 MDL-60626 calendar: Fix for overrides
Override events do not have the courseid so we need to get it from the module instance.
2017-11-06 12:21:27 +08:00
Mark Nelson 1bd70073c5 MDL-60590 enrol_manual: only show cohorts with necessary capabilities 2017-11-06 11:22:45 +08:00
Damyon Wiese 9e0884d410 MDL-60626 calendar: Unit tests for capabilities
Check various calendar external functions for capabilities.
2017-11-06 11:11:28 +08:00
Damyon Wiese af25b8fc7f MDL-60626 calendar: Check capabilities for api
All external functions must check all capabilities before returning data.
The calendar API itself does not check capabilities (I wish it did), so we must be
careful exposing these functions to webservices.
2017-11-06 11:11:28 +08:00
Damyon Wiese ef29782f31 Merge branch 'MDL-59858-master' of git://github.com/junpataleta/moodle 2017-11-06 10:45:34 +08:00
Damyon Wiese 1ada616c56 Merge branch 'MDL-60596_master' of git://github.com/dmonllao/moodle 2017-11-06 10:19:10 +08:00
Damyon Wiese 8443b88995 Merge branch 'MDL-60437-multilang-html-block-titles' of https://github.com/lucaboesch/moodle 2017-11-06 10:09:08 +08:00
Jake Dallimore eb354bdefa Merge branch 'MDL-60361-master' of git://github.com/andrewnicols/moodle 2017-11-06 09:29:46 +08:00
Jun Pataleta 4cd3927c4f MDL-59858 amd: Focus on the element that actually triggers the modal 2017-11-06 13:18:03 +13:00
Jun Pataleta 6a973d261a Merge branch 'MDL-60598_master' of git://github.com/dmonllao/moodle 2017-11-06 10:18:46 +13:00
Eloy Lafuente (stronk7) 796e48a58b MDL-60611 phpunit: remove deprecated stuff and other minor fixes
Thanks @scara for MDL-60611 phpunit: improved redis skipping reasons
2017-11-05 01:45:04 +01:00
AMOS bot 496b39974f Automatically generated installer lang files 2017-11-05 00:05:09 +00:00
Luca Bösch 6586118e0f MDL-60437 blocks: HTML block title multilang 2017-11-03 16:35:59 +01:00
David Monllao 4a145a8ae5 MDL-60598 analytics: Info message for predictions based on data 2017-11-03 12:45:40 +01:00
David Monllao da8a0c97f0 MDL-60596 analytics: Check cm completion if available
Previous code was restricted to course modules origin.
2017-11-03 12:44:21 +01:00
David Monllao 20b2565c38 MDL-60667 mlbackend_python: Bump to non-linear neural net version 2017-11-03 12:43:52 +01:00
David Monllao 36e84e96fc MDL-59256 analytics: Move get_activities test scope 2017-11-03 12:42:20 +01:00
David Monllao 159b4e5d8c Moodle release 3.4rc1 2017-11-03 10:26:18 +01:00
Jake Dallimore aa95085969 Merge branch 'MDL-58047-master-fix1' of http://github.com/damyon/moodle 2017-11-03 16:09:29 +08:00
Damyon Wiese 79ea89fea2 MDL-58047 assign: submission sorting
Only exclude new submission records from the sorting, draft and reopened submission are valid.
2017-11-03 15:55:10 +08:00
Jun Pataleta 928bcb02d6 Merge branch 'MDL-60657-int-fix-1' of github.com:ryanwyllie/moodle 2017-11-03 16:51:24 +13:00
Andrew Nicols b9fd516407 MDL-60361 calendar: Support all event types for calendar subs 2017-11-03 11:27:40 +08:00
Ryan Wyllie c2502375ff MDL-60657 boost: fix styles when extending modal components
I've wrapped the custom modal styling in the .modal class. This prevents
those custom styles from being pulled in when the SCSS @extend
functionality is used to extend the modal components.
2017-11-03 03:18:02 +00:00
Simey Lameze 20a5056df6 MDL-60638 calendar: fix event subscription variable names 2017-11-03 10:03:17 +08:00
Jake Dallimore 4071a2b6fe Merge branch 'MDL-60587-master-4' of git://github.com/andrewnicols/moodle 2017-11-03 09:14:52 +08:00
Andrew Nicols 6630b38c95 MDL-60587 calendar: Adjust use of time() in unit tests 2017-11-03 09:04:10 +08:00
Jake Dallimore b974b5d05d Merge branch 'MDL-60587-master-4' of git://github.com/andrewnicols/moodle 2017-11-03 08:37:31 +08:00
Andrew Nicols 1ab858314a MDL-60587 block: Correct courseid/categoryid check
pagelib uses magic getters for both the course, and category.
It does not define the magic __isset function though.
2017-11-03 08:14:56 +08:00
Eloy Lafuente (stronk7) 6be1923d81 MDL-60611 phpunit: ignore risky (empty) unit tests
At some point we should review them, removing or moving stuff.
2017-11-02 23:45:35 +01:00
Eloy Lafuente (stronk7) 801a372dad MDL-60611 phpunit: switch to namespaced phunit classes 2017-11-02 23:45:34 +01:00
Eloy Lafuente (stronk7) 1322351b92 MDL-60611 phpunit: Bump phpunit to 6.4 and travis to use PHP72 2017-11-02 23:45:21 +01:00
David Monllao bb2071ca17 Merge branch 'MDL-58047-34-sortbysubmission' of https://github.com/roperto/moodle 2017-11-02 16:57:03 +01:00
David Monllao be713b7144 Merge branch 'MDL-51945-master' of git://github.com/jleyva/moodle 2017-11-02 16:54:34 +01:00
Andrew Nicols e20752c4f5 MDL-60587 calendar: Fix un-validated params 2017-11-02 21:49:28 +08:00
Andrew Nicols 30ff29dc9f MDL-60587 calendar: Improve link params for calendar buttons 2017-11-02 21:49:28 +08:00
Andrew Nicols 6607c5ffb6 MDL-60587 calendar: Switch WS to use new helper 2017-11-02 21:49:28 +08:00
Andrew Nicols 7f14def230 MDL-60587 calendar: Add missing categoryid in upcoming WS 2017-11-02 21:49:28 +08:00
Andrew Nicols 39e364515f MDL-60587 calendar: Switch to new helper in main view 2017-11-02 21:49:28 +08:00
Andrew Nicols 557d8528eb MDL-60587 block_calendar_upcoming: Setup calendar using new helper 2017-11-02 21:49:28 +08:00
Andrew Nicols 0bd6039f40 MDL-60587 block_calendar_month: Setup calendar using new helper 2017-11-02 21:49:28 +08:00
Andrew Nicols 57e8c9f748 MDL-60587 calendar: Correct category subscription in information 2017-11-02 21:49:28 +08:00
Andrew Nicols 7b7bf31d4c MDL-60587 calendar: Add helper to setup the calendar_information 2017-11-02 21:49:28 +08:00
David Monllao 59aff5f949 Merge branch 'MDL-60634-master' of git://github.com/jleyva/moodle 2017-11-02 13:24:58 +01:00
Eloy Lafuente (stronk7) f816ea9a67 Merge branch 'MDL-60659-master' of git://github.com/junpataleta/moodle 2017-11-02 12:45:22 +01:00
David Monllao 6e3314f044 Merge branch 'MDL-60633-master' of git://github.com/andrewnicols/moodle 2017-11-02 12:04:07 +01:00
David Monllao 2a542d0265 Merge branch 'MDL-60657-master' of git://github.com/ryanwyllie/moodle 2017-11-02 11:59:30 +01:00
Damyon Wiese f18fb611c9 Merge branch 'MDL-60558-master' of git://github.com/andrewnicols/moodle 2017-11-02 15:46:42 +08:00
Andrew Nicols 43caf0217f MDL-60558 block_calendar_upcoming: Render the template when no events 2017-11-02 15:43:17 +08:00
David Monllao 7b03092121 Merge branch 'MDL-53501-master' of git://github.com/jleyva/moodle 2017-11-02 08:30:24 +01:00
Damyon Wiese 5dbd051502 Merge branch 'MDL-59950_master' of git://github.com/dmonllao/moodle 2017-11-02 14:39:32 +08:00
Jun Pataleta c39a22f600 MDL-60659 mod_forum: Use PHP EOL for line breaks in expected values 2017-11-02 19:11:00 +13:00
Ryan Wyllie f0f38bf1d3 MDL-60657 core: fix upgrade notice modal header padding 2017-11-02 06:07:00 +00:00
Damyon Wiese 41080050b0 Merge branch 'MDL-60558-master' of git://github.com/andrewnicols/moodle 2017-11-02 13:03:35 +08:00
Damyon Wiese ae348e78a0 Merge branch 'MDL-59982_master' of git://github.com/markn86/moodle 2017-11-02 12:21:39 +08:00
Damyon Wiese 71fc06aae5 Merge branch 'MDL-60645-master' of git://github.com/andrewnicols/moodle 2017-11-02 12:10:04 +08:00
Andrew Nicols e3491a093a MDL-60558 calendar: Upcoming block should use the right template 2017-11-02 11:55:49 +08:00
Andrew Nicols a0a78199b8 MDL-60558 calendar: Add event metadata to upcoming template 2017-11-02 11:55:49 +08:00
Andrew Nicols d523cbcb26 MDL-60558 calendar: Upcoming should support categories 2017-11-02 11:54:43 +08:00
Andrew Nicols 5c9acb8164 MDL-60558 calendar: Adjust URL change
The URL change belongs in the calendar_view, not the view_manager.
The view_manager is responsibe for updating the view, not for the
resultant actions from it.

This also changes to use pushState so as not to overwrite the current
location in history.
2017-11-02 11:54:13 +08:00
Andrew Nicols 8242027da3 MDL-60558 calendar: Move edit event to CRUD 2017-11-02 11:53:52 +08:00
Andrew Nicols fd2f1ae146 MDL-60558 calendar: Remove old SELECTORS 2017-11-02 11:53:49 +08:00
Andrew Nicols c8419f87c0 MDL-60558 calendar: Harden event link detection 2017-11-02 11:53:26 +08:00
Damyon Wiese 4837fea0aa Merge branch 'MDL-60619-master' of https://github.com/snake/moodle 2017-11-02 11:51:35 +08:00
Damyon Wiese 671440d708 Merge branch 'MDL-60576-master' of git://github.com/andrewnicols/moodle 2017-11-02 11:38:57 +08:00
Andrew Nicols 6c3f463dbd MDL-60558 calendar: Move the summary modal to view_manager 2017-11-02 10:56:00 +08:00
Damyon Wiese fca7e60c81 Merge branch 'MDL-60655-master' of git://github.com/junpataleta/moodle 2017-11-02 10:45:07 +08:00
Jake Dallimore 1e83eec993 Merge branch 'MDL-60555-master' of https://github.com/sammarshallou/moodle 2017-11-02 10:40:43 +08:00
Jake Dallimore 216bb33940 Merge branch 'master_MDL-60007' of https://github.com/CengageEng/moodle 2017-11-02 08:50:42 +08:00
Andrew Nicols 58280ae0b8 Merge branch 'wip-MDL-60515-master' of git://github.com/abgreeve/moodle 2017-11-02 08:47:17 +08:00
Andrew Nicols 0df5c743ad MDL-60361 calendar: Make eventtype functionality a trait 2017-11-02 07:57:44 +08:00
Jun Pataleta e8da33d86e MDL-60655 tool_httpsreplace: Use \core_text string functions 2017-11-02 10:42:33 +13:00
Jun Pataleta 02331dcd48 MDL-60655 tool_httpsreplace: Use appropriate classes for PHPDocs params 2017-11-02 10:42:33 +13:00
Eloy Lafuente (stronk7) c8e7777766 on-demand release 3.4beta+ 2017-11-01 13:40:07 +01:00
Eloy Lafuente (stronk7) d25f1c3c3c Merge branch 'MDL-60503-master' of git://github.com/damyon/moodle 2017-11-01 10:41:48 +01:00
Adrian Greeve ab2095fb0f MDL-60515 groups: Behat test for viewing the group description. 2017-11-01 15:24:38 +08:00
Adrian Greeve 6b839f3222 MDL-60515 groups: Group details template change.
The group details template has been changed to be
simpler and is styled a bit nicer.
2017-11-01 15:24:38 +08:00
Damyon Wiese 66242b95e0 MDL-60503 npm: Lock required node 8.9.x (LTS) 2017-11-01 14:52:16 +08:00
Mark Nelson 9a428ae012 MDL-59982 core_user: allow user to use filters from same category 2017-11-01 12:55:17 +08:00
Daniel Thee Roperto b8243e4164 MDL-58047 gradebook: fix sort by submission order. 2017-11-01 15:12:48 +11:00
Damyon Wiese 14a1672cff Merge branch 'MDL-52037-master-fix' of https://github.com/andrewnicols/moodle 2017-11-01 11:14:50 +08:00
Andrew Nicols 89cf38c6d9 MDL-52037 theme: Correct question feedback width
This relates to the cloze question answer when hovered.
2017-11-01 11:12:16 +08:00
Andrew Nicols 43a1e9a2a5 MDL-60645 calendar: Add missing clean classes 2017-11-01 09:36:15 +08:00
sam marshall 82735dec4d MDL-60555 core_search: Change unit tests to use fake time
Using real time caused rare failures. I've changed it to use fake
measurement for the indexing timeouts, which were unit-tested.
2017-10-31 14:48:09 +00:00
Vervoort, Claude 76f11421a4 MDL-60007 mod lti: allow delete without content-type 2017-10-31 09:57:38 -04:00
Juan Leyva 1b0978abf3 MDL-60433 mod_data: Fix strict check for groupid 2017-10-31 13:24:07 +01:00
Juan Leyva 098b16fb13 MDL-60634 tool_mobile: Change page used for https test
We need to do the HTTPS check using a page that:
- Does not redirect (login/index.php may redirect because of auth
plugins)
- Does not return moodle exceptions (some custom exceptions handlers
may launch custom HTTP errors)
2017-10-31 11:57:25 +01:00
David Monllao 4916c9bb66 MDL-52037 theme: Update compiled css 2017-10-31 11:00:59 +01:00
Luca Bösch 8fcb479246 MDL-52037 questions: „Whether correct“-feedback marks adaptive width 2017-10-31 10:42:49 +01:00
Jun Pataleta 73ec9b4778 Merge branch 'MDL-60635-master' of git://github.com/andrewnicols/moodle 2017-10-31 21:30:01 +13:00
Jake Dallimore 9cca2db570 Merge branch 'MDL-60472_master' of git://github.com/markn86/moodle 2017-10-31 15:18:37 +08:00
Jake Dallimore 9daa5874a0 Merge branch 'MDL-60607' of git://github.com/timhunt/moodle 2017-10-31 12:57:36 +08:00
Andrew Nicols 60829fbe6d Merge branch 'MDL-60631_master' of git://github.com/dmonllao/moodle 2017-10-31 12:08:01 +08:00
Mark Nelson 9f33d5ac6e MDL-60472 core_user: filter by group id when specified in URL 2017-10-31 12:05:13 +08:00
Jun Pataleta 1cc7a14ce4 Merge branch 'MDL-59936-int-fix-1' of github.com:ryanwyllie/moodle 2017-10-31 16:02:50 +13:00
Jun Pataleta 958c9c17ca Merge branch 'MDL-57560-master' of git://github.com/damyon/moodle 2017-10-31 15:40:19 +13:00
Ryan Wyllie 4397da0c4d MDL-59936 boost: improve focus outline on modal header 2017-10-31 02:38:29 +00:00
Andrew Nicols d8966238dd Merge branch 'wip-MDL-60569-master' of git://github.com/marinaglancy/moodle 2017-10-31 10:15:56 +08:00
Andrew Nicols 065a754111 Merge branch 'MDL-60575-master' of https://github.com/snake/moodle 2017-10-31 10:05:38 +08:00
Andrew Nicols 3e4de62607 Merge branch 'MDL-60139' of git://github.com/timhunt/moodle 2017-10-31 09:14:32 +08:00
Andrew Nicols a37faf9c70 MDL-60635 calendar: Fix end of month issue with previous/next month
This reverts to the previous way in which this was calculated.
2017-10-31 08:51:50 +08:00
Andrew Nicols aba60237cd Merge branch 'MDL-60522-master' of https://github.com/Kathrin84/moodle 2017-10-31 08:12:31 +08:00
Jake Dallimore 5836baf593 MDL-60619 core: fix autocomplete suggestions css for RTL 2017-10-31 07:44:05 +08:00
Jake Dallimore ed44df22a8 MDL-60575 lang: Change registration string to html from markdown 2017-10-31 07:30:33 +08:00
Andrew Nicols 314b8093e7 MDL-60633 core: Add pendingjs checks for inplace editable 2017-10-31 07:03:13 +08:00
Tim Hunt ade8dd5d08 MDL-60607 quiz reports: catch separate groups & user has no group case 2017-10-30 17:57:30 +00:00
David Monllao 28196427a2 Merge branch 'MDL-60528-m' of https://github.com/micaherne/moodle 2017-10-30 17:58:39 +01:00
Juan Leyva 8c4d7cee79 MDL-51945 core_user: Prevent duplicated emails in update_users WS 2017-10-30 17:42:03 +01:00
David Monllao 64476c520e Merge branch 'MDL-52037-cloze-whether-correct-feedback-width' of https://github.com/lucaboesch/moodle 2017-10-30 15:58:39 +01:00
Juan Leyva c851ee5ddb MDL-53501 webservice: Avoid values higher than PHP_INT_MAX
Integers coming from site settings needs casting to int to avoid
returning values higher than PHP_INT_MAX.
2017-10-30 15:55:49 +01:00
David Monllao 860d33c90a Merge branch 'MDL-60348-master' of git://github.com/jleyva/moodle 2017-10-30 15:53:53 +01:00
Tim Hunt eefa2c88e0 MDL-60607 quiz reports: move duplicate code to superclass method 2017-10-30 13:43:36 +00:00
Tim Hunt 284c795d23 MDL-60139 question manual grading: move code to reduce confusion
Move the variable definition closer to where it is used.
2017-10-30 12:55:11 +00:00
Tim Hunt 808b68835b MDL-60139 question manual grading: redisplay mark as typed if editing
When the teacher is upgrading a previously entered grade, we re-display
exactly what they typed before if possible, rather than displaying with
a set number of decimal places.
2017-10-30 12:52:02 +00:00
Tim Hunt 46a3753424 MDL-60139 phpunit: Make assertTag verify attribute values with ===
I had a test that cared about the difference between value="5.0" and value="5".
2017-10-30 12:52:00 +00:00
Juan Leyva 7336f854e6 MDL-60348 mod_workshop: Add parameters checks in evaluate_assessment WS 2017-10-30 13:50:57 +01:00
David Monllao 6065875eac Merge branch 'MDL-60433-master' of git://github.com/jleyva/moodle 2017-10-30 13:23:35 +01:00
David Monllao 3fdecc2841 Merge branch 'MDL-60377-master' of git://github.com/jleyva/moodle 2017-10-30 11:42:11 +01:00
Luca Bösch 8c00d189f4 MDL-52037 questions: „Whether correct“-feedback marks adaptive width 2017-10-30 10:34:09 +00:00
David Monllao 8c7db03a56 MDL-60631 analytics: Pass evaluation analysables filters as objects 2017-10-30 10:54:07 +01:00
Adrian Greeve c550fd0e11 MDL-60515 groups: Update to weblib group function.
Added a new function to get the url for the group picture.
2017-10-30 16:43:19 +08:00
Adrian Greeve 349b705d31 MDL-60515 groups: Display group information on the participants page. 2017-10-30 16:43:18 +08:00
Kathrin Osswald 9cc55074d5 MDL-60522 message: Removed additional tooltips
I removed the additional tooltips because I think that they are just used
in the notifications and messages context and duplicate the all over used
title tag that gives the same information when hovering. So the whole system
stays more consistently.
2017-10-30 08:01:10 +01:00
Damyon Wiese 4fab795ac9 MDL-57560 boost: File upload progress
Copy / adapt some styles from the bootstrap progress widget to match the DOM used for file upload progress.

Bootstrap changed this alot in the current beta so I opted to do a minimal change (affect the scss for boost only), rather
than adapt the HTML to something that will change again anyway when we upgrade to the release version of bootstrap 4.
2017-10-30 13:12:05 +08:00
Jake Dallimore 51af04ab2f Merge branch 'MDL-59606' of git://github.com/timhunt/moodle 2017-10-30 11:23:18 +08:00
Andrew Nicols 9e6d1a3884 Merge branch 'MDL-60605_filetree-spacing' of https://github.com/dvdcastro/moodle 2017-10-30 10:50:26 +08:00
Jun Pataleta 391ea5b7de Merge branch 'MDL-59936-master' of git://github.com/andrewnicols/moodle 2017-10-30 14:34:58 +13:00
Andrew Nicols 9d0e1fca5a Merge branch 'MDL-60360_enable_file_indexing_retroactively' of https://github.com/mattporritt/moodle 2017-10-30 09:17:13 +08:00
Ryan Wyllie 8f730872a7 MDL-59936 calendar: use event colour in summary modal header 2017-10-30 08:34:26 +08:00
Ryan Wyllie 4febb36efe MDL-59936 calendar: use icons in event summary modal 2017-10-30 08:33:54 +08:00
Ryan Wyllie 368832d51c MDL-59936 javascript: hide modal footer without content 2017-10-30 08:33:54 +08:00
Jun Pataleta cc80554892 Merge branch 'MDL-60608-master' of git://github.com/lameze/moodle 2017-10-30 11:47:54 +13:00
Jun Pataleta e905b656f5 Merge branch 'MDL-60570-master' of git://github.com/andrewnicols/moodle 2017-10-30 11:00:44 +13:00
Jun Pataleta 526d354991 Merge branch 'MDL-60572-master' of git://github.com/jleyva/moodle 2017-10-30 10:10:34 +13:00
Andrew Nicols eb3b38f04c MDL-60570 calendar: Correct course filter label in day view 2017-10-29 21:05:55 +08:00
Andrew Nicols a1b696f943 MDL-60576 calendar: Remove underline between icons and text 2017-10-29 21:01:40 +08:00
David Castro 4e52eb8eb0 MDL-60605 assignment: Added some styles to fix spacing in YUI file tree 2017-10-27 11:06:25 -05:00
Tim Hunt dae0ccfc45 MDL-59606 quiz responses: fix edge cases in the report
This patch conbines valuable contributions from Kashmira Nagwekar and
Luca Bösch. Many thanks to them. However, the final form of the fix,
and hence the blame, falls to me -- Tim.

There were several issues here:

* The load_questions_usages_by_activity method in
  question/engine/datalib.php was incorrectly treating the case
  when no data was returned. (Looks like a historic copy-pase from
  other methods that fetch one item by unique id, which therefore
  must exist.)

* The report was not correctly handling the display when the 'Which
  tries' was set to 'with, and without, attempts'.

* It was possible to select the 'All tries' option when also saying
  'Users without attempts'. This combination makes not sense, so
  a disabledIf rule was added to the form.
2017-10-27 16:57:01 +01:00
David Monllao 40f1801c4b on-demand release 3.4beta+ 2017-10-27 12:49:10 +02:00
Juan Leyva 6078d420bf MDL-60572 admin: Enforce URLs in forgottenpasswordurl setting
Also display warnings for admins.
2017-10-27 11:15:01 +02:00
Juan Leyva 2479a7c446 MDL-60572 admin: Fix forgottenpasswordurl for WS
We should expect URLs in that field.
The tool_mobile change is to not break the WS response if
forgottenpasswordurl does not contain a URL.
2017-10-27 11:12:32 +02:00
David Monllao ef9f60a635 MDL-59950 analytics: Use cognitive depth and social breadth constants 2017-10-27 10:48:42 +02:00
David Monllao db9d745c7b MDL-59950 analytics: Add constants for cognitive and social levels 2017-10-27 10:48:38 +02:00
Simey Lameze 0d049757c0 MDL-60608 calendar: change eventdefaultcontext default to 0 2017-10-27 14:19:16 +08:00
Matt Porritt 0f56f6e6da MDL-60360 Global Search: Enable file indexing message update.
If you have Global Search set up on a site without file
indexing enabled, then at a later date you enable file indexing
files associated with existing objects are not added.

The only way to have files for existing objects indexed is to
run a reindex of all content.

This patches updates the file indexing language string in the
solr search settings of Global Search to make this clear
to the site administrator.
2017-10-27 11:11:12 +11:00
David Monllao ff340a0afa Merge branch 'wip-MDL-57055-master' of git://github.com/abgreeve/moodle 2017-10-26 19:17:28 +02:00
David Monllao 62a38a4ece Merge branch 'MDL-60559-master' of git://github.com/andrewnicols/moodle 2017-10-26 19:15:44 +02:00
David Monllao a272c25649 Merge branch 'MDL-60600_master' of https://github.com/marxjohnson/moodle 2017-10-26 18:33:49 +02:00
Mark Johnson a9ca3fa167 MDL-60600 core_output: Clear static icon system cache between unit tests 2017-10-26 14:59:35 +01:00
David Monllao 7ec04e0e09 Merge branch 'MDL-60430-master' of https://github.com/mihailges/moodle 2017-10-26 10:27:34 +02:00
Jun Pataleta 1fc642324a Merge branch 'MDL-59909-master' of git://github.com/damyon/moodle 2017-10-26 21:09:12 +13:00
Damyon Wiese 7f91fb036b Merge branch 'MDL-60366_feedback_upgrade' of git://github.com/davosmith/moodle 2017-10-26 16:02:13 +08:00
David Monllao fd39db29e2 Merge branch 'MDL-59973-master' of git://github.com/damyon/moodle 2017-10-26 09:47:22 +02:00
David Monllao 341505e5de Merge branch 'MDL-60458-master' of git://github.com/damyon/moodle 2017-10-26 09:41:09 +02:00
Damyon Wiese ef7df2ae0a Merge branch 'MDL-60564_master' of git://github.com/markn86/moodle 2017-10-26 14:43:39 +08:00
Damyon Wiese ed6d81c9f7 MDL-59973 calendar: Remove duplication
The function calendar_get_default_courses is responsible for loading all variants of calendar
course lists.

1 the list of courses that the current user will see events for in the site calendar.
2 the list of courses the current user will see when they are looking at a specific course calendar.
3 the list of course calendars the current user can create / edit events in.
2017-10-26 14:39:35 +08:00
Damyon Wiese 01ed53df0f MDL-59973 calendar: Only load required fields
When loading courses for the course filter on the calendar, we only need the id and shortname.
2017-10-26 14:21:29 +08:00
Andrew Nicols 4d03dbf13d Merge branch 'wip-MDL-60543-master' of git://github.com/marinaglancy/moodle 2017-10-26 14:19:43 +08:00
Andrew Nicols 4cc469b2cc Merge branch 'MDL-60162' of git://github.com/timhunt/moodle 2017-10-26 14:04:45 +08:00
Damyon Wiese 1b7d75f19f MDL-59973 calendar: Improve help for admin setting 2017-10-26 13:28:01 +08:00
Damyon Wiese 4dc645d64d MDL-59973 calendar: Unittest calendar_get_default_courses 2017-10-26 13:28:01 +08:00
Damyon Wiese a5327e449d MDL-59973 calendar: Admin calendar course lists
Consolidate the logic for the list of courses an admin will see in the calendar.

They will see all courses if calendar_admincanseeall is enabled.

They will see only courses they are enrolled in of calendar_admincanseeall is not enabled.

They will also see the current course, if they are admin and it is not already in the list.

This applies to the course selector and the create and update event forms.

The calendar link in the navigation block has also been changed to link to the current course calendar instead of the global
one.
2017-10-26 13:28:00 +08:00
Andrew Nicols 4d4b8ae6bf Merge branch 'MDL-60535-questionbank-button-styled' of https://github.com/lucaboesch/moodle 2017-10-26 13:17:56 +08:00
Jake Dallimore 1e67827131 Merge branch 'MDL-60434_master' of git://github.com/dmonllao/moodle 2017-10-26 13:11:46 +08:00
Damyon Wiese 7dfc9ea6b3 Merge branch 'wip-MDL-60390-fix' of https://github.com/marinaglancy/moodle 2017-10-26 12:52:11 +08:00
Marina Glancy 69e89f4a82 MDL-60390 tool_messageinboud: not strict index comparision
This is something that changed in the upgraded Horde library. structure->findBody() returns string but structure->contentTypeMap is indexed with ints
2017-10-26 12:44:51 +08:00
Andrew Nicols b799cde890 Merge branch 'wip-MDL-60104-m34' of git://github.com/amygroshek/moodle 2017-10-26 11:32:54 +08:00
Andrew Nicols 9fd91f8eec Merge branch 'master-MDL-51892' of https://github.com/fwsl/moodle 2017-10-26 11:08:50 +08:00
Jake Dallimore 6e186498fd Merge branch 'MDL-59686-master' of git://github.com/lameze/moodle 2017-10-26 10:16:21 +08:00
Simey Lameze 3c2b703e00 MDL-59686 form: fix autosave support for editor field 2017-10-26 09:03:31 +08:00
Adrian Greeve e6ccfad242 MDL-57055 mod_label: Add label administration for boost.
This patch adds the label adminstration settings to the
label edit page.
2017-10-26 08:41:33 +08:00
Jun Pataleta 75909e3c92 Merge branch 'MDL-59938-master' of git://github.com/andrewnicols/moodle 2017-10-26 11:22:30 +13:00
Jun Pataleta 2a1f7a4442 Merge branch 'MDL-60571-manualgrading-savegotonextpage-styled' of https://github.com/lucaboesch/moodle 2017-10-26 10:02:27 +13:00
David Monllao 7851132177 Merge branch 'MDL-60516-master' of git://github.com/andrewnicols/moodle 2017-10-25 15:16:21 +02:00
David Monllao 4f7a80341e Merge branch 'MDL-59942-master' of git://github.com/andrewnicols/moodle 2017-10-25 15:14:54 +02:00
David Monllao 3b4e9a9fc8 Merge branch 'wip_MDL-60250_master' of git://github.com/gjb2048/moodle 2017-10-25 15:12:23 +02:00
David Monllao 507335e2de Merge branch 'MDL-60538-master' of https://github.com/mihailges/moodle 2017-10-25 15:08:49 +02:00
David Monllao 5b93dc8539 Merge branch 'MDL-60560-master' of git://github.com/andrewnicols/moodle 2017-10-25 15:06:49 +02:00
David Monllao 3a89d0b541 MDL-60434 analytics: Analysables lazy loading 2017-10-25 14:16:35 +02:00
David Monllao cc4d7ce61b MDL-60434 analytics: Missing dependency
Sneaking it in...
2017-10-25 14:13:53 +02:00
David Monllao b8bb8fe8de MDL-60434 analytics: Remove legacy is_valid method
This method was used when the API was tied to students at risk model,
this method does not make sense any more as it is up to each target
to define what is a valid course.
2017-10-25 12:47:12 +02:00
Damyon Wiese a66de3ca70 MDL-59909 calendar: Try hard not to fail the adhoc task.
Triggering a fatal error in an adhoc task is bad. It will be retried indefinitely.
Even though we are not sure how to get a module instance without a course module record,
it is possible and should not kill the Moodle site.
2017-10-25 15:42:14 +08:00
Marina Glancy 13e7626834 MDL-60569 registration: fix bug with showing email in the form 2017-10-25 15:12:43 +08:00
Mihail Geshoski 6a633d36c2 MDL-60430 assignment: Assignment save and show next for 1 user 2017-10-25 14:18:16 +08:00
Damyon Wiese 7b18365be7 MDL-60458 javascript: MathJax Workaround
Mathjax currently has a bug in an upstream library that is incorrectly
loading 'process' because it things it's running under Node.js.

We don't load modules by shortname - so it should be fine to map process to
something else.

Because of the syntax they used we need to map it to something that is already loaded
and evaluates to null (Their code will then assume the module could not be loaded and continue).

We have a handy module that is guaranteed to be loaded first and evaluates to null -> core/first.

We should remove this workaround when MathJax releases a fixed version on their CDN and update the docs.
2017-10-25 12:30:21 +08:00
Damyon Wiese 89ceede3bf MDL-60458 Mathjax: Restore the accessible config
Undo the changes to the accessible config that were introduced by the previous library upgrade.
2017-10-25 12:30:14 +08:00
Mark Nelson 8e85371800 MDL-60564 calendar: removed duplication of exporter properties 2017-10-25 12:06:26 +08:00
Marina Glancy 786d9cd3a1 MDL-60543 env: Moodle 3.2 and 3.3 do no support PHP7.2 2017-10-25 09:02:22 +08:00
Mihail Geshoski 994ccb7845 MDL-60538 lesson: check if max attempts exceeded, use new lang string 2017-10-25 09:00:20 +08:00
Tim Hunt c282157fc3 MDL-60162 quiz reports: refactor duplicated code into the base class
This is needed to fix the unit test in the last commit.
2017-10-24 18:06:46 +01:00
Tim Hunt ff456b59ea MDL-60162 quiz reports: too many rows fetched on download
This happened if one user had multiple enrolments in a course, and was
quite inefficient.
2017-10-24 18:06:44 +01:00
Amy Groshek 88924ff772 MDL-60104 mod_scorm: Fix scorm description display overflow 2017-10-24 10:42:23 -05:00
Luca Bösch 57f4e9608d MDL-60535 quiz: question bank button styled 2017-10-24 16:08:17 +01:00
Luca Bösch 1003e7e57e MDL-60571 quiz: Manual grading Save and go to next page button styled 2017-10-24 12:11:51 +01:00
Mark Nelson 429f78412d MDL-60564 calendar: removed unnecessary get_new_event_button() 2017-10-24 17:49:28 +08:00
Mark Nelson d2065abd0b MDL-60564 calendar: removed unnecessary get_course_filter_selector() 2017-10-24 17:49:26 +08:00
Grzegorz Ziółek 5fd7c11d17 MDL-51892 logging: Proper description of login errors. 2017-10-24 11:00:05 +02:00
Andrew Nicols acd146fe7c MDL-59938 calendar: Only show repeat information if repeating event 2017-10-24 16:00:36 +08:00
Andrew Nicols 79dff18711 MDL-59942 calendar: Add missing attribute to narrow day link 2017-10-24 15:35:31 +08:00
Andrew Nicols 9da0be8c46 MDL-60559 calendar: Upcoming block should respect type filter 2017-10-24 15:25:34 +08:00
Andrew Nicols 80e4426aeb MDL-60516 calendar: Update mini calendar on course change 2017-10-24 10:43:01 +08:00
Andrew Nicols 9eced5050b MDL-60560 calendar: Correct type of JS event on update 2017-10-24 09:45:27 +08:00
Gareth J Barnard 6d5f9d1218 MDL-60250 theme_bootstrapbase: Calendar popover misplaced in RTL langs. 2017-10-23 11:15:25 +01:00
Michael Aherne 71826ac268 MDL-60528 grading: Accurate class names in PHPDoc 2017-10-20 14:13:19 +01:00
Juan Leyva 21824a9325 MDL-60433 mod_data: Fix groups in Web Services 2017-10-13 12:42:10 +02:00
Marina Glancy 9016f772ce MDL-60391 libraries: patch bennu for php 7.2 2017-10-13 16:42:34 +08:00
Juan Leyva 84346754f6 MDL-60377 webservice: Format correctly text returned by WS 2017-10-10 15:06:23 +02:00
Davo Smith 5ef66eaf7e MDL-60366 mod_feedback: fix deletion of valid anonymous duplicates 2017-10-06 13:38:08 +01:00
742 changed files with 9728 additions and 4279 deletions
+5 -5
View File
@@ -13,7 +13,7 @@ language: php
php:
# We only run the highest and lowest supported versions to reduce the load on travis-ci.org.
- 7.1
- 7.2
- 7.0
addons:
@@ -30,7 +30,7 @@ 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 7.1, so run that first.
# We only run MySQL on PHP 7.2, 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.
@@ -54,12 +54,12 @@ matrix:
include:
# Run grunt/npm install on highest version ('node' is an alias for the latest node.js version.)
- php: 7.1
env: DB=none TASK=GRUNT NVM_VERSION='node'
- php: 7.2
env: DB=none TASK=GRUNT NVM_VERSION='8.9'
exclude:
# MySQL - it's just too slow.
# Exclude it on all versions except for 7.1
# Exclude it on all versions except for 7.2
- env: DB=mysqli TASK=PHPUNIT
php: 7.0
+2
View File
@@ -1754,6 +1754,7 @@
<VENDOR name="oracle" version="10.2" />
</DATABASE>
<PHP version="5.6.5" level="required">
<RESTRICT function="restrict_php_version_72" message="unsupportedphpversion72" />
</PHP>
<PCREUNICODE level="optional">
<FEEDBACK>
@@ -1919,6 +1920,7 @@
<VENDOR name="oracle" version="10.2" />
</DATABASE>
<PHP version="5.6.5" level="required">
<RESTRICT function="restrict_php_version_72" message="unsupportedphpversion72" />
</PHP>
<PCREUNICODE level="optional">
<FEEDBACK>
+2 -1
View File
@@ -868,6 +868,7 @@ $cachewarnings = cache_helper::warnings();
$eventshandlers = $DB->get_records_sql('SELECT DISTINCT component FROM {events_handlers}');
$themedesignermode = !empty($CFG->themedesignermode);
$mobileconfigured = !empty($CFG->enablemobilewebservice);
$invalidforgottenpasswordurl = !empty($CFG->forgottenpasswordurl) && empty(clean_param($CFG->forgottenpasswordurl, PARAM_URL));
// Check if a directory with development libraries exists.
if (empty($CFG->disabledevlibdirscheck) && (is_dir($CFG->dirroot.'/vendor') || is_dir($CFG->dirroot.'/node_modules'))) {
@@ -885,4 +886,4 @@ $output = $PAGE->get_renderer('core', 'admin');
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed, $cronoverdue, $dbproblems,
$maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
$registered, $cachewarnings, $eventshandlers, $themedesignermode, $devlibdir,
$mobileconfigured, $overridetossl);
$mobileconfigured, $overridetossl, $invalidforgottenpasswordurl);
+1 -1
View File
@@ -36,6 +36,6 @@ class core_register_renderer extends plugin_renderer_base {
* @return string
*/
public function moodleorg_registration_message() {
return format_text(get_string('registermoodlenet', 'admin'), FORMAT_MARKDOWN, ['noclean' => true]);
return format_text(get_string('registermoodlenet', 'admin'), FORMAT_HTML, ['noclean' => true]);
}
}
+21 -1
View File
@@ -280,6 +280,7 @@ class core_admin_renderer extends plugin_renderer_base {
* @param bool $devlibdir Warn about development libs directory presence.
* @param bool $mobileconfigured Whether the mobile web services have been enabled
* @param bool $overridetossl Whether or not ssl is being forced.
* @param bool $invalidforgottenpasswordurl Whether the forgotten password URL does not link to a valid URL.
*
* @return string HTML to output.
*/
@@ -287,7 +288,7 @@ class core_admin_renderer extends plugin_renderer_base {
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch,
$buggyiconvnomb, $registered, array $cachewarnings = array(), $eventshandlers = 0,
$themedesignermode = false, $devlibdir = false, $mobileconfigured = false,
$overridetossl = false) {
$overridetossl = false, $invalidforgottenpasswordurl = false) {
global $CFG;
$output = '';
@@ -308,6 +309,7 @@ class core_admin_renderer extends plugin_renderer_base {
$output .= $this->events_handlers($eventshandlers);
$output .= $this->registration_warning($registered);
$output .= $this->mobile_configuration_warning($mobileconfigured);
$output .= $this->forgotten_password_url_warning($invalidforgottenpasswordurl);
//////////////////////////////////////////////////////////////////////////////////////////////////
//// IT IS ILLEGAL AND A VIOLATION OF THE GPL TO HIDE, REMOVE OR MODIFY THIS COPYRIGHT NOTICE ///
@@ -866,6 +868,24 @@ class core_admin_renderer extends plugin_renderer_base {
return $output;
}
/**
* Display a warning about the forgotten password URL not linking to a valid URL.
*
* @param boolean $invalidforgottenpasswordurl true if the forgotten password URL is not valid
* @return string HTML to output.
*/
protected function forgotten_password_url_warning($invalidforgottenpasswordurl) {
$output = '';
if ($invalidforgottenpasswordurl) {
$settingslink = new moodle_url('/admin/settings.php', ['section' => 'manageauths']);
$configurebutton = $this->single_button($settingslink, get_string('check', 'moodle'));
$output .= $this->warning(get_string('invalidforgottenpasswordurl', 'admin') . '&nbsp;' . $configurebutton,
'error alert alert-danger');
}
return $output;
}
/**
* Helper method to render the information about the available Moodle update
*
+1 -1
View File
@@ -102,7 +102,7 @@ if ($hassiteconfig) {
$temp->add(new admin_setting_configtext('alternateloginurl', new lang_string('alternateloginurl', 'auth'),
new lang_string('alternatelogin', 'auth', htmlspecialchars(get_login_url())), ''));
$temp->add(new admin_setting_configtext('forgottenpasswordurl', new lang_string('forgottenpasswordurl', 'auth'),
new lang_string('forgottenpassword', 'auth'), ''));
new lang_string('forgottenpassword', 'auth'), '', PARAM_URL));
$temp->add(new admin_setting_confightmleditor('auth_instructions', new lang_string('instructions', 'auth'),
new lang_string('authinstructions', 'auth'), ''));
$setting = new admin_setting_configtext('allowemailaddresses', new lang_string('allowemailaddresses', 'admin'),
@@ -264,8 +264,13 @@ class models_list implements \renderable, \templatable {
} else {
$url = new \moodle_url('/admin/settings.php', array('section' => 'analyticssettings'),
'id_s_analytics_onlycli');
$langstrid = 'clievaluationandpredictionsnoadmin';
if (is_siteadmin()) {
$langstrid = 'clievaluationandpredictions';
}
$data->infos = array(
(object)array('message' => get_string('clievaluationandpredictions', 'tool_analytics', $url->out()),
(object)array('message' => get_string($langstrid, 'tool_analytics', $url->out()),
'closebutton' => true)
);
}
@@ -117,12 +117,21 @@ function tool_analytics_calculate_course_dates($course, $options) {
$notification = $course->shortname . ' (id = ' . $course->id . '): ';
$originalenddate = null;
$guessedstartdate = null;
$guessedenddate = null;
$samestartdate = null;
$lowerenddate = null;
if ($options['guessstart'] || $options['guessall']) {
$originalstartdate = $course->startdate;
$guessedstartdate = $courseman->guess_start();
if ($guessedstartdate == $originalstartdate) {
$samestartdate = ($guessedstartdate == $originalstartdate);
$lowerenddate = ($course->enddate && ($course->enddate < $guessedstartdate));
if ($samestartdate) {
if (!$guessedstartdate) {
$notification .= PHP_EOL . ' ' . get_string('cantguessstartdate', 'tool_analytics');
} else {
@@ -131,6 +140,9 @@ function tool_analytics_calculate_course_dates($course, $options) {
}
} else if (!$guessedstartdate) {
$notification .= PHP_EOL . ' ' . get_string('cantguessstartdate', 'tool_analytics');
} else if ($lowerenddate) {
$notification .= PHP_EOL . ' ' . get_string('cantguessstartdate', 'tool_analytics') . ': ' .
get_string('enddatebeforestartdate', 'error') . ' - ' . userdate($guessedstartdate);
} else {
// Update it to something we guess.
@@ -151,16 +163,21 @@ function tool_analytics_calculate_course_dates($course, $options) {
if ($options['guessend'] || $options['guessall']) {
if (!empty($lowerenddate) && !empty($guessedstartdate)) {
$course->startdate = $guessedstartdate;
}
$originalenddate = $course->enddate;
$format = course_get_format($course);
$formatoptions = $format->get_format_options();
if ($course->format === 'weeks' && $formatoptions['automaticenddate']) {
// Special treatment for weeks with automatic end date.
// Change this for a course formats API level call in MDL-60702.
if (method_exists($format, 'update_end_date') && $formatoptions['automaticenddate']) {
// Special treatment for weeks-based formats with automatic end date.
if ($options['update']) {
format_weeks::update_end_date($course->id);
$format::update_end_date($course->id);
$course->enddate = $DB->get_field('course', 'enddate', array('id' => $course->id));
$notification .= PHP_EOL . ' ' . get_string('weeksenddateautomaticallyset', 'tool_analytics') . ': ' .
userdate($course->enddate);
@@ -195,10 +212,8 @@ function tool_analytics_calculate_course_dates($course, $options) {
$updateit = true;
}
if ($options['update']) {
if ($course->enddate > $course->startdate) {
update_course($course);
}
if ($options['update'] && $updateit) {
update_course($course);
}
}
}
@@ -33,6 +33,7 @@ $string['clearpredictions'] = 'Clear predictions';
$string['clearmodelpredictions'] = 'Are you sure you want to clear all "{$a}" predictions?';
$string['clienablemodel'] = 'You can enable the model by selecting a time-splitting method by its ID. Note that you can also enable it later using the web interface (\'none\' to exit).';
$string['clievaluationandpredictions'] = 'A scheduled task iterates through enabled models and gets predictions. Models evaluation via the web interface is disabled. You can allow these processes to be executed manually via the web interface by disabling the <a href="{$a}">\'onlycli\'</a> analytics setting.';
$string['clievaluationandpredictionsnoadmin'] = 'A scheduled task iterates through enabled models and gets predictions. Models evaluation via the web interface is disabled. It may be enabled by a site administrator.';
$string['editmodel'] = 'Edit "{$a}" model';
$string['edittrainedwarning'] = 'This model has already been trained. Note that changing its indicators or its time-splitting method will delete its previous predictions and start generating new predictions.';
$string['enabled'] = 'Enabled';
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_analytics'; // Full name of the plugin (used for diagnostics).
+3 -3
View File
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'tool_assignmentupgrade';
$plugin->dependencies = array('mod_assign' => 2017050500);
$plugin->dependencies = array('mod_assign' => 2017110800);
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'tool_availabilityconditions';
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_behat'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_capability'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -25,8 +25,8 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_cohortroles'; // Full name of the plugin (used for diagnostics).
$plugin->dependencies = array(
+2 -2
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'tool_customlang'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_dbtransfer'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'tool_filetypes';
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'tool_generator';
+2 -2
View File
@@ -25,8 +25,8 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_health'; // Full name of the plugin (used for diagnostics)
$plugin->maturity = MATURITY_ALPHA; // this version's maturity level
@@ -24,6 +24,9 @@
namespace tool_httpsreplace;
use database_column_info;
use progress_bar;
defined('MOODLE_INTERNAL') || die();
/**
@@ -60,7 +63,7 @@ class url_finder {
* for less straightforward swaps.
*
* @param string $table
* @param string $column
* @param database_column_info $column
* @param string $domain
* @param string $search search string that has prefix, protocol, domain name and one extra character,
* example1: src="http://host.com/
@@ -174,7 +177,7 @@ class url_finder {
$regex = '#((src|data)\ *=\ *[\'\"])(http://)([^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))[\'\"]#i';
preg_match_all($regex, $record->$columnname, $match);
foreach ($match[0] as $i => $fullmatch) {
if (strpos($fullmatch, $CFG->wwwroot) !== false) {
if (\core_text::strpos($fullmatch, $CFG->wwwroot) !== false) {
continue;
}
$prefix = $match[1][$i];
@@ -186,7 +189,7 @@ class url_finder {
}
if ($replacing) {
// For replace string use: prefix, protocol, host and one extra character.
$found[$prefix . substr($url, 0, strlen($host) + 8)] = $host;
$found[$prefix . \core_text::substr($url, 0, \core_text::strlen($host) + 8)] = $host;
} else {
$entry["table"] = $table;
$entry["columnname"] = $columnname;
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017082500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017082400; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_httpsreplace'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_innodb'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->component = 'tool_installaddon';
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->maturity = MATURITY_STABLE;
+2 -2
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_langimport'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017062600; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'logstore_database'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'logstore_legacy'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'logstore_standard'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_log'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017062700; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_lp'; // Full name of the plugin (used for diagnostics).
+3 -3
View File
@@ -25,8 +25,8 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_lpimportcsv'; // Full name of the plugin (used for diagnostics).
$plugin->dependencies = array('tool_lp' => 2017050500);
$plugin->dependencies = array('tool_lp' => 2017110800);
+2 -2
View File
@@ -24,8 +24,8 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_lpmigrate'; // Full name of the plugin (used for diagnostics).
$plugin->dependencies = array(
'tool_lp' => ANY_VERSION
@@ -584,10 +584,10 @@ class manager {
'usestream' => true,
));
if ($part === $plainpartid) {
if ($part == $plainpartid) {
$contentplain = $this->process_message_part_body($messagedata, $partdata, $part);
} else if ($part === $htmlpartid) {
} else if ($part == $htmlpartid) {
$contenthtml = $this->process_message_part_body($messagedata, $partdata, $part);
} else if ($filename = $partdata->getName($part)) {
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'tool_messageinbound';
+3 -2
View File
@@ -140,7 +140,7 @@ class api {
'rememberusername' => $CFG->rememberusername,
'authloginviaemail' => $CFG->authloginviaemail,
'registerauth' => $CFG->registerauth,
'forgottenpasswordurl' => $CFG->forgottenpasswordurl,
'forgottenpasswordurl' => clean_param($CFG->forgottenpasswordurl, PARAM_URL), // We may expect a mailto: here.
'authinstructions' => $authinstructions,
'authnoneenabled' => (int) is_enabled_auth('none'),
'enablewebservices' => $CFG->enablewebservices,
@@ -386,7 +386,8 @@ class api {
// Return certificate information and verify the certificate.
$curl->setopt(array('CURLOPT_CERTINFO' => 1, 'CURLOPT_SSL_VERIFYPEER' => true));
$httpswwwroot = str_replace('http:', 'https:', $CFG->wwwroot); // Force https url.
$curl->head($httpswwwroot . "/login/index.php");
// Check https using a page not redirecting or returning exceptions.
$curl->head($httpswwwroot . "/$CFG->admin/tool/mobile/mobile.webmanifest.php");
$info = $curl->get_info();
// First of all, check the server certificate (if any).
@@ -97,11 +97,13 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
set_config('typeoflogin', api::LOGIN_VIA_BROWSER, 'tool_mobile');
set_config('logo', 'mock.png', 'core_admin');
set_config('logocompact', 'mock.png', 'core_admin');
set_config('forgottenpasswordurl', 'mailto:fake@email.zy'); // Test old hack.
list($authinstructions, $notusedformat) = external_format_text($authinstructions, FORMAT_MOODLE, $context->id);
$expected['registerauth'] = 'email';
$expected['authinstructions'] = $authinstructions;
$expected['typeoflogin'] = api::LOGIN_VIA_BROWSER;
$expected['forgottenpasswordurl'] = ''; // Expect empty when it's not an URL.
if ($logourl = $OUTPUT->get_logo_url()) {
$expected['logourl'] = $logourl->out(false);
+3 -3
View File
@@ -23,9 +23,9 @@
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051501; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_mobile'; // Full name of the plugin (used for diagnostics).
$plugin->dependencies = array(
'webservice_rest' => 2017050500
'webservice_rest' => 2017110800
);
+2 -2
View File
@@ -26,6 +26,6 @@
defined('MOODLE_INTERNAL') || die;
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_monitor'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_multilangupgrade'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_oauth2'; // Full name of the plugin (used for diagnostics).
+1 -1
View File
@@ -74,7 +74,7 @@ if ($options['run']) {
}
}
$_SERVER['argv'] = array_values($_SERVER['argv']);
PHPUnit_TextUI_Command::main();
PHPUnit\TextUI\Command::main();
exit(0);
}
+2 -2
View File
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_phpunit'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_profiling'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_recyclebin'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -25,8 +25,8 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_replace'; // Full name of the plugin (used for diagnostics)
$plugin->maturity = MATURITY_ALPHA; // this version's maturity level
+2 -2
View File
@@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'tool_spamcleaner'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_task'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -21,6 +21,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_templatelibrary'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_unsuproles'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_uploadcourse'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_uploaduser'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'tool_usertours'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'tool_xmldb'; // Full name of the plugin (used for diagnostics)
+4
View File
@@ -29,6 +29,10 @@ defined('MOODLE_INTERNAL') || die();
/**
* Any element analysers can analyse.
*
* Analysers get_analysers method return all analysable elements in the site;
* it is important that analysable elements implement lazy loading to avoid
* big memory footprints. See \core_analytics\course example.
*
* @package core_analytics
* @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+87 -235
View File
@@ -40,9 +40,19 @@ require_once($CFG->dirroot . '/lib/enrollib.php');
class course implements \core_analytics\analysable {
/**
* @var \core_analytics\course[] $instances
* @var bool Has this course data been already loaded.
*/
protected static $instances = array();
protected $loaded = false;
/**
* @var int $cachedid self::$cachedinstance analysable id.
*/
protected static $cachedid = 0;
/**
* @var \core_analytics\course $cachedinstance
*/
protected static $cachedinstance = null;
/**
* Course object
@@ -122,7 +132,7 @@ class course implements \core_analytics\analysable {
* Use self::instance() instead to get cached copies of the course. Instances obtained
* through this constructor will not be cached.
*
* Loads course students and teachers.
* Lazy load of course data, students and teachers.
*
* @param int|stdClass $course Course id
* @return void
@@ -130,18 +140,70 @@ class course implements \core_analytics\analysable {
public function __construct($course) {
if (is_scalar($course)) {
$this->course = get_course($course);
$this->course = new \stdClass();
$this->course->id = $course;
} else {
$this->course = $course;
}
}
$this->coursecontext = \context_course::instance($this->course->id);
/**
* Returns an analytics course instance.
*
* Lazy load of course data, students and teachers.
*
* @param int|stdClass $course Course object or course id
* @return \core_analytics\course
*/
public static function instance($course) {
$courseid = $course;
if (!is_scalar($courseid)) {
$courseid = $course->id;
}
if (self::$cachedid === $courseid) {
return self::$cachedinstance;
}
$cachedinstance = new \core_analytics\course($course);
self::$cachedinstance = $cachedinstance;
self::$cachedid = (int)$courseid;
return self::$cachedinstance;
}
/**
* get_id
*
* @return int
*/
public function get_id() {
return $this->course->id;
}
/**
* Loads the analytics course object.
*
* @return null
*/
protected function load() {
// The instance constructor could be already loaded with the full course object. Using shortname
// because it is a required course field.
if (empty($this->course->shortname)) {
$this->course = get_course($this->course->id);
}
$this->coursecontext = $this->get_context();
$this->now = time();
// Get the course users, including users assigned to student and teacher roles at an higher context.
$cache = \cache::make_from_params(\cache_store::MODE_REQUEST, 'core_analytics', 'rolearchetypes');
// Flag the instance as loaded.
$this->loaded = true;
if (!$studentroles = $cache->get('student')) {
$studentroles = array_keys(get_archetype_roles('student'));
$cache->set('student', $studentroles);
@@ -155,53 +217,13 @@ class course implements \core_analytics\analysable {
$this->teacherids = $this->get_user_ids($teacherroles);
}
/**
* Returns an analytics course instance.
*
* @param int|stdClass $course Course id
* @return \core_analytics\course
*/
public static function instance($course) {
$courseid = $course;
if (!is_scalar($courseid)) {
$courseid = $course->id;
}
if (!empty(self::$instances[$courseid])) {
return self::$instances[$courseid];
}
$instance = new \core_analytics\course($course);
self::$instances[$courseid] = $instance;
return self::$instances[$courseid];
}
/**
* Clears all statically cached instances.
*
* @return void
*/
public static function reset_caches() {
self::$instances = array();
}
/**
* get_id
*
* @return int
*/
public function get_id() {
return $this->course->id;
}
/**
* The course short name
*
* @return string
*/
public function get_name() {
return format_string($this->course->shortname, true, array('context' => $this->get_context()));
return format_string($this->get_course_data()->shortname, true, array('context' => $this->get_context()));
}
/**
@@ -228,8 +250,8 @@ class course implements \core_analytics\analysable {
}
// The field always exist but may have no valid if the course is created through a sync process.
if (!empty($this->course->startdate)) {
$this->starttime = (int)$this->course->startdate;
if (!empty($this->get_course_data()->startdate)) {
$this->starttime = (int)$this->get_course_data()->startdate;
} else {
$this->starttime = 0;
}
@@ -256,7 +278,7 @@ class course implements \core_analytics\analysable {
// We first try to find current course student logs.
$firstlogs = array();
foreach ($this->studentids as $studentid) {
foreach ($this->get_students() as $studentid) {
// Grrr, we are limited by logging API, we could do this easily with a
// select min(timecreated) from xx where courseid = yy group by userid.
@@ -278,7 +300,7 @@ class course implements \core_analytics\analysable {
sort($firstlogs);
$firstlogsmedian = $this->median($firstlogs);
$studentenrolments = enrol_get_course_users($this->get_id(), $this->studentids);
$studentenrolments = enrol_get_course_users($this->get_id(), $this->get_students());
if (empty($studentenrolments)) {
return 0;
}
@@ -306,8 +328,8 @@ class course implements \core_analytics\analysable {
}
// The enddate field is only available from Moodle 3.2 (MDL-22078).
if (!empty($this->course->enddate)) {
$this->endtime = (int)$this->course->enddate;
if (!empty($this->get_course_data()->enddate)) {
$this->endtime = (int)$this->get_course_data()->enddate;
return $this->endtime;
}
@@ -334,7 +356,7 @@ class course implements \core_analytics\analysable {
$monthsago = time() - (WEEKSECS * 4 * 2);
$select = $filterselect . ' AND timeaccess > :timeaccess';
$params = $filterparams + array('timeaccess' => $monthsago);
$sql = "SELECT timeaccess FROM {user_lastaccess} ula
$sql = "SELECT DISTINCT timeaccess FROM {user_lastaccess} ula
JOIN {enrol} e ON e.courseid = ula.courseid
JOIN {user_enrolments} ue ON e.id = ue.enrolid AND ue.userid = ula.userid
WHERE $select";
@@ -342,7 +364,7 @@ class course implements \core_analytics\analysable {
return 0;
}
$sql = "SELECT timeaccess FROM {user_lastaccess} ula
$sql = "SELECT DISTINCT timeaccess FROM {user_lastaccess} ula
JOIN {enrol} e ON e.courseid = ula.courseid
JOIN {user_enrolments} ue ON e.id = ue.enrolid AND ue.userid = ula.userid
WHERE $filterselect AND ula.timeaccess != 0
@@ -362,21 +384,12 @@ class course implements \core_analytics\analysable {
* @return \stdClass
*/
public function get_course_data() {
return $this->course;
}
/**
* Is the course valid to extract indicators from it?
*
* @return bool
*/
public function is_valid() {
if (!$this->was_started() || !$this->is_finished()) {
return false;
if (!$this->loaded) {
$this->load();
}
return true;
return $this->course;
}
/**
@@ -427,7 +440,7 @@ class course implements \core_analytics\analysable {
public function get_user_ids($roleids) {
// We need to index by ra.id as a user may have more than 1 $roles role.
$records = get_role_users($roleids, $this->coursecontext, true, 'ra.id, u.id AS userid, r.id AS roleid', 'ra.id ASC');
$records = get_role_users($roleids, $this->get_context(), true, 'ra.id, u.id AS userid, r.id AS roleid', 'ra.id ASC');
// If a user have more than 1 $roles role array_combine will discard the duplicate.
$callable = array($this, 'filter_user_id');
@@ -441,6 +454,11 @@ class course implements \core_analytics\analysable {
* @return stdClass[]
*/
public function get_students() {
if (!$this->loaded) {
$this->load();
}
return $this->studentids;
}
@@ -453,7 +471,7 @@ class course implements \core_analytics\analysable {
global $DB;
// No logs if no students.
if (empty($this->studentids)) {
if (empty($this->get_students())) {
return 0;
}
@@ -529,172 +547,6 @@ class course implements \core_analytics\analysable {
return $grades;
}
/**
* Guesses all activities that were available during a period of time.
*
* @param string $activitytype
* @param int $starttime
* @param int $endtime
* @param \stdClass $student
* @return array
*/
public function get_activities($activitytype, $starttime, $endtime, $student = false) {
// Var $student may not be available, default to not calculating dynamic data.
$studentid = -1;
if ($student) {
$studentid = $student->id;
}
$modinfo = get_fast_modinfo($this->get_course_data(), $studentid);
$activities = $modinfo->get_instances_of($activitytype);
$timerangeactivities = array();
foreach ($activities as $activity) {
if (!$this->completed_by($activity, $starttime, $endtime)) {
continue;
}
$timerangeactivities[$activity->context->id] = $activity;
}
return $timerangeactivities;
}
/**
* Was the activity supposed to be completed during the provided time range?.
*
* @param \cm_info $activity
* @param int $starttime
* @param int $endtime
* @return bool
*/
protected function completed_by(\cm_info $activity, $starttime, $endtime) {
// We can't check uservisible because:
// - Any activity with available until would not be counted.
// - Sites may block student's course view capabilities once the course is closed.
// Students can not view hidden activities by default, this is not reliable 100% but accurate in most of the cases.
if ($activity->visible === false) {
return false;
}
// We skip activities that were not yet visible or their 'until' was not in this $starttime - $endtime range.
if ($activity->availability) {
$info = new \core_availability\info_module($activity);
$activityavailability = $this->availability_completed_by($info, $starttime, $endtime);
if ($activityavailability === false) {
return false;
} else if ($activityavailability === true) {
// This activity belongs to this time range.
return true;
}
}
// We skip activities in sections that were not yet visible or their 'until' was not in this $starttime - $endtime range.
$section = $activity->get_modinfo()->get_section_info($activity->sectionnum);
if ($section->availability) {
$info = new \core_availability\info_section($section);
$sectionavailability = $this->availability_completed_by($info, $starttime, $endtime);
if ($sectionavailability === false) {
return false;
} else if ($sectionavailability === true) {
// This activity belongs to this section time range.
return true;
}
}
// When the course is using format weeks we use the week's end date.
$format = course_get_format($activity->get_modinfo()->get_course());
if ($this->course->format === 'weeks') {
$dates = $format->get_section_dates($section);
// We need to consider the +2 hours added by get_section_dates.
// Avoid $starttime <= $dates->end because $starttime may be the start of the next week.
if ($starttime < ($dates->end - 7200) && $endtime >= ($dates->end - 7200)) {
return true;
} else {
return false;
}
}
if ($activity->sectionnum == 0) {
return false;
}
if (!$this->get_end() || !$this->get_start()) {
debugging('Activities which due date is in a time range can not be calculated ' .
'if the course doesn\'t have start and end date', DEBUG_DEVELOPER);
return false;
}
if (!course_format_uses_sections($this->course->format)) {
// If it does not use sections and there are no availability conditions to access it it is available
// and we can not magically classify it into any other time range than this one.
return true;
}
// Split the course duration in the number of sections and consider the end of each section the due
// date of all activities contained in that section.
$formatoptions = $format->get_format_options();
if (!empty($formatoptions['numsections'])) {
$nsections = $formatoptions['numsections'];
} else {
// There are course format that use sections but without numsections, we fallback to the number
// of cached sections in get_section_info_all, not that accurate though.
$coursesections = $activity->get_modinfo()->get_section_info_all();
$nsections = count($coursesections);
if (isset($coursesections[0])) {
// We don't count section 0 if it exists.
$nsections--;
}
}
$courseduration = $this->get_end() - $this->get_start();
$sectionduration = round($courseduration / $nsections);
$activitysectionenddate = $this->get_start() + ($sectionduration * $activity->sectionnum);
if ($activitysectionenddate > $starttime && $activitysectionenddate <= $endtime) {
return true;
}
return false;
}
/**
* Check if the activity/section should have been completed during the provided period according to its availability rules.
*
* @param \core_availability\info $info
* @param int $starttime
* @param int $endtime
* @return bool|null
*/
protected function availability_completed_by(\core_availability\info $info, $starttime, $endtime) {
$dateconditions = $info->get_availability_tree()->get_all_children('\availability_date\condition');
foreach ($dateconditions as $condition) {
// Availability API does not allow us to check from / to dates nicely, we need to be naughty.
$conditiondata = $condition->save();
if ($conditiondata->d === \availability_date\condition::DIRECTION_FROM &&
$conditiondata->t > $endtime) {
// Skip this activity if any 'from' date is later than the end time.
return false;
} else if ($conditiondata->d === \availability_date\condition::DIRECTION_UNTIL &&
($conditiondata->t < $starttime || $conditiondata->t > $endtime)) {
// Skip activity if any 'until' date is not in $starttime - $endtime range.
return false;
} else if ($conditiondata->d === \availability_date\condition::DIRECTION_UNTIL &&
$conditiondata->t < $endtime && $conditiondata->t > $starttime) {
return true;
}
}
// This can be interpreted as 'the activity was available but we don't know if its expected completion date
// was during this period.
return null;
}
/**
* Used by get_user_ids to extract the user id.
*
@@ -731,7 +583,7 @@ class course implements \core_analytics\analysable {
}
// Check the amount of student logs in the 4 previous weeks.
list($studentssql, $studentsparams) = $DB->get_in_or_equal($this->studentids, SQL_PARAMS_NAMED);
list($studentssql, $studentsparams) = $DB->get_in_or_equal($this->get_students(), SQL_PARAMS_NAMED);
$filterselect = $prefix . 'courseid = :courseid AND ' . $prefix . 'userid ' . $studentssql;
$filterparams = array('courseid' => $this->course->id) + $studentsparams;
@@ -44,17 +44,21 @@ abstract class by_course extends base {
// Default to all system courses.
if (!empty($this->options['filter'])) {
$courses = $this->options['filter'];
$courses = array();
foreach ($this->options['filter'] as $courseid) {
$courses[$courseid] = new \stdClass();
$courses[$courseid]->id = $courseid;
}
} else {
// Iterate through all potentially valid courses.
$courses = get_courses('all', 'c.sortorder ASC');
$courses = get_courses('all', 'c.sortorder ASC', 'c.id');
}
unset($courses[SITEID]);
$analysables = array();
foreach ($courses as $course) {
// Skip the frontpage course.
$analysable = \core_analytics\course::instance($course);
$analysable = \core_analytics\course::instance($course->id);
$analysables[$analysable->get_id()] = $analysable;
}
@@ -35,6 +35,13 @@ defined('MOODLE_INTERNAL') || die();
*/
abstract class community_of_inquiry_activity extends linear {
/**
* instancedata
*
* @var array
*/
protected $instancedata = array();
/**
* @var \core_analytics\course
*/
@@ -60,6 +67,56 @@ abstract class community_of_inquiry_activity extends linear {
*/
const INDICATOR_SOCIAL = "social";
/**
* Constant for this cognitive level.
*/
const COGNITIVE_LEVEL_1 = 1;
/**
* Constant for this cognitive level.
*/
const COGNITIVE_LEVEL_2 = 2;
/**
* Constant for this cognitive level.
*/
const COGNITIVE_LEVEL_3 = 3;
/**
* Constant for this cognitive level.
*/
const COGNITIVE_LEVEL_4 = 4;
/**
* Constant for this cognitive level.
*/
const COGNITIVE_LEVEL_5 = 5;
/**
* Constant for this social level.
*/
const SOCIAL_LEVEL_1 = 1;
/**
* Constant for this social level.
*/
const SOCIAL_LEVEL_2 = 2;
/**
* Constant for this social level.
*/
const SOCIAL_LEVEL_3 = 3;
/**
* Constant for this social level.
*/
const SOCIAL_LEVEL_4 = 4;
/**
* Constant for this social level.
*/
const SOCIAL_LEVEL_5 = 5;
/**
* Max cognitive depth level accepted.
*/
@@ -428,8 +485,8 @@ abstract class community_of_inquiry_activity extends linear {
// Samples are at cm level or below.
$useractivities = array(\context_module::instance($cm->id)->id => $cm);
} else {
// All course activities.
$useractivities = $this->course->get_activities($this->get_activity_type(), $starttime, $endtime, $user);
// Activities that should be completed during this time period.
$useractivities = $this->get_activities($starttime, $endtime, $user);
}
return $useractivities;
@@ -530,13 +587,15 @@ abstract class community_of_inquiry_activity extends linear {
foreach ($useractivities as $contextid => $cm) {
$potentiallevel = $this->get_cognitive_depth_level($cm);
if (!is_int($potentiallevel) || $potentiallevel > self::MAX_COGNITIVE_LEVEL || $potentiallevel < 1) {
if (!is_int($potentiallevel)
|| $potentiallevel > self::MAX_COGNITIVE_LEVEL
|| $potentiallevel < self::COGNITIVE_LEVEL_1) {
throw new \coding_exception('Activities\' potential cognitive depth go from 1 to 5.');
}
$scoreperlevel = $scoreperactivity / $potentiallevel;
switch ($potentiallevel) {
case 5:
case self::COGNITIVE_LEVEL_5:
// Cognitive level 5 is to submit after feedback.
if ($this->any_feedback('submitted', $cm, $contextid, $user)) {
$score += $scoreperlevel * 5;
@@ -544,7 +603,7 @@ abstract class community_of_inquiry_activity extends linear {
}
// The user didn't reach the activity max cognitive depth, continue with level 2.
case 4:
case self::COGNITIVE_LEVEL_4:
// Cognitive level 4 is to comment on feedback.
if ($this->any_feedback('replied', $cm, $contextid, $user)) {
$score += $scoreperlevel * 4;
@@ -552,7 +611,7 @@ abstract class community_of_inquiry_activity extends linear {
}
// The user didn't reach the activity max cognitive depth, continue with level 2.
case 3:
case self::COGNITIVE_LEVEL_3:
// Cognitive level 3 is to view feedback.
if ($this->any_feedback('viewed', $cm, $contextid, $user)) {
@@ -562,7 +621,7 @@ abstract class community_of_inquiry_activity extends linear {
}
// The user didn't reach the activity max cognitive depth, continue with level 2.
case 2:
case self::COGNITIVE_LEVEL_2:
// Cognitive depth level 2 is to submit content.
if ($this->any_write_log($contextid, $user)) {
@@ -571,7 +630,7 @@ abstract class community_of_inquiry_activity extends linear {
}
// The user didn't reach the activity max cognitive depth, continue with level 1.
case 1:
case self::COGNITIVE_LEVEL_1:
// Cognitive depth level 1 is just accessing the activity.
if ($this->any_log($contextid, $user)) {
@@ -617,16 +676,18 @@ abstract class community_of_inquiry_activity extends linear {
foreach ($useractivities as $contextid => $cm) {
$potentiallevel = $this->get_social_breadth_level($cm);
if (!is_int($potentiallevel) || $potentiallevel > self::MAX_SOCIAL_LEVEL || $potentiallevel < 1) {
if (!is_int($potentiallevel)
|| $potentiallevel > self::MAX_SOCIAL_LEVEL
|| $potentiallevel < self::SOCIAL_LEVEL_1) {
throw new \coding_exception('Activities\' potential social breadth go from 1 to ' .
community_of_inquiry_activity::MAX_SOCIAL_LEVEL . '.');
}
$scoreperlevel = $scoreperactivity / $potentiallevel;
switch ($potentiallevel) {
case 2:
case 3:
case 4:
case 5:
case self::SOCIAL_LEVEL_2:
case self::SOCIAL_LEVEL_3:
case self::SOCIAL_LEVEL_4:
case self::SOCIAL_LEVEL_5:
// Core activities social breadth only reaches level 2, until core activities social
// breadth do not reach level 5 we limit it to what we currently support, which is level 2.
@@ -639,7 +700,7 @@ abstract class community_of_inquiry_activity extends linear {
}
// The user didn't reach the activity max social breadth, continue with level 1.
case 1:
case self::SOCIAL_LEVEL_1:
// Social breadth level 1 is just accessing the activity.
if ($this->any_log($contextid, $user)) {
$score += $scoreperlevel;
@@ -687,6 +748,250 @@ abstract class community_of_inquiry_activity extends linear {
$this->grades = $course->get_student_grades($courseactivities);
}
/**
* Guesses all activities that were available during a period of time.
*
* @param int $starttime
* @param int $endtime
* @param \stdClass|false $student
* @return array
*/
protected function get_activities($starttime, $endtime, $student = false) {
$activitytype = $this->get_activity_type();
// Var $student may not be available, default to not calculating dynamic data.
$studentid = -1;
if ($student) {
$studentid = $student->id;
}
$modinfo = get_fast_modinfo($this->course->get_course_data(), $studentid);
$activities = $modinfo->get_instances_of($activitytype);
$timerangeactivities = array();
foreach ($activities as $activity) {
if (!$this->activity_completed_by($activity, $starttime, $endtime, $student)) {
continue;
}
$timerangeactivities[$activity->context->id] = $activity;
}
return $timerangeactivities;
}
/**
* Was the activity supposed to be completed during the provided time range?.
*
* @param \cm_info $activity
* @param int $starttime
* @param int $endtime
* @param \stdClass|false $student
* @return bool
*/
protected function activity_completed_by(\cm_info $activity, $starttime, $endtime, $student = false) {
// We can't check uservisible because:
// - Any activity with available until would not be counted.
// - Sites may block student's course view capabilities once the course is closed.
// Students can not view hidden activities by default, this is not reliable 100% but accurate in most of the cases.
if ($activity->visible === false) {
return false;
}
// Give priority to the different methods activities have to set a "due" date.
$return = $this->activity_type_completed_by($activity, $starttime, $endtime, $student);
if (!is_null($return)) {
// Method activity_type_completed_by returns null if there is no due date method or there is but it is not set.
return $return;
}
// We skip activities that were not yet visible or their 'until' was not in this $starttime - $endtime range.
if ($activity->availability) {
$info = new \core_availability\info_module($activity);
$activityavailability = $this->availability_completed_by($info, $starttime, $endtime);
if ($activityavailability === false) {
return false;
} else if ($activityavailability === true) {
// This activity belongs to this time range.
return true;
}
}
// We skip activities in sections that were not yet visible or their 'until' was not in this $starttime - $endtime range.
$section = $activity->get_modinfo()->get_section_info($activity->sectionnum);
if ($section->availability) {
$info = new \core_availability\info_section($section);
$sectionavailability = $this->availability_completed_by($info, $starttime, $endtime);
if ($sectionavailability === false) {
return false;
} else if ($sectionavailability === true) {
// This activity belongs to this section time range.
return true;
}
}
// When the course is using format weeks we use the week's end date.
$format = course_get_format($activity->get_modinfo()->get_course());
// We should change this in MDL-60702.
if (method_exists($format, 'get_section_dates')) {
$dates = $format->get_section_dates($section);
// We need to consider the +2 hours added by get_section_dates.
// Avoid $starttime <= $dates->end because $starttime may be the start of the next week.
if ($starttime < ($dates->end - 7200) && $endtime >= ($dates->end - 7200)) {
return true;
} else {
return false;
}
}
if ($activity->sectionnum == 0) {
return false;
}
if (!$this->course->get_end() || !$this->course->get_start()) {
debugging('Activities which due date is in a time range can not be calculated ' .
'if the course doesn\'t have start and end date', DEBUG_DEVELOPER);
return false;
}
if (!course_format_uses_sections($this->course->get_course_data()->format)) {
// If it does not use sections and there are no availability conditions to access it it is available
// and we can not magically classify it into any other time range than this one.
return true;
}
// Split the course duration in the number of sections and consider the end of each section the due
// date of all activities contained in that section.
$formatoptions = $format->get_format_options();
if (!empty($formatoptions['numsections'])) {
$nsections = $formatoptions['numsections'];
} else {
// There are course format that use sections but without numsections, we fallback to the number
// of cached sections in get_section_info_all, not that accurate though.
$coursesections = $activity->get_modinfo()->get_section_info_all();
$nsections = count($coursesections);
if (isset($coursesections[0])) {
// We don't count section 0 if it exists.
$nsections--;
}
}
$courseduration = $this->course->get_end() - $this->course->get_start();
$sectionduration = round($courseduration / $nsections);
$activitysectionenddate = $this->course->get_start() + ($sectionduration * $activity->sectionnum);
if ($activitysectionenddate > $starttime && $activitysectionenddate <= $endtime) {
return true;
}
return false;
}
/**
* True if the activity is due or it has been closed during this period, false if during another period, null if no due time.
*
* It can be overwritten by activities that allow teachers to set a due date or a time close separately
* from Moodle availability system. Note that in most of the cases overwriting get_timeclose_field should
* be enough.
*
* Returns true or false if the time close date falls into the provided time range. Null otherwise.
*
* @param \cm_info $activity
* @param int $starttime
* @param int $endtime
* @param \stdClass|false $student
* @return null
*/
protected function activity_type_completed_by(\cm_info $activity, $starttime, $endtime, $student = false) {
$fieldname = $this->get_timeclose_field();
if (!$fieldname) {
// This activity type do not have its own availability control.
return null;
}
$this->fill_instance_data($activity);
$instance = $this->instancedata[$activity->instance];
if (!$instance->{$fieldname}) {
return null;
}
if ($starttime < $instance->{$fieldname} && $endtime >= $instance->{$fieldname}) {
return true;
}
return false;
}
/**
* Returns the name of the field that controls activity availability.
*
* Should be overwritten by activities that allow teachers to set a due date or a time close separately
* from Moodle availability system.
*
* Just 1 field will not be enough for all cases, but for the most simple ones without
* overrides and stuff like that.
*
* @return null|string
*/
protected function get_timeclose_field() {
return null;
}
/**
* Check if the activity/section should have been completed during the provided period according to its availability rules.
*
* @param \core_availability\info $info
* @param int $starttime
* @param int $endtime
* @return bool|null
*/
protected function availability_completed_by(\core_availability\info $info, $starttime, $endtime) {
$dateconditions = $info->get_availability_tree()->get_all_children('\availability_date\condition');
foreach ($dateconditions as $condition) {
// Availability API does not allow us to check from / to dates nicely, we need to be naughty.
$conditiondata = $condition->save();
if ($conditiondata->d === \availability_date\condition::DIRECTION_FROM &&
$conditiondata->t > $endtime) {
// Skip this activity if any 'from' date is later than the end time.
return false;
} else if ($conditiondata->d === \availability_date\condition::DIRECTION_UNTIL &&
($conditiondata->t < $starttime || $conditiondata->t > $endtime)) {
// Skip activity if any 'until' date is not in $starttime - $endtime range.
return false;
} else if ($conditiondata->d === \availability_date\condition::DIRECTION_UNTIL &&
$conditiondata->t < $endtime && $conditiondata->t > $starttime) {
return true;
}
}
// This can be interpreted as 'the activity was available but we don't know if its expected completion date
// was during this period.
return null;
}
/**
* Fills in activity instance data.
*
* @param \cm_info $cm
* @return void
*/
protected function fill_instance_data(\cm_info $cm) {
global $DB;
if (!isset($this->instancedata[$cm->instance])) {
$this->instancedata[$cm->instance] = $DB->get_record($this->get_activity_type(), array('id' => $cm->instance),
'*', MUST_EXIST);
}
}
/**
* Defines indicator type.
*
@@ -197,6 +197,10 @@ abstract class base {
$dataset = $this->calculate_indicators($sampleids, $samplesorigin, $indicators, $ranges);
if (empty($dataset)) {
return false;
}
// Now that we have the indicators in place we can add the time range indicators (and target if provided) to each of them.
$this->fill_dataset($dataset, $calculatedtarget);
@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Unit tests for course activities.
* Unit tests for activities completed by classification.
*
* @package core_analytics
* @copyright 2017 David Monllaó {@link http://www.davidmonllao.com}
@@ -25,13 +25,13 @@
defined('MOODLE_INTERNAL') || die();
/**
* Unit tests for course activities
* Unit tests for activities completed by classification.
*
* @package core_analytics
* @copyright 2017 David Monllaó {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_analytics_course_activities_testcase extends advanced_testcase {
class community_of_inquiry_activities_completed_by_testcase extends advanced_testcase {
/**
* availability_levels
@@ -59,8 +59,6 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
// Forum1 is ignored as section 0 does not count.
$forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
$courseman = new \core_analytics\course($course);
$modinfo = get_fast_modinfo($course, $stu1->id);
$cm = $modinfo->get_cm($forum->cmid);
@@ -93,20 +91,23 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
$cm = $modinfo->get_cm($forum->cmid);
$course = new \core_analytics\course($course);
list($indicator, $method) = $this->instantiate_indicator('mod_forum', $course);
// Condition from after provided end time.
$this->assertCount(0, $courseman->get_activities('forum', strtotime('2015-10-20 00:00:00 GMT'),
$this->assertCount(0, $method->invoke($indicator, strtotime('2015-10-20 00:00:00 GMT'),
strtotime('2015-10-21 00:00:00 GMT'), $stu1));
// Condition until before provided start time
$this->assertCount(0, $courseman->get_activities('forum', strtotime('2015-10-25 00:00:00 GMT'),
$this->assertCount(0, $method->invoke($indicator, strtotime('2015-10-25 00:00:00 GMT'),
strtotime('2015-10-26 00:00:00 GMT'), $stu1));
// Condition until after provided end time.
$this->assertCount(0, $courseman->get_activities('forum', strtotime('2015-10-22 00:00:00 GMT'),
$this->assertCount(0, $method->invoke($indicator, strtotime('2015-10-22 00:00:00 GMT'),
strtotime('2015-10-23 00:00:00 GMT'), $stu1));
// Condition until after provided start time and before provided end time.
$this->assertCount(1, $courseman->get_activities('forum', strtotime('2015-10-22 00:00:00 GMT'),
$this->assertCount(1, $method->invoke($indicator, strtotime('2015-10-22 00:00:00 GMT'),
strtotime('2015-10-25 00:00:00 GMT'), $stu1));
}
@@ -138,7 +139,8 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
$forum5 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
array('section' => 4));
$courseman = new \core_analytics\course($course);
$course = new \core_analytics\course($course);
list($indicator, $method) = $this->instantiate_indicator('mod_forum', $course);
$this->setUser($stu1);
@@ -146,10 +148,10 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
$second = $startdate + WEEKSECS;
$third = $startdate + (WEEKSECS * 2);
$forth = $startdate + (WEEKSECS * 3);
$this->assertCount(1, $courseman->get_activities('forum', $first, $first + WEEKSECS, $stu1));
$this->assertCount(1, $courseman->get_activities('forum', $second, $second + WEEKSECS, $stu1));
$this->assertCount(0, $courseman->get_activities('forum', $third, $third + WEEKSECS, $stu1));
$this->assertCount(2, $courseman->get_activities('forum', $forth, $forth + WEEKSECS, $stu1));
$this->assertCount(1, $method->invoke($indicator, $first, $first + WEEKSECS, $stu1));
$this->assertCount(1, $method->invoke($indicator, $second, $second + WEEKSECS, $stu1));
$this->assertCount(0, $method->invoke($indicator, $third, $third + WEEKSECS, $stu1));
$this->assertCount(2, $method->invoke($indicator, $forth, $forth + WEEKSECS, $stu1));
}
/**
@@ -189,7 +191,8 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
$forum6 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
array('section' => 12));
$courseman = new \core_analytics\course($course);
$course = new \core_analytics\course($course);
list($indicator, $method) = $this->instantiate_indicator('mod_forum', $course);
$this->setUser($stu1);
@@ -199,10 +202,10 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
$second = $startdate + $duration;
$third = $startdate + ($duration * 2);
$forth = $startdate + ($duration * 3);
$this->assertCount(1, $courseman->get_activities('forum', $first, $first + $duration, $stu1));
$this->assertCount(1, $courseman->get_activities('forum', $second, $second + $duration, $stu1));
$this->assertCount(1, $courseman->get_activities('forum', $third, $third + $duration, $stu1));
$this->assertCount(2, $courseman->get_activities('forum', $forth, $forth + $duration, $stu1));
$this->assertCount(1, $method->invoke($indicator, $first, $first + $duration, $stu1));
$this->assertCount(1, $method->invoke($indicator, $second, $second + $duration, $stu1));
$this->assertCount(1, $method->invoke($indicator, $third, $third + $duration, $stu1));
$this->assertCount(2, $method->invoke($indicator, $forth, $forth + $duration, $stu1));
// Split the course in as many parts as sections.
$duration = ($enddate - $startdate) / $numsections;
@@ -210,15 +213,94 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
// The -1 because section 1 start represents the course start.
$timeranges[$i] = $startdate + ($duration * ($i - 1));
}
$this->assertCount(1, $courseman->get_activities('forum', $timeranges[1], $timeranges[1] + $duration, $stu1));
$this->assertCount(1, $courseman->get_activities('forum', $timeranges[4], $timeranges[4] + $duration, $stu1));
$this->assertCount(1, $courseman->get_activities('forum', $timeranges[8], $timeranges[8] + $duration, $stu1));
$this->assertCount(1, $courseman->get_activities('forum', $timeranges[10], $timeranges[10] + $duration, $stu1));
$this->assertCount(1, $courseman->get_activities('forum', $timeranges[12], $timeranges[12] + $duration, $stu1));
$this->assertCount(1, $method->invoke($indicator, $timeranges[1], $timeranges[1] + $duration, $stu1));
$this->assertCount(1, $method->invoke($indicator, $timeranges[4], $timeranges[4] + $duration, $stu1));
$this->assertCount(1, $method->invoke($indicator, $timeranges[8], $timeranges[8] + $duration, $stu1));
$this->assertCount(1, $method->invoke($indicator, $timeranges[10], $timeranges[10] + $duration, $stu1));
$this->assertCount(1, $method->invoke($indicator, $timeranges[12], $timeranges[12] + $duration, $stu1));
// Nothing here.
$this->assertCount(0, $courseman->get_activities('forum', $timeranges[2], $timeranges[2] + $duration, $stu1));
$this->assertCount(0, $courseman->get_activities('forum', $timeranges[3], $timeranges[3] + $duration, $stu1));
$this->assertCount(0, $method->invoke($indicator, $timeranges[2], $timeranges[2] + $duration, $stu1));
$this->assertCount(0, $method->invoke($indicator, $timeranges[3], $timeranges[3] + $duration, $stu1));
}
/**
* test_get_activities_with_specific_restrictions
*
* @return void
*/
public function test_get_activities_with_specific_restrictions() {
list($course, $stu1) = $this->setup_course();
$end = strtotime('2015-10-24 00:00:00 GMT');
// 1 with time close, one without.
$params = array('course' => $course->id);
$assign1 = $this->getDataGenerator()->create_module('assign', $params);
$params['duedate'] = $end;
$assign2 = $this->getDataGenerator()->create_module('assign', $params);
// 1 with time close, one without.
$params = array('course' => $course->id);
$choice1 = $this->getDataGenerator()->create_module('choice', $params);
$params['timeclose'] = $end;
$choice1 = $this->getDataGenerator()->create_module('choice', $params);
// 1 with time close, one without.
$params = array('course' => $course->id);
$data1 = $this->getDataGenerator()->create_module('data', $params);
$params['timeavailableto'] = $end;
$data1 = $this->getDataGenerator()->create_module('data', $params);
// 1 with time close, one without.
$params = array('course' => $course->id);
$feedback1 = $this->getDataGenerator()->create_module('feedback', $params);
$params['timeclose'] = $end;
$feedback1 = $this->getDataGenerator()->create_module('feedback', $params);
// 1 with time close, one without.
$params = array('course' => $course->id);
$lesson1 = $this->getDataGenerator()->create_module('lesson', $params);
$params['deadline'] = $end;
$lesson1 = $this->getDataGenerator()->create_module('lesson', $params);
// 1 with time close, one without.
$params = array('course' => $course->id);
$quiz1 = $this->getDataGenerator()->create_module('quiz', $params);
$params['timeclose'] = $end;
$quiz1 = $this->getDataGenerator()->create_module('quiz', $params);
// 1 with time close, one without.
$params = array('course' => $course->id);
$scorm1 = $this->getDataGenerator()->create_module('scorm', $params);
$params['timeclose'] = $end;
$scorm1 = $this->getDataGenerator()->create_module('scorm', $params);
// 1 with time close, one without.
$params = array('course' => $course->id);
$workshop1 = $this->getDataGenerator()->create_module('workshop', $params);
$params['submissionend'] = $end;
$workshop1 = $this->getDataGenerator()->create_module('workshop', $params);
$course = new \core_analytics\course($course);
$activitytypes = array('mod_assign', 'mod_choice', 'mod_data', 'mod_feedback', 'mod_lesson',
'mod_quiz', 'mod_scorm', 'mod_workshop');
foreach ($activitytypes as $activitytype) {
list($indicator, $method) = $this->instantiate_indicator($activitytype, $course);
$message = $activitytype . ' activity type returned activities do not match expected size';
$this->assertCount(0, $method->invoke($indicator, strtotime('2015-10-20 00:00:00 GMT'),
strtotime('2015-10-21 00:00:00 GMT'), $stu1), $message);
$this->assertCount(0, $method->invoke($indicator, strtotime('2015-10-25 00:00:00 GMT'),
strtotime('2015-10-26 00:00:00 GMT'), $stu1), $message);
$this->assertCount(1, $method->invoke($indicator, strtotime('2015-10-22 00:00:00 GMT'),
strtotime('2015-10-25 00:00:00 GMT'), $stu1), $message);
}
}
/**
@@ -243,4 +325,27 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
return array($course, $stu1);
}
/**
* Returns the module cognitive depth indicator and the reflection method.
*
* @param string $modulename
* @param \core_analytics\course $course
* @return array
*/
private function instantiate_indicator($modulename, \core_analytics\course $course) {
$classname = '\\' . $modulename . '\analytics\indicator\cognitive_depth';
$indicator = new $classname();
$class = new ReflectionClass($indicator);
$property = $class->getProperty('course');
$property->setAccessible(true);
$property->setValue($indicator, $course);
$method = new ReflectionMethod($indicator, 'get_activities');
$method->setAccessible(true);
return array($indicator, $method);
}
}
+4 -6
View File
@@ -86,7 +86,6 @@ class core_analytics_course_testcase extends advanced_testcase {
$courseman = new \core_analytics\course($this->course->id);
$this->assertFalse($courseman->was_started());
$this->assertFalse($courseman->is_finished());
$this->assertFalse($courseman->is_valid());
// Nothing should change when assigning as teacher.
for ($i = 0; $i < 10; $i++) {
@@ -94,7 +93,8 @@ class core_analytics_course_testcase extends advanced_testcase {
$this->getDataGenerator()->enrol_user($user->id, $this->course->id, $this->teacherroleid);
}
$courseman = new \core_analytics\course($this->course->id);
$this->assertFalse($courseman->is_valid());
$this->assertFalse($courseman->was_started());
$this->assertFalse($courseman->is_finished());
// More students now.
for ($i = 0; $i < 10; $i++) {
@@ -102,7 +102,8 @@ class core_analytics_course_testcase extends advanced_testcase {
$this->getDataGenerator()->enrol_user($user->id, $this->course->id, $this->studentroleid);
}
$courseman = new \core_analytics\course($this->course->id);
$this->assertFalse($courseman->is_valid());
$this->assertFalse($courseman->was_started());
$this->assertFalse($courseman->is_finished());
// Valid start date unknown end date.
$this->course->startdate = gmmktime('0', '0', '0', 10, 24, 2015);
@@ -110,7 +111,6 @@ class core_analytics_course_testcase extends advanced_testcase {
$courseman = new \core_analytics\course($this->course->id);
$this->assertTrue($courseman->was_started());
$this->assertFalse($courseman->is_finished());
$this->assertFalse($courseman->is_valid());
// Valid start and end date.
$this->course->enddate = gmmktime('0', '0', '0', 8, 27, 2016);
@@ -118,7 +118,6 @@ class core_analytics_course_testcase extends advanced_testcase {
$courseman = new \core_analytics\course($this->course->id);
$this->assertTrue($courseman->was_started());
$this->assertTrue($courseman->is_finished());
$this->assertTrue($courseman->is_valid());
// Valid start and ongoing course.
$this->course->enddate = gmmktime('0', '0', '0', 8, 27, 2286);
@@ -126,7 +125,6 @@ class core_analytics_course_testcase extends advanced_testcase {
$courseman = new \core_analytics\course($this->course->id);
$this->assertTrue($courseman->was_started());
$this->assertFalse($courseman->is_finished());
$this->assertFalse($courseman->is_valid());
}
/**
+1
View File
@@ -24,6 +24,7 @@
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once(__DIR__ . '/fixtures/test_indicator_max.php');
require_once(__DIR__ . '/fixtures/test_indicator_min.php');
require_once(__DIR__ . '/fixtures/test_indicator_fullname.php');
+3 -3
View File
@@ -26,8 +26,8 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'auth_cas'; // Full name of the plugin (used for diagnostics)
$plugin->dependencies = array('auth_ldap' => 2017050500);
$plugin->dependencies = array('auth_ldap' => 2017110800);
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'auth_db'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die;
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'auth_email'; // Full name of the plugin (used for diagnostics)
+1 -1
View File
@@ -121,7 +121,7 @@ $string['didntgetusersfromldap'] = "Did not get any users from LDAP -- error? --
$string['gotcountrecordsfromldap'] = "Got {\$a} records from LDAP\n";
$string['ldapnotconfigured'] = 'The LDAP host url is currently not configured';
$string['morethanoneuser'] = 'Strange! More than one user record found in ldap. Only using the first one.';
$string['needbcmath'] = 'You need the BCMath extension to use grace logins with Active Directory';
$string['needbcmath'] = 'You need the BCMath extension to use expired password checking with Active Directory.';
$string['needmbstring'] = 'You need the mbstring extension to change passwords in Active Directory';
$string['nodnforusername'] = 'Error in user_update_password(). No DN for: {$a->username}';
$string['noemail'] = 'Tried to send you an email but failed!';
+2 -2
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017080100; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'auth_ldap'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version (3.1).
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'auth_lti'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'auth_manual'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'auth_mnet'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'auth_nologin'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'auth_none'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051501; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'auth_oauth2'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'auth_shibboleth'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'auth_webservice'; // Full name of the plugin (used for diagnostics)
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'availability_completion';
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'availability_date';
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'availability_grade';
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'availability_group';
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'availability_grouping';
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500;
$plugin->requires = 2017050500;
$plugin->version = 2017111300;
$plugin->requires = 2017110800;
$plugin->component = 'availability_profile';
+1 -1
View File
@@ -136,7 +136,7 @@ abstract class backup implements checksumable {
* point is backup when some behavior/approach channged, in order to allow
* conditional coding based on it.
*/
const VERSION = 2017051500;
const VERSION = 2017111300;
/**
* Usually same than major release zero version, mainly for informative/historic purposes.
*/
+1 -1
View File
@@ -112,7 +112,7 @@ class cc_forum extends entities {
public function get_topic_data ($instance) {
$topic_data = '';
$topic_data = array();
$topic_file = $this->get_external_xml($instance['resource_indentifier']);
+1 -1
View File
@@ -68,7 +68,7 @@ class cc_quiz extends entities {
$last_question_id = 0;
$last_answer_id = 0;
$instances = '';
$instances = array();
$types = array(MOODLE_TYPE_QUIZ, MOODLE_TYPE_QUESTION_BANK);
+1 -1
View File
@@ -87,7 +87,7 @@ class cc11_basiclti extends entities11 {
public function get_basiclti_data($instance) {
$topic_data = '';
$topic_data = array();
$basiclti_file = $this->get_external_xml($instance['resource_indentifier']);
+1 -1
View File
@@ -111,7 +111,7 @@ class cc11_forum extends entities11 {
public function get_topic_data ($instance) {
$topic_data = '';
$topic_data = array();
$topic_file = $this->get_external_xml($instance['resource_indentifier']);
+1 -1
View File
@@ -82,7 +82,7 @@ class cc11_lti extends entities11 {
public function get_basiclti_data($instance) {
$topic_data = '';
$topic_data = array();
$basiclti_file = $this->get_external_xml($instance['resource_indentifier']);
+1 -1
View File
@@ -68,7 +68,7 @@ class cc11_quiz extends entities11 {
$last_question_id = 0;
$last_answer_id = 0;
$instances = '';
$instances = array();
$types = array(MOODLE_TYPE_QUIZ, MOODLE_TYPE_QUESTION_BANK);
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'block_activity_modules'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'block_activity_results'; // Full name of the plugin (used for diagnostics).
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'block_admin_bookmarks'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -25,6 +25,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017050500; // Requires this Moodle version.
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2017110800; // Requires this Moodle version.
$plugin->component = 'block_badges';
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'block_blog_menu'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'block_blog_recent'; // Full name of the plugin (used for diagnostics)
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'block_blog_tags'; // Full name of the plugin (used for diagnostics)
+4 -31
View File
@@ -49,41 +49,14 @@ class block_calendar_month extends block_base {
$this->content->footer = '';
$courseid = $this->page->course->id;
$issite = ($courseid == SITEID);
$course = null;
$courses = null;
$categories = null;
if ($issite) {
// Being displayed at site level. This will cause the filter to fall back to auto-detecting
// the list of courses it will be grabbing events from.
$course = get_site();
$courses = calendar_get_default_courses();
if ($this->page->context->contextlevel === CONTEXT_COURSECAT) {
// Restrict to categories, and their parents, and the courses that the user is enrolled in within those
// categories.
$categories = array_keys($this->page->categories);
$courses = array_filter($courses, function($course) use ($categories) {
return array_search($course->category, $categories) !== false;
});
}
} else {
// Forcibly filter events to include only those from the particular course we are in.
$course = $this->page->course;
$courses = [$course->id => $course];
}
$categoryid = ($this->page->context->contextlevel === CONTEXT_COURSECAT) ? $this->page->category->id : null;
$calendar = \calendar_information::create(time(), $courseid, $categoryid);
list($data, $template) = calendar_get_view($calendar, 'mini', isloggedin());
$renderer = $this->page->get_renderer('core_calendar');
$calendar = new calendar_information();
$calendar->set_sources($course, $courses, $this->page->category);
list($data, $template) = calendar_get_view($calendar, 'mini');
$this->content->text .= $renderer->render_from_template($template, $data);
if (!$issite) {
if ($this->page->course->id != SITEID) {
$this->content->text .= $renderer->event_filter();
}
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'block_calendar_month'; // Full name of the plugin (used for diagnostics)
@@ -45,38 +45,83 @@ class block_calendar_upcoming extends block_base {
}
$this->content = new stdClass;
$this->content->text = '';
$this->content->footer = '';
$renderer = $this->page->get_renderer('core_calendar');
$courseid = $this->page->course->id;
$issite = ($courseid == SITEID);
if ($issite) {
// Being displayed at site level. This will cause the filter to fall back to auto-detecting
// the list of courses it will be grabbing events from.
$course = get_site();
$courses = calendar_get_default_courses();
} else {
// Forcibly filter events to include only those from the particular course we are in.
$course = $this->page->course;
$courses = [$course->id => $course];
}
$calendar = new calendar_information(0, 0, 0, time());
$calendar->set_sources($course, $courses);
$categoryid = ($this->page->context->contextlevel === CONTEXT_COURSECAT) ? $this->page->category->id : null;
$calendar = \calendar_information::create(time(), $courseid, $categoryid);
list($data, $template) = calendar_get_view($calendar, 'upcoming_mini');
if (empty($data->events)) {
$this->content->text = '<div class="post">'. get_string('noupcomingevents', 'calendar').'</div>';
} else {
$this->content->text .= $renderer->render_from_template($template, $data);
$renderer = $this->page->get_renderer('core_calendar');
$this->content->text .= $renderer->render_from_template($template, $data);
$url = new \moodle_url('/calendar/view.php', ['view' => 'upcoming']);
if ($courseid != SITEID) {
$url->param('course', $this->page->course->id);
} else if (!empty($categoryid)) {
$url->param('category', $this->page->category->id);
}
$this->content->footer = '<div class="gotocal">
<a href="'.$CFG->wwwroot.'/calendar/view.php?view=upcoming&amp;course='.$courseid.'">'.
get_string('gotocalendar', 'calendar').'</a>...</div>';
$this->content->footer = html_writer::div(
html_writer::link($url, get_string('gotocalendar', 'block_calendar_upcoming')),
'gotocal'
);
return $this->content;
}
/**
* Get the upcoming event block content.
*
* @param array $events list of events
* @param \moodle_url|string $linkhref link to event referer
* @param boolean $showcourselink whether links to courses should be shown
* @return string|null $content html block content
* @deprecated since 3.4
*/
public static function get_upcoming_content($events, $linkhref = null, $showcourselink = false) {
debugging(
'get_upcoming_content() is deprecated. ' .
'Please see block_calendar_upcoming::get_content() for the correct API usage.',
DEBUG_DEVELOPER
);
$content = '';
$lines = count($events);
if (!$lines) {
return $content;
}
for ($i = 0; $i < $lines; ++$i) {
if (!isset($events[$i]->time)) {
continue;
}
$events[$i] = calendar_add_event_metadata($events[$i]);
$content .= '<div class="event"><span class="icon c0">' . $events[$i]->icon . '</span>';
if (!empty($events[$i]->referer)) {
// That's an activity event, so let's provide the hyperlink.
$content .= $events[$i]->referer;
} else {
if (!empty($linkhref)) {
$href = calendar_get_link_href(new \moodle_url(CALENDAR_URL . $linkhref), 0, 0, 0,
$events[$i]->timestart);
$href->set_anchor('event_' . $events[$i]->id);
$content .= \html_writer::link($href, $events[$i]->name);
} else {
$content .= $events[$i]->name;
}
}
$events[$i]->time = str_replace('&raquo;', '<br />&raquo;', $events[$i]->time);
if ($showcourselink && !empty($events[$i]->courselink)) {
$content .= \html_writer::div($events[$i]->courselink, 'course');
}
$content .= '<div class="date">' . $events[$i]->time . '</div></div>';
if ($i < $lines - 1) {
$content .= '<hr />';
}
}
return $content;
}
}
@@ -24,4 +24,5 @@
$string['calendar_upcoming:addinstance'] = 'Add a new upcoming events block';
$string['calendar_upcoming:myaddinstance'] = 'Add a new upcoming events block to Dashboard';
$string['gotocalendar'] = 'Go to calendar...';
$string['pluginname'] = 'Upcoming events';
+5
View File
@@ -0,0 +1,5 @@
=== 3.4 ===
* block_calendar_upcoming::get_upcoming_content has been deprecated. Please
update your code to use the new APIs. You can see an example of how these
may be used in block_calendar_upcoming::get_content().
+2 -2
View File
@@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017050500; // Requires this Moodle version
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2017110800; // Requires this Moodle version
$plugin->component = 'block_calendar_upcoming'; // Full name of the plugin (used for diagnostics)

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