Compare commits

..

829 Commits

Author SHA1 Message Date
Eloy Lafuente (stronk7) 5c8860f735 Moodle release 2.4.2 2013-03-08 20:02:48 +01:00
Eloy Lafuente (stronk7) db0175400b MDL-38378 Take rid of harcoded db prefix and bump. 2013-03-08 00:24:55 +01:00
Eloy Lafuente (stronk7) 5dd43226a0 weekly release 2.4.1+ 2013-03-07 16:23:57 +01:00
Eloy Lafuente (stronk7) 20cb544cdd Merge branch 'install_24_STABLE' of git://git.moodle.cz/moodle-install into MOODLE_24_STABLE 2013-03-07 16:16:40 +01:00
Eloy Lafuente (stronk7) 5ac03639ca MDL-38345 Prevent undefined CFG leading to DB error.
It seems that MDL-32975, no matter a version bump
was done, leads to the $CFG->navsortmycoursessort
setting undefined sometimes. And that ends with an error
visiting the /my page. This just ensures a safe default
if the setting is undefined/empty.
2013-03-07 10:23:46 +01:00
Frederic Massart 67c858414a MDL-37852 repository: Admins can't access user instances settings 2013-03-07 16:37:05 +08:00
Frederic Massart e1be68f296 MDL-37852 repository: Prevent user from deleting a site-wide instance 2013-03-07 14:35:31 +08:00
Rossiani Wijaya ebfdc35f2a MDL-37411 Note Module: additional patch to fixed undefined property for stable branches 2013-03-07 11:09:05 +08:00
Damyon Wiese d6d470ae15 Revert "MDL-38055 block_courseoverview: fixed formatting of course fullname"
This reverts commit 6013e16b25.
This reverts commit 498ee7d44b.

This issue has failed testing and will be delayed.
2013-03-07 10:29:47 +08:00
Eloy Lafuente (stronk7) f73c7d410b Merge branch 'MDL-38173-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-03-06 17:55:19 +01:00
Eloy Lafuente (stronk7) f4b9cea5fc Merge branch 'MDL-38352-en_fix_24' of git://github.com/mudrd8mz/moodle into MOODLE_24_STABLE 2013-03-06 17:28:19 +01:00
Damyon Wiese 4d25fc3208 MDL-38173 Course: Fix DB from regression when adding a (new) course module to a section. 2013-03-06 23:58:36 +08:00
Helen Foster 3658d00c2b MDL-38352 Merge English strings from the en_fix language pack 2013-03-06 16:55:00 +01:00
Tim Hunt fdbb450f5f MDL-38311 question manual grading: comment fixes. 2013-03-06 10:37:16 +01:00
Sam Hemelryk 3d6fb349eb MDL-32975 navigation: fixed error when viewing my with no enrolments 2013-03-06 14:35:30 +13:00
AMOS bot 3cc745a16c Automatically generated installer lang files 2013-03-06 00:36:56 +00:00
Eloy Lafuente (stronk7) ef01018a00 Merge branch 'MDL-38311_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-03-06 01:24:11 +01:00
Rossiani Wijaya bc144ebbe0 MDL-37411 Notes: unset courseid and userid when updating the note to prevent accidental changes. Thank you Sam Hemelryk for suggesting an alternative solution.
Conflicts:
	notes/edit.php
2013-03-06 09:39:41 +13:00
Eloy Lafuente (stronk7) add7b5a250 Merge branch 'MDL-38119_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-03-05 16:45:42 +01:00
Tim Hunt 1707b741b6 MDL-38311 questions: manual grading API should accept commentformat
Comment format (FORMAT_...) was correctly being processed when the
manual grading happened as the result of a form submission. It was only
when done using the question_usage or question_attempt API method that
there was no way to specify the format. (Although I think the only place
this API as used was in the unit tests.)

Note that question_attempt::manual_grade API had to change, but I don't
think that is a real API change. Calling code should be using
question_usage::question_attempt, which is backwards compatible.

Note that now, if you don't pass format, then no error is generated, but
a developer debugging message is generated.
2013-03-05 11:56:12 +00:00
Aparup Banerjee 57b0cfaaf1 Merge branch 'wip-MDL-34775-stable24' of git://github.com/phalacee/moodle into MOODLE_24_STABLE 2013-03-05 17:03:44 +08:00
Frederic Massart 2498509cfd MDL-37852 repository: Prevent undesired access to repositories settings 2013-03-05 09:56:19 +01:00
Damyon Wiese fa1a43c43e Merge branch 'MDL-38282_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-03-05 16:14:26 +08:00
Damyon Wiese 099b7986a5 Merge branch 'MDL-38279_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-03-05 15:36:15 +08:00
Damyon Wiese c694545650 MDL-37935: Cache - fix spelling mistake in language string 2013-03-05 13:07:33 +08:00
Damyon Wiese c23f9efc64 Merge branch 'wip-MDL-37935-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-03-05 13:07:19 +08:00
Aparup Banerjee a05b00c686 Merge branch 'MDL-30481_m24' of git://github.com/rwijaya/moodle into MOODLE_24_STABLE 2013-03-05 12:56:14 +08:00
Damyon Wiese 469025580f Merge branch 'wip-MDL-38055-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-03-05 11:41:11 +08:00
Frederic Massart eecdec4d5b MDL-34284 library: Import ZF2012-01 security patch for Zend 2013-03-05 10:32:16 +08:00
Sam Hemelryk af27002b54 Merge branch 'wip-MDL-37901_M24' of git://github.com/gjb2048/moodle into MOODLE_24_STABLE 2013-03-05 15:22:57 +13:00
Eloy Lafuente (stronk7) 29f07d932a Merge branch 'wip-MDL-36215-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-03-05 01:28:03 +01:00
Eloy Lafuente (stronk7) 00d4e02598 MDL-32975 mini-bump to get navsortmycoursessort defined. 2013-03-04 23:47:10 +01:00
Eloy Lafuente (stronk7) 032b80ea4b Merge branch 'wip-MDL-32975-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-03-04 23:47:10 +01:00
Sam Hemelryk 7581032c96 MDL-32975 navigation: Added option to select how my courses are sorted 2013-03-05 09:46:36 +13:00
Sam Hemelryk b0aca71569 Merge branch 'MDL-38101-m24' of git://github.com/sammarshallou/moodle into MOODLE_24_STABLE 2013-03-05 09:29:49 +13:00
Eloy Lafuente (stronk7) 083b0a54aa Merge branch 'MDL-37522-published-attachment_24' of git://github.com/mudrd8mz/moodle into MOODLE_24_STABLE 2013-03-04 20:47:02 +01:00
Eloy Lafuente (stronk7) 6c2dec31f5 Merge branch 'wip-MDL-33013-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-03-04 20:18:37 +01:00
Eloy Lafuente (stronk7) 4856fb65b2 Merge branch 'MDL-36380-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-03-04 18:00:03 +01:00
Eloy Lafuente (stronk7) bbdbe0a490 Merge branch 'wip-MDL-37983-24' of git://github.com/abgreeve/moodle into MOODLE_24_STABLE 2013-03-04 16:43:00 +01:00
Eloy Lafuente (stronk7) 26431c6f94 Merge branch 'MDL-38170-m24' of git://github.com/sammarshallou/moodle into MOODLE_24_STABLE 2013-03-04 16:26:07 +01:00
Sam Hemelryk 892ee7ee56 Merge branch 'MDL-35350_m24' of git://github.com/rwijaya/moodle into MOODLE_24_STABLE 2013-03-04 16:12:54 +13:00
Sam Hemelryk fb2ac5029c Merge branch 'MDL-35127-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-03-04 16:07:59 +13:00
Eloy Lafuente (stronk7) 653c7d4a27 Merge branch 'wip-MDL-38205-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-03-04 03:01:21 +01:00
Frederic Massart 6153c8040d MDL-36426 repository: Prevent login_as() users to access 2013-03-04 02:38:32 +01:00
Sam Hemelryk b158bcce98 Merge branch 'MDL-37625-m24' of https://github.com/jfilip/moodle into MOODLE_24_STABLE 2013-03-04 14:18:33 +13:00
Sam Hemelryk 6a218739e4 Merge branch 'MDL-36128-moodle24' of https://github.com/StudiUM/moodle into MOODLE_24_STABLE 2013-03-04 13:59:40 +13:00
Frederic Massart 92e5923857 MDL-37681 repository_webdav: improved form handling when configuring an instance 2013-03-04 13:55:47 +13:00
Rajesh Taneja a608b0e670 MDL-37338 Calendar: User will not see calendar subscription, which he/she can't edit
Signed-off-by: Rajesh Taneja <rajesh@moodle.com>
2013-03-04 01:51:09 +01:00
Sam Hemelryk 4ea25c227c Merge branch 'MDL-38168-m24' of git://github.com/sammarshallou/moodle into MOODLE_24_STABLE 2013-03-04 13:35:00 +13:00
Frederic Massart 75822af579 MDL-37507 repositories: improved formatting of external resources 2013-03-04 13:28:36 +13:00
Mark Nielsen 53c66110a8 MDL-36901: Remove system paths from exceptions
Replaces any server paths, like dataroot, with a token
in exception messages and debug info.
2013-03-04 00:16:58 +01:00
Frederic Massart fc58c234ed MDL-37481 user: fixed bug when logged in as guest 2013-03-04 11:18:49 +13:00
Eloy Lafuente (stronk7) 8b0318d538 Merge branch 'wip-MDL-38165-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-03-03 23:08:12 +01:00
Sam Hemelryk b62c8a06ad Merge branch 'MDL-32125-moodle24' of git://github.com/StudiUM/moodle into MOODLE_24_STABLE 2013-03-04 10:31:30 +13:00
Sam Hemelryk 6013e16b25 MDL-38055 block_courseoverview: fixed formatting of course fullname
Conflicts:
	blocks/course_overview/renderer.php
2013-03-04 09:35:17 +13:00
Andrew Davis d2dbe64ba4 MDL-38149 core_grade: added a guard for when there are no old grades 2013-03-03 11:16:33 +08:00
Gareth J Barnard c2cd6618d2 MDL-37901 format_topics & format_weeks: Fix drag icon tooltip after move. 2013-03-02 12:53:37 +00:00
Tim Hunt 97f7bfc457 MDL-39282 quiz: always allow removal of bogus questions. 2013-03-01 17:34:17 +00:00
Tim Hunt a78c180efa MDL-38279 questions: must have default mark positive. 2013-03-01 15:22:05 +00:00
sam marshall 850d33e658 MDL-38170 SimplePie: Cannot read https feeds through proxy 2013-03-01 10:33:24 +00:00
AMOS bot 58110adcc6 Automatically generated installer lang files 2013-03-01 00:42:16 +00:00
Sam Hemelryk ca35d1c6b6 MDL-38165 cache: fixed issues purging peristent caches by event 2013-03-01 11:37:56 +13:00
Sam Hemelryk fcb404faac MDL-38165 cache: added unit tests for event purging of persistent caches 2013-03-01 11:37:56 +13:00
Sam Hemelryk 5a9b867cec MDL-38205 cache: implemented key prefix in memcache plugin 2013-03-01 10:11:19 +13:00
Sam Hemelryk f9bbcc5302 MDL-38165 cache: fixed up application event purging 2013-03-01 10:10:25 +13:00
Sam Hemelryk f810487764 MDL-38165 cache: fixed up session event purging 2013-03-01 10:10:25 +13:00
Sam Hemelryk 498ee7d44b MDL-38055 navigation: fixed ampersand use within titles
Conflicts:
	lib/navigationlib.php
2013-03-01 10:09:47 +13:00
Sam Hemelryk 704d82627c MDL-37935 cache: improved ready testing of stores on admin screen and testing script 2013-03-01 10:09:20 +13:00
Sam Hemelryk 49f853bfcb MDL-36215 navigation: fixed blog URL within courses using groups 2013-03-01 10:08:38 +13:00
Sam Hemelryk 5defa8f05e MDL-33013 navigation: fixed expansion limit issue hiding nodes 2013-03-01 10:08:15 +13:00
Jean-Philippe Gaudreau 4d30065a0a MDL-36128 grade: Import outcomes error 2013-02-28 13:30:24 -05:00
Tim Hunt 627f31b52c MDL-37847 / MDL-38119 question engine: document API change. 2013-02-28 18:26:46 +00:00
David Mudrák c24b75e257 MDL-37522 Serve images from published submissions
If the user is allowed to see the published submission, she must be also
able to see images in it (both embedded into the text as well as
attached to the submission). See the logic in submission.php as a
reference.
2013-02-28 18:51:44 +01:00
Gilles-Philippe Leblanc 445146552a MDL-32125 mod_forum: Updating subscription mode not reflecting subscribers 2013-02-28 11:59:26 -05:00
Eloy Lafuente (stronk7) 19075a2120 weekly release 2.4.1+ 2013-02-28 15:50:39 +01:00
Eloy Lafuente (stronk7) eac27523b5 Merge branch 'install_24_STABLE' of git://git.moodle.cz/moodle-install into MOODLE_24_STABLE 2013-02-28 15:40:31 +01:00
Michael de Raadt 79e21e7d75 MDL-34775 - Forum, RSS - Fixing RSS entries option to be disabled if RSS is not enabled 2013-02-28 15:50:28 +08:00
Michael de Raadt d5c6c474c2 MDL-35350 Advanced uploading assignment: add submission timestamp on assignment index page 2013-02-28 14:04:50 +08:00
Frederic Massart fad56ea4be MDL-36380 stats: Issue with DST and monthly statistics 2013-02-28 13:56:45 +08:00
Frederic Massart 4c4ea10c3f MDL-36380 stats: No more duplicated entries when viewing monthly stats 2013-02-28 13:56:45 +08:00
Damyon Wiese 73646066a4 MDL-35127 Assignment - declare the variables in the outer scope (for readability) 2013-02-27 09:59:03 +08:00
Damyon Wiese 507507352b Merge branch 'MDL-35127_m24' of git://github.com/merrill-oakland/moodle into MDL-35127-24 2013-02-27 09:58:24 +08:00
Eric Merrill 37cb15e634 MDL-35127 mod_assign More efficient use of expensive database queries
Moving two relatively expensive DB queries so they are only executed when needed
instead of on every function call. They will still only execute once, and not
repeatedly during execution of the loop.
2013-02-26 09:48:46 -05:00
Rossiani Wijaya e6e074cc70 MDL-30481 Advanced upload assignment: Fixed assignment available date string to appropriately identify past or future availability 2013-02-26 17:41:04 +08:00
Eloy Lafuente (stronk7) f881b74bd8 Merge branch 'MDL-38076-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-02-26 10:14:51 +01:00
Erik Lundberg a5c4a76848 MDL-37835 Assignment unit tests fail when custom submission types are installed.
The assignment generator will now take all submission/feedback modules into concideration when creating new assignments.
2013-02-26 10:09:16 +01:00
Adrian Greeve 4f1538728a MDL-30669 - blocks: Unit tests for course_page_type_list() 2013-02-26 09:50:02 +01:00
Adrian Greeve 2d931ca93b MDL-30669 - blocks: Added a warning when deleting blocks that have multiple displays set.
Also added a fix to the function course_page_type_list(). It was making a call to
get_context_info_array() which will generate an error if $currentcontext is not set.
2013-02-26 09:49:52 +01:00
Damyon Wiese 382b3d7596 MDL-37792 Conditions: Fix upgrade step in previous patch 2013-02-26 10:56:11 +08:00
Damyon Wiese db0c7b4e7b Merge branch 'MDL-37792-m24' of git://github.com/sammarshallou/moodle into MOODLE_24_STABLE 2013-02-26 10:54:48 +08:00
Sam Hemelryk 823b45cb49 Merge branch 'wip-MDL-38144-MOODLE_24_STABLE' of git://github.com/marinaglancy/moodle into MOODLE_24_STABLE 2013-02-26 15:26:55 +13:00
Marina Glancy 1a9d07fb59 MDL-38144 categories are created in reverse sort order in externallib 2013-02-26 11:29:39 +11:00
Eloy Lafuente (stronk7) a5ce98d52f Merge branch 'wip-MDL-38162-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-02-26 01:29:10 +01:00
Sam Hemelryk 5fe9dcbbed MDL-38110 cache: increased ttl unit test value to avoid timing issues 2013-02-26 00:47:37 +01:00
sam marshall 1a44518a64 MDL-37792 Conditions: Interests condition offered but not implemented 2013-02-25 13:25:17 +00:00
Damyon Wiese 3424086143 MDL-28692 Base theme - Version bump for css change 2013-02-25 13:52:05 +08:00
Damyon Wiese 6ff9929833 Merge branch 'MDL-28692_M24' of git://github.com/lazydaisy/moodle into MOODLE_24_STABLE 2013-02-25 13:34:55 +08:00
Damyon Wiese 203338ab02 Merge branch 'MDL-38052_M24' of git://github.com/kordan/moodle into MOODLE_24_STABLE 2013-02-25 11:38:47 +08:00
Tim Lock c9c205e450 MDL-38113: Blind Marking grader email reveals submitters details 2013-02-25 11:14:17 +08:00
Dan Poltawski 6b5dc09867 Merge branch 'wip-MDL-38091-MOODLE_24_STABLE' of git://github.com/marinaglancy/moodle into MOODLE_24_STABLE 2013-02-25 11:00:11 +08:00
Dan Poltawski 45551ed4df Merge branch 'MDL-38061-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-02-25 10:20:55 +08:00
Damyon Wiese a083389c63 Merge branch 'MDL-35175_24' of git://github.com/rlorenzo/moodle into MOODLE_24_STABLE 2013-02-25 09:52:19 +08:00
AMOS bot 0d260e54da Automatically generated installer lang files 2013-02-25 00:39:45 +00:00
Marina Glancy c49adb8e18 MDL-38091 fixed bug with SQL query on Oracle 2013-02-23 12:22:21 +11:00
kordan 06c108f879 MDL-38052 theme_formal_white: allowed the overlap between headermenu and header logo 2013-02-22 19:12:24 +01:00
sam marshall aee5f1f4d8 MDL-38168 Filelib: Curl class does not honour proxybypass option 2013-02-22 14:20:04 +00:00
Damyon Wiese 56d22f190e weekly release 2.4.1+ 2013-02-22 10:59:52 +08:00
Damyon Wiese 45dc254910 Merge branch 'install_24_STABLE' of git://git.moodle.cz/moodle-install into MOODLE_24_STABLE 2013-02-22 10:50:27 +08:00
Damyon Wiese 351cd1416f MDL-38061 Assignment - Use $CFG->showuseridentity to add extra fields to the assignment grading table/user summary.
Conflicts:

	mod/assign/gradingtable.php
	mod/assign/locallib.php
	mod/assign/renderable.php
	mod/assign/renderer.php
2013-02-22 10:32:08 +08:00
Sam Hemelryk 7a3a576617 MDL-38162 memcache: fixed up the memcache plugins 2013-02-22 14:27:28 +13:00
Sam Hemelryk c7746a0f7f MDL-37224 backup-import: better handling of search button 2013-02-21 08:24:20 +13:00
Dan Poltawski b1703e2951 Revert "MDL-36380 stats: No more duplicated entries when viewing monthly stats"
This reverts commit 33b5464e96.
2013-02-20 17:04:52 +08:00
Dan Poltawski 349a6fde37 Merge branch 'MDL-35622-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-02-20 14:27:52 +08:00
Rajesh Taneja 2225d0cfe6 MDL-37329 Navigation: Enrolled courses in category should be added only. 2013-02-20 12:41:21 +08:00
Frederic Massart 16296b4a84 MDL-35622 files: Fixed typo in galleryitem extension 2013-02-20 12:23:56 +08:00
Rajesh Taneja d432ff9e99 MDL-37329 Navigation: Navigation node My Courses will only show enrolled courses 2013-02-20 08:58:02 +08:00
Eloy Lafuente (stronk7) d863b93f5c MDL-37894 Amend tests with new openclose rule. 2013-02-20 01:37:08 +01:00
Eloy Lafuente (stronk7) 49ac497117 Merge branch 'wip-MDL-37224-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-02-20 00:48:50 +01:00
Eloy Lafuente (stronk7) ee04accfba Merge branch 'wip-MDL-34298-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-02-20 00:46:24 +01:00
Eloy Lafuente (stronk7) 5ddaf0a8ff Merge branch 'MDL-37894_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-02-20 00:40:21 +01:00
Eloy Lafuente (stronk7) 097404cd2b Merge branch 'MDL-37967_24' of git://github.com/jmvedrine/moodle into MOODLE_24_STABLE 2013-02-20 00:34:36 +01:00
Eloy Lafuente (stronk7) 950fead105 Merge branch 'wip-MDL-38075-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-02-20 00:07:47 +01:00
sam marshall fc84419f34 MDL-38101 Completion: Error when teacher/admin marks activity complete 2013-02-19 16:57:09 +00:00
Eloy Lafuente (stronk7) 8e628ee242 MDL-32620 whitespace + comment fixes. 2013-02-19 13:23:10 +01:00
Mark Nielsen 2fc00b3a5d MDL-32620: Fixing up white space in comment 2013-02-19 13:23:01 +01:00
Chris Scribner 53a993e103 Fixing an issue with not sending the launch_presentation_return_url 2013-02-19 13:22:55 +01:00
Eloy Lafuente (stronk7) e9d41cebe5 Merge branch 'MDL-38031-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-02-19 12:50:25 +01:00
Eloy Lafuente (stronk7) b5476a34bc Merge branch 'MDL-38033_dnd_uppercase_extn_24' of git://github.com/davosmith/moodle into MOODLE_24_STABLE 2013-02-19 12:24:24 +01:00
Dan Poltawski 8fbdd7cd1e Merge branch 'w07_MDL-38059_m24_cachedir' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-02-19 14:07:20 +08:00
Damyon Wiese fc511c8e48 Merge branch 'wip-MDL-38000-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-02-19 13:47:23 +08:00
Dan Poltawski e2b55c9c34 Merge branch 'MDL-38048-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-02-19 13:44:27 +08:00
Dan Poltawski bf0c578f16 Merge branch 'm24_MDL-37449_Reports_ORA-00918_column_ambiguously_defined' of https://github.com/scara/moodle into MOODLE_24_STABLE 2013-02-19 13:41:55 +08:00
Dan Poltawski e23d098117 Merge branch 'MDL-37749_M24' of git://github.com/lazydaisy/moodle into MOODLE_24_STABLE 2013-02-19 12:25:30 +08:00
Damyon Wiese e3f6d84b15 MDL-31636 Comments - Call display callback when adding a new comment. 2013-02-19 11:52:13 +08:00
Aparup Banerjee 86c1de421f MDL-31636 Added strftimeformat to comment object being passed through to xxx_comment_display() for further time format changes. 2013-02-19 11:52:02 +08:00
Aparup Banerjee 5fef447ee3 MDL-31636 redirect debugging to error log for ajax 2013-02-19 11:51:50 +08:00
Dan Poltawski ff7a518119 Merge branch 'MDL-38051_24' of git://github.com/jmvedrine/moodle into MOODLE_24_STABLE 2013-02-19 11:23:46 +08:00
Dan Poltawski 0141a869eb Merge branch 'MDL-37934_24' of git://github.com/jmvedrine/moodle into MOODLE_24_STABLE 2013-02-19 10:56:37 +08:00
AMOS bot ad3e244afd Automatically generated installer lang files 2013-02-19 00:44:34 +00:00
Sam Hemelryk 99720e73a6 MDL-34298 course: fixed course search output validation issue 2013-02-19 11:03:33 +13:00
Sam Hemelryk f3e186ab55 MDL-37224 backup: fixed bug when searching for a course to import 2013-02-19 09:32:22 +13:00
Tim Hunt fd8c97d264 MDL-37894 Show the quiz close date even if the quiz is not open yet.
People care a lot about deadlines!
2013-02-18 10:28:45 +00:00
Dan Poltawski 0e3d1236f8 Merge branch 'MDL-38039_M24' of git://github.com/lazydaisy/moodle into MOODLE_24_STABLE 2013-02-18 15:59:56 +08:00
Aparup Banerjee 3026cb9910 MDL-37687 use $SITE to allow non-logged-in users to browse comment via ajax 2013-02-18 15:18:54 +08:00
Jean-Michel Vedrine ddc03b10d5 MDL-37967 Improve XML question import format handling of duplicated files 2013-02-18 07:54:30 +01:00
Dan Poltawski ff1d6556a7 Merge branch 'MDL-37396_m24' of git://github.com/rwijaya/moodle into MOODLE_24_STABLE 2013-02-18 14:27:40 +08:00
Dan Poltawski 9d0c759ed1 Merge branch 'MDL-36380-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-02-18 14:18:36 +08:00
Rossiani Wijaya 4086097935 MDL-37396 Enrollmen: pass $perpage as optional_param and set default perpage variable in quickenrolment.js 2013-02-18 13:30:33 +08:00
Damyon Wiese bc11a70203 Merge branch 'MDL-37939-m24' of https://github.com/andrewnicols/moodle into MOODLE_24_STABLE
Conflicts:
	lib/db/upgrade.php
	version.php
2013-02-18 12:47:32 +08:00
Dan Poltawski 047f7aa46c Merge branch 'MDL-35336_m24' of git://github.com/rwijaya/moodle into MOODLE_24_STABLE 2013-02-18 12:24:12 +08:00
Dan Poltawski a2f6f882c4 Merge branch 'MDL-35622-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE
Conflicts:
	lib/db/upgrade.php
	version.php
2013-02-18 11:33:00 +08:00
Dan Poltawski f4fb6d9898 Merge branch 'MDL-34800_ajax_submit_24' of git://github.com/andyjdavis/moodle into MOODLE_24_STABLE 2013-02-18 11:07:40 +08:00
Damyon Wiese 86c2bbd5f2 MDL-37683 cache: - Comments cleanup and remove ;; 2013-02-18 10:41:48 +08:00
Damyon Wiese b6f49c741d Merge branch 'wip-MDL-37683-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-02-18 10:39:47 +08:00
Rossiani Wijaya 53a054c8dd MDL-37396 User Enrollment: fixed missing user from enrolment sub-menu 2013-02-18 10:27:38 +08:00
Rossiani Wijaya 2102aee45c MDL-35336 report (course overview): check the setting for enablestats before printing out the node for setting > site admin > reports 2013-02-18 10:22:51 +08:00
Rossiani Wijaya ec0fef3294 MDL-35336 Report (course overview): fixed redirect url to enable statistics setting page when statistics is disable 2013-02-18 10:22:50 +08:00
Mary Evans b402f6ddc3 MDL-28692 theme_base: Added background-color to admin settings form overridden in base/style/admin.css 2013-02-18 01:58:47 +00:00
Frederic Massart 5bcea4d315 MDL-38076 usability: Fix wrong position of new 2.4 icons 2013-02-18 09:41:31 +08:00
Adrian Greeve 3884b0624e MDL-37983 - my home / navigation: $CFG->forcelogin is no longer affecting default home page redirects. 2013-02-18 08:53:45 +08:00
Sam Hemelryk 31c94e5cb3 MDL-37683 cache: improved indentifier collection and storage 2013-02-18 10:20:23 +13:00
Sam Hemelryk 2ad68b8c95 MDL-38000 css: fixed handling of CSS files by outputlib. 2013-02-18 08:34:01 +13:00
Sam Hemelryk a2b5f389de MDL-37683 cache: siteidentifier is now included in the keys
Conflicts:
	lib/db/upgrade.php
	lib/moodlelib.php
	version.php
2013-02-18 08:30:29 +13:00
Sam Hemelryk fd6d738db4 MDL-38075 csslib: fixed coding error when working with an array of styles 2013-02-18 08:22:08 +13:00
Petr Škoda 4a9c28b513 MDL-38059 explain that cachedir must be shared in cluster 2013-02-16 14:45:17 +01:00
Jean-Michel Vedrine ffcc444fa7 MDL-38051 Annihilate all the CRLFs present in some questions/fixtures... 2013-02-16 14:41:35 +01:00
Andrew Robert Nicols acdf4859b5 MDL-37939 Course: Add additional unit tests to confirm that module move occurs correctly 2013-02-15 21:10:22 +00:00
Andrew Robert Nicols 41d397e68b MDL-37939 Course: Correct broken sequence data 2013-02-15 21:10:13 +00:00
Matteo Scaramuccia 9b6485865c MDL-37449 Incorrect doubled 'u.email' field in the SQL query (Oracle error: ORA-00918) 2013-02-15 21:19:14 +01:00
Frederic Massart 33b5464e96 MDL-36380 stats: No more duplicated entries when viewing monthly stats 2013-02-15 15:03:37 +08:00
Frederic Massart 59cb24ff0c MDL-38048 documentation: Typo in README file 2013-02-15 13:15:24 +08:00
Frederic Massart b4d0144d09 MDL-38301 usability: Fixed wrong icon size 2013-02-15 10:05:20 +08:00
Eloy Lafuente (stronk7) 03fd922158 MDL-38040 Clean core from CRLFs 2013-02-15 02:20:28 +01:00
Mary Evans 229e69a1c0 MDL-38039 theme_base: Corrected typo fickering to flickering in CSS comment which blocked IPCOP browser firewall in IE. 2013-02-15 01:06:44 +00:00
Davo Smith aea372a659 MDL-38033 dndupload - ignore case when comparing dropped file extensions with those supported by activity modules 2013-02-14 20:22:07 +00:00
Jean-Michel Vedrine 58a43ebebe MDL-37934 Blackboard_six question import fails in some cases
Import fails if the same image is used several times
in the same field of the same question.
2013-02-14 14:43:32 +01:00
Damyon Wiese 09de5eb3de weekly release 2.4.1+ 2013-02-14 14:08:04 +08:00
Damyon Wiese 73e15efa4b Merge branch 'install_24_STABLE' of git://git.moodle.cz/moodle-install into MOODLE_24_STABLE 2013-02-14 14:06:54 +08:00
AMOS bot 5b98dd1e85 Automatically generated installer lang files 2013-02-14 00:49:56 +00:00
Damyon Wiese 47d8bb6e25 MDL-37883 Assignment Grade import/export. Additional fix to prevent different grade rounding on export. 2013-02-13 15:35:39 +08:00
AMOS bot a31370452a Automatically generated installer lang files 2013-02-13 00:45:40 +00:00
Rex Lorenzo b20c4d58db MDL-35175 - Lesson shows no attempts if associated with a grouping 2013-02-12 15:27:50 -08:00
Mary Evans fbf87b8143 MDL-37749 theme_mymobile: Removed redundant JS and CSS code for Collapsed Topic contributed plugin. 2013-02-12 17:20:29 +00:00
Eloy Lafuente (stronk7) efdb676e84 MDL-37893 Take rid of old comment. 2013-02-12 10:04:28 +01:00
Eloy Lafuente (stronk7) 553e19b443 Merge branch 'MDL-37893-grouped-empty_24' of git://github.com/mudrd8mz/moodle into MOODLE_24_STABLE 2013-02-12 10:04:12 +01:00
Dan Poltawski 6d5f4fd536 Merge branch 'wip-MDL-37976-MOODLE_24_STABLE' of git://github.com/marinaglancy/moodle into MOODLE_24_STABLE 2013-02-12 16:13:55 +08:00
Dan Poltawski db41eeb8bd Merge branch 'wip-mdl-37633-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2013-02-12 15:49:55 +08:00
Rajesh Taneja 353fac6f48 MDL-37633 Forum: Allow fronpage user to have forum:allowforcesubscribe capability by default
Conflicts:

	mod/forum/version.php
2013-02-12 15:01:05 +08:00
Andrew Davis c605d0b9c6 MDL-34800 core_grade:switched from hiding the submit button to disabling it if ajax is enabled 2013-02-12 14:54:28 +08:00
Dan Poltawski dbdcc42eee Merge branch 'MDL-32076_unlimited2_24' of git://github.com/andyjdavis/moodle into MOODLE_24_STABLE 2013-02-12 14:42:35 +08:00
Dan Poltawski 25da216389 Merge branch 'MDL-37883-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-02-12 13:47:44 +08:00
Dan Poltawski 519375f9fe Merge branch 'MDL-37074-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-02-12 13:39:34 +08:00
Dan Poltawski ccc32eba06 Merge branch 'MDL-37924_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-02-12 13:36:04 +08:00
Dan Poltawski 09931f8158 Merge branch 'wip-MDL-34798_M24-2' of git://github.com/gjb2048/moodle into MOODLE_24_STABLE 2013-02-12 10:34:15 +08:00
Marina Glancy abc3a22f42 MDL-37976 fixed missing global 2013-02-12 12:53:47 +11:00
Dan Poltawski 6cf9f04cd6 Merge branch 'MDL-37952_24' of git://github.com/stronk7/moodle into MOODLE_24_STABLE 2013-02-12 09:46:08 +08:00
Damyon Wiese 3da2415167 MDL-36297 Version bump for js changes. 2013-02-12 09:40:11 +08:00
Davo Smith 80accd23bb MDL-37831 filepicker - icons / details / tree selector buttons now work more reliably 2013-02-12 09:37:33 +08:00
Eloy Lafuente (stronk7) d3a2b63143 Merge branch 'MDL-37943_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-02-12 01:21:06 +01:00
Eloy Lafuente (stronk7) 017382e6d3 Merge branch 'MDL-37896_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-02-12 01:14:24 +01:00
David Mudrák 0eab91dcce MDL-37919 Let PHPUnit display the content of $a even if the error string is not found 2013-02-12 01:08:22 +01:00
Eloy Lafuente (stronk7) 2c9a28bbe6 Merge branch 'MDL-35037-24' of git://github.com/danpoltawski/moodle into MOODLE_24_STABLE 2013-02-12 00:59:56 +01:00
Frederic Massart bc2de4ab0e MDL-37961 webservice: PARAM_BOOL with PARAM_DEFAULT accepts boolean default 2013-02-12 00:44:17 +01:00
Gareth J Barnard cac8708d0b MDL_34798 format_topics and format_weeks: Adjust section names when moving up. 2013-02-11 14:07:35 +00:00
Dan Poltawski af5d66f999 Merge branch 'MDL-37039-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-02-11 14:33:27 +08:00
Dan Poltawski 8b2034bc7b Merge branch 'MDL-37797_m24' of git://github.com/rwijaya/moodle into MOODLE_24_STABLE 2013-02-11 13:58:47 +08:00
Frederic Massart bac188fa71 MDL-35622 files: Add support for SMART Notebook MIME types
- The MIME type for Notebook files is: application/x-smarttech-notebook
- The MIME type for Gallery files is also: application/x-smarttech-notebook
Refs: http://exchange-forum.smarttech.com/forums/p/5152/11945.aspx#11945

Original author: Matteo Scaramuccia <moodle@matteoscaramuccia.com>
Fixed by: Paul Holden <pholden@greenhead.ac.uk>

Conflicts:

	lib/db/upgrade.php
	version.php
2013-02-11 10:29:50 +08:00
AMOS bot 526bff4c64 Automatically generated installer lang files 2013-02-10 00:41:39 +00:00
Eloy Lafuente (stronk7) dcaeeda60c MDL-37952 make helper descendants abstract 2013-02-09 16:21:49 +01:00
Tim Hunt e2d9006792 MDL-37924 quiz settings: change wrong 'fix' => 'adv'. 2013-02-08 12:50:17 +00:00
Tim Hunt 2de3659810 MDL-37896 qtype_essay: correct PARAM_CLEANHTML -> PARAM_RAW.
It turns out that you should almost never use PARAM_CLEANHTML.
2013-02-08 12:49:58 +00:00
Tim Hunt 5baa26c105 MDL-37943 upgrade: logic error in upgrade_plugins_blocks.
Derek Woolhead tracked down the problem and what needed to be fixed. I
just made the patch.

The problem was that if $plugin->cron had changed in version.php, then
the version number in the database could end up wrong after the upgrade,
and so the upgrade would immediately run a second time.
2013-02-08 12:43:58 +00:00
David Mudrák dc85a9e833 MDL-37774 Do not pass trailing slash if the method does not want it 2013-02-08 12:53:23 +01:00
David Mudrák 9f887c6c79 MDL-37774 Make moodle1_file_manager::migrate_directory() support trailing slash in rootpath
As the $rootpath is concatenated with the $relpath, we would end with a
path like course_files//file.txt. Such a path is detected as not-valid
later and an error would be thrown.

So the patch makes sure that the trailing slash is cut off and a
debugging for the developer is displayed.
2013-02-08 12:53:23 +01:00
David Mudrák 8616f9380c MDL-37774 Add unit test to illustrate the problem with the trailing slash
The patch introduces two new tests for moodle1_file_manager::migrate_directory().
The second test with the trailing slash reveals the trouble here.
The expected behaviour is that the method would deal with the trailing
slash. Debugging message for the developer should be displayed though.
2013-02-08 12:53:23 +01:00
Damyon Wiese b9dc4c3cbe MDL-37039 Assignment - Do not apply filters to grading table for offline assignments
Because the filters do not make sense for offline assignments, they are hidden. But if the active filter
prevents you from seeing any assignments you cannot change it. This change makes it so the filters are
also not applied when the assignment is an offline assignment.
2013-02-08 15:48:08 +08:00
Damyon Wiese 1d16b7f80c MDL-37074 Assign theming: Use addClass/removeClass instead of setAttribute to preserve existing classes 2013-02-08 15:18:53 +08:00
Damyon Wiese 0e6d8bc952 weekly release 2.4.1+ 2013-02-08 11:19:06 +08:00
Damyon Wiese f2d81d1e54 Merge branch 'install_24_STABLE' of git://git.moodle.cz/moodle-install into MOODLE_24_STABLE 2013-02-08 11:01:44 +08:00
Eloy Lafuente (stronk7) 04116863fb MDL-37893 Always notify pending starts before dispatching chunk 2013-02-08 01:48:32 +01:00
David Mudrák 176f08e90c MDL-37893 Allow elements with no final tags to form a grouped path 2013-02-08 01:48:32 +01:00
David Mudrák 8ab37b5fca MDL-37893 Add unit test to demonstrate the issue 2013-02-08 01:48:32 +01:00
AMOS bot 7da5b49bc4 Automatically generated installer lang files 2013-02-08 00:45:15 +00:00
Sam Hemelryk 007cd537d0 MDL-37645 cache: fixed issue deleting mongo instance 2013-02-08 08:07:01 +13:00
Dan Poltawski b59f90efa4 MDL-35037 tags: dont display blog entries when blogging disabled 2013-02-07 12:34:55 +08:00
Andrew Robert Nicols 3c754bb442 MDL-37566 AJAX Fix issues with minimum height and centring
Conflicts:
	lib/yui/chooserdialogue/chooserdialogue.js
2013-02-07 01:10:21 +01:00
Damyon Wiese 99aa14d1ff MDL-37883 Assign offline marking: Properly handle french decimal grades when importing worksheet. 2013-02-06 15:45:43 +08:00
Andrew Davis e456586166 MDL-32076 core_grade: fixed ajax handling of unlimited grades and added some unit tests 2013-02-06 15:34:35 +08:00
Rajesh Taneja cd1792a902 MDL-30144 Assignmnet 2.2: fixed context retrival 2013-02-06 13:22:17 +08:00
Eloy Lafuente (stronk7) b626992e09 Merge branch 'MDL-37854_m24' of https://github.com/markn86/moodle into MOODLE_24_STABLE 2013-02-05 11:19:30 +01:00
Mark Nelson e0d4f2b66c MDL-37854 phpunit: replaced occurrence of non-existent function assertFail 2013-02-05 18:03:58 +08:00
David Mudrák e57a314de8 MDL-37870 Fix the number of parameters when calling the parent constructor 2013-02-05 10:19:52 +01:00
Howard Miller 3bcf80e9f2 MDL-37797 HTML block: add contextid to block_positions query and make it more unique. 2013-02-05 16:23:23 +08:00
Damyon Wiese d854035ffe MDL-36206 Unit tests - Cleanup whitespace issues from previous patch 2013-02-05 14:13:37 +08:00
Jason Fowler 27e79a40ce MDL-36206 - Unit Test - Create unit test for pagination bar 2013-02-05 14:13:16 +08:00
Dan Poltawski 44a29a501a Merge branch 'MDL-37800_24' of git://github.com/grabs/moodle into MOODLE_24_STABLE 2013-02-05 12:43:15 +08:00
Dan Poltawski 7298cf7db3 Merge branch 'wip-MDL-36322-m24' of https://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-02-05 10:26:21 +08:00
Dan Poltawski 50890e037e MDL-37357 - fix trailing whitespace 2013-02-05 09:58:27 +08:00
Dan Poltawski d5822fbfd7 Merge branch 'MDL-37357_hidden_rank_24' of git://github.com/andyjdavis/moodle into MOODLE_24_STABLE 2013-02-05 09:58:10 +08:00
Dan Poltawski 2647ebb63c MDL-37574 - Fix navigation tests: remove title
We are no longer setting it, to improve accessibility
2013-02-05 08:38:39 +08:00
Eloy Lafuente (stronk7) 4ce7de34ca Merge branch 'MDL-37566-m24' of git://github.com/andrewnicols/moodle into MOODLE_24_STABLE 2013-02-05 01:14:21 +01:00
Davo Smith 747e16f7b0 MDL-37801 mod_glossary - encode / decode links to 'showentry' pages during backup & restore 2013-02-05 01:03:14 +01:00
Eloy Lafuente (stronk7) 52c86533d9 Merge branch 'MDL-37775_M24' of git://github.com/lazydaisy/moodle into MOODLE_24_STABLE 2013-02-05 00:57:33 +01:00
Eloy Lafuente (stronk7) 47ae7ebe35 Merge branch 'MDL-37785_M24' of git://github.com/lazydaisy/moodle into MOODLE_24_STABLE 2013-02-05 00:36:13 +01:00
Eloy Lafuente (stronk7) e42c4ee260 Merge branch 'MDL-37523_M24' of git://github.com/lazydaisy/moodle into MOODLE_24_STABLE 2013-02-05 00:28:32 +01:00
Eloy Lafuente (stronk7) 125d26d23c Merge branch 'MDL-37518_m24' of https://github.com/markn86/moodle into MOODLE_24_STABLE 2013-02-05 00:14:01 +01:00
Eloy Lafuente (stronk7) bd11fca3aa Merge branch 'm24_MDL-33078' of git://github.com/danmarsden/moodle into MOODLE_24_STABLE 2013-02-04 23:59:14 +01:00
Eloy Lafuente (stronk7) 65828d8652 Merge branch 'MDL-37847_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-02-04 22:56:03 +01:00
Tim Hunt b7f894a403 MDL-37847 plain text essays were screwing up HTML special chars.
This was incorrect use of PARAM_CLEANHTML for these inputs.

This fix also adds some unit tests to try to verify that this does not
break again in future.
2013-02-04 12:55:31 +00:00
Mary Evans 9ed92b3bd2 MDL-37523 theme_mymobile: Removed a renderer from mymobile/renderers.php and added it to theme/mymobile/renderers/mod_choice_renderer.php. Then added a conditional statement to theme/mymobile/renderers.php in order to call mymobile/renderers/mod_choice_renderer.php. 2013-02-04 11:35:23 +00:00
Dan Marsden 76b177f6c3 MDL-33078 SCORM: rebuild toc when calling LMSCommit to improve pre-req handling 2013-02-04 22:10:19 +13:00
Damyon Wiese 2c9f35960f Merge branch 'MDL-37781-workshop-schedule_24' of git://github.com/mudrd8mz/moodle into MOODLE_24_STABLE 2013-02-04 16:19:26 +08:00
Dan Poltawski bfc80ec4e8 Merge branch 'MDL-37574-m24' of git://github.com/andrewnicols/moodle into MOODLE_24_STABLE 2013-02-04 16:14:12 +08:00
Dan Poltawski 64d4729f3d Merge branch 'm24_MDL-29207' of git://github.com/danmarsden/moodle into MOODLE_24_STABLE 2013-02-04 15:56:15 +08:00
Dan Poltawski 3677b2ecf3 Revert "MDL-32076 core_grade: fixed ajax handling of unlimited grades and added some unit tests"
This reverts commit 002178276f.
2013-02-04 15:12:45 +08:00
Dan Poltawski 3fd6f7e088 Merge branch 'MDL-32076_unlimited2_24' of git://github.com/andyjdavis/moodle into MOODLE_24_STABLE 2013-02-04 14:30:48 +08:00
Michael Hughes da071ee1d2 MDL-30144 Assignment 2.2: Download all as zip should only contain submission from active enroled users 2013-02-04 13:55:30 +08:00
Dan Poltawski 2cb6f68179 Merge branch 'MDL-37646-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-02-04 13:49:32 +08:00
Dan Poltawski 8b447463ad Merge branch 'MDL-37710-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-02-04 12:12:56 +08:00
Dan Poltawski 3e0ddd4cfd Merge branch 'MDL-37635-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-02-04 11:57:15 +08:00
Mark Nelson ec4663f863 MDL-37518 blocks: described the introduction of the myaddinstance capability in upgrade.txt 2013-02-04 11:43:46 +08:00
Damyon Wiese ecd60630ac Merge branch 'm24_MDL-36800' of git://github.com/danmarsden/moodle into MOODLE_24_STABLE 2013-02-04 11:41:33 +08:00
Damyon Wiese 8917ec5117 Merge branch 'MDL-37177-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-02-04 11:18:33 +08:00
Dan Poltawski a6bd6fcd41 Merge branch 'MDL-37746_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-02-04 10:17:46 +08:00
Dan Poltawski 56f84f2b99 Merge branch 'MDL-25853-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-02-04 10:13:58 +08:00
Dan Marsden a07fe914d0 MDL-29207: SCORM prereq callback is pure js - move it to module.js so it can be cached better. 2013-02-03 20:29:00 +13:00
Dan Marsden bb22d0696e MDL-29207 SCORM: Auto-continue doesn't work with Pre-req due to JS errors 2013-02-03 20:28:57 +13:00
Dan Marsden 216e2e5b7f MDL-36800 SCORM: Fix Yui().use calls - thanks to Nancy Cheng for the fix 2013-02-03 20:22:18 +13:00
Andrew Robert Nicols 9388982eab MDL-37574 Remove default link title from navigation items 2013-02-01 11:34:50 +00:00
Andrew Robert Nicols 3a64e6eb02 MDL-37566 AJAX Only set max-height for chooser dialogues
If we set height as well as max-height then there is a potential for
whitespace to be shown at the bottom of the list of choices.

This commit stops removing the height option so that we only rely upon
max-height for dialogue heigh calculation.
2013-02-01 11:26:30 +00:00
Andreas Grabs baea79cca4 MDL-37800 mod_feedback - item "information" does not appear correctly 2013-02-01 11:42:43 +01:00
Damyon Wiese 5c15ab2b4a MDL-37635 Assign: Prevent errors when viewing a feedback for an assignment with no gradeitem in gradebook
Unit tests removed from backport to verify that:
Feedback is visible even if there is no grade
The grade is not shown if the gradeitem is hidden unless you have mod/assign:grade capability

Conflicts:

	mod/assign/locallib.php
	mod/assign/renderer.php
	mod/assign/tests/locallib_test.php
2013-02-01 13:46:58 +08:00
Andrew Davis 6d168299ae MDL-37357 core_grade: fixed the showing and hiding of rank on the overview report 2013-02-01 10:54:41 +08:00
Andrew Davis 002178276f MDL-32076 core_grade: fixed ajax handling of unlimited grades and added some unit tests 2013-02-01 08:52:52 +08:00
Sam Hemelryk 3fbba4bf48 MDL-36322 cache: implemented cache_store::create_clone 2013-02-01 08:49:07 +13:00
Sam Hemelryk 722907c7b0 MDL-36322 cache: clarified docs for initialise and construct 2013-02-01 08:49:07 +13:00
Sam Hemelryk 770eed82fd MDL-36322 cache: cache stores now test connections during construction 2013-02-01 08:49:07 +13:00
Matteo Scaramuccia 447475e5d7 MDL-36322 Errors when updating a Moodle instance with some misconfigured cache stores 2013-02-01 08:49:07 +13:00
Tim Hunt 3f7a6d5331 MDL-37746 qtype_shortanser: avoid normalizer_normalize dangers.
When an error occurs, normalizer_normalize just silently returns null,
which is dangerous. Here, we wrap it in a safe helper function.
2013-01-31 11:33:12 +00:00
Eloy Lafuente (stronk7) a8e927e26c weekly release 2.4.1+ 2013-01-31 11:04:58 +01:00
Mary Evans 56364dcec0 MDL-37775 theme_canvas: Changed ADD a block from center align to left in style/blocks.css 2013-01-31 08:11:08 +00:00
Frederic Massart ba7b0fb3b3 MDL-37177 navigation: Prevent exception when viewing a profile
When viewing a profile as a non-authenticated user, an exception
was raised because we were trying to fetch the context of this user.
2013-01-31 12:26:52 +08:00
David Mudrák 337c3fa74c MDL-37781 Allocate workshop submissions without waiting for cron
Now we are checking for the need to execute the allocator every time the
main view.php is displayed to any user. Previously this was done by cron
only.
2013-01-31 03:38:21 +01:00
David Mudrák 351aeeeba6 MDL-37781 Check for switching the workshop phase without waiting for cron
Now we are checking for the need to switch the phase when the main
view.php is displayed to any user (previously this was done via cron
only). To give our subplugins (such as the scheduled allocation method)
a chance to do what they need to do, the workshop_viewed event is
triggered before the phase is actually switched.
2013-01-31 03:31:18 +01:00
Dan Poltawski d070222f69 Merge branch 'm24_MDL-34231' of git://github.com/danmarsden/moodle into MOODLE_24_STABLE 2013-01-31 10:14:53 +08:00
Mary Evans 05ec4d9d20 MDL-37785 theme_base: remove duplicate .dir-rtl file-picker css rules from styke/core.css 2013-01-31 01:17:52 +00:00
Sam Hemelryk 8003618cd1 MDL-36363 cache: added unit tests for muliple loaders 2013-01-31 12:16:21 +13:00
Dan Marsden 54bc823b80 MDL-34231 SCORM: calculate correct number of attemptsleft when entering an attempt. 2013-01-31 10:46:16 +13:00
Sam Hemelryk 4786eca8f2 MDL-36363 cache: fixed issue with double parsing keys for stacked loaders 2013-01-31 09:14:31 +13:00
Damyon Wiese 2c24a252c5 Merge branch 'wip-MDL-37747-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-01-30 09:06:04 +08:00
Frederic Massart d987453bd4 MDL-25853 calendar: Fixed broken previous/next links 2013-01-30 09:03:22 +08:00
Eloy Lafuente (stronk7) 498a14ef8b Merge branch 'w04_MDL-37734_m24_marshack' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-30 01:23:36 +01:00
Sam Hemelryk 0241200633 MDL-37747 cache: changed PARAM_TEXT to PARAM_ALPHANUMEXT 2013-01-30 13:18:56 +13:00
Petr Škoda 1b2ab57a92 MDL-37767 allow empty host in enrol_database which is required for default pg socket 2013-01-30 00:42:37 +01:00
Eloy Lafuente (stronk7) f89712dc6d Merge branch 'MDL-37533-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-01-29 15:35:14 +01:00
Eloy Lafuente (stronk7) becce23e4a Merge branch 'wip-MDL-36363-m24' of https://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-01-29 12:06:43 +01:00
Petr Škoda 674e0a210d MDL-37734 add one more recordset isolation test 2013-01-29 10:18:54 +01:00
Petr Škoda e63aff8479 MDL-37734 use prefetching workaround for MARS transaction problems 2013-01-29 10:18:41 +01:00
Damyon Wiese 3cf3ecd90f MDL-37710 Assign: Fix pluginfile permission checks for student viewing their own team submission.
This change adds a function to the assign class to allow the permissions for a group submission
to be checked and updates all the submission plugins to call it.

Conflicts:

	mod/assign/locallib.php
	mod/assign/submission/file/lib.php
	mod/assign/submission/onlinetext/lib.php
2013-01-29 17:07:17 +08:00
Rajesh Taneja 9f9bc1f0ab MDL-34190 Course: Role with student archtype should be selected as default in user list 2013-01-29 16:54:04 +08:00
ppichet 92a7501ac6 MDL-29691 Improve numerical format in multianswer
Allow the use of , as decsep in multianswer numerical subquestions
2013-01-29 16:30:27 +08:00
Damyon Wiese afcc12e80b MDL-37646 Assign: Quickgrading fix when using grading filters or lots of students. 2013-01-29 14:39:42 +08:00
Dan Poltawski adedab33de Merge branch 'MDL-37694_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-01-29 11:54:42 +08:00
Sam Hemelryk 3cb0325122 Merge branch 'MDL-37476-stable24' of git://github.com/mouneyrac/moodle into MOODLE_24_STABLE 2013-01-29 15:23:45 +13:00
Dan Marsden 2a97de2671 MDL-37696 SCORM css: don't include style.css multiple times 2013-01-29 10:34:22 +13:00
Sam Hemelryk bb5ebb6280 Merge branch 'MDL-37697-m24' of git://github.com/andrewnicols/moodle into MOODLE_24_STABLE 2013-01-29 09:56:37 +13:00
Sam Hemelryk 6a1e566152 Merge branch 'MDL-37350-m24' of git://github.com/andrewnicols/moodle into MOODLE_24_STABLE 2013-01-29 08:54:52 +13:00
Sam Hemelryk cd6e980e66 Merge branch 'MDL-36881-m24' of git://github.com/andrewnicols/moodle into MOODLE_24_STABLE 2013-01-29 08:51:39 +13:00
Sam Hemelryk 47795b2126 Merge branch 'MDL-34671-m24' of git://github.com/andrewnicols/moodle into MOODLE_24_STABLE 2013-01-29 08:39:23 +13:00
Sam Hemelryk 21126fc5e8 Merge branch 'MDL-37668-m24' of git://github.com/sammarshallou/moodle into MOODLE_24_STABLE 2013-01-29 08:33:19 +13:00
Sam Hemelryk 353db49bfb Merge branch 'm24_MDL-34231' of git://github.com/danmarsden/moodle into MOODLE_24_STABLE 2013-01-29 08:28:12 +13:00
Eloy Lafuente (stronk7) 18d4c3120a Merge branch 'wip-MDL-37545-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-01-28 19:23:25 +01:00
Eloy Lafuente (stronk7) f1b7893d57 MDL-37086 phpunit: use alt reset method.
When code executed in test cases is using/preventing
database transactions, phpunit itself cannot
use transactions for reseting between cases. But we
can tell it about, so some alternative (and slower)
method for reseting will be used.
2013-01-28 18:49:56 +01:00
sam marshall e978e6b5f5 MDL-37668 Accessibility: Help popup should be easy to close using keyboard 2013-01-28 10:58:59 +00:00
Andrew Robert Nicols d2e360710f MDL-34671 Stop browser receiving escape keydown in modal dialogues
In certain modal dialogues, we listen on the Escape key to close a
dialogue. However, this is still passed to the browser. As a result, if the
browser is in full screen mode and that browser respects the escape key as
a means to exit full screen.

As a result, we need to ensure that we listen for the escape key at keydown
rather than keyup, and additionally prevent the default browser behaviour.

This is a workaround to http://yuilibrary.com/projects/yui3/ticket/2532616
and, should that issue be fixed, it should be removed.
2013-01-28 10:49:15 +00:00
Sam Chaffee 48a5b81346 MDL-36881 Handle poorly behaved modname_get_types functions better
The modname_get_types function is not always well implemented by
third-party plugins and some return poor data. This in turn leads to
incorrect module definitions, and can lead to problems in both the
'Add an activity...' dropdowns and the Activity chooser.

This will also prevent display of plugins which legitimately can have
subtypes but where no subtypes were found. Since such plugins cannot be
used in this fashion in any case, this is also beneficial.

Signed-off-by: Andrew Robert Nicols <andrew.nicols@lancaster.ac.uk>
2013-01-28 10:22:55 +00:00
Andrew Robert Nicols 584eca0871 MDL-37350 Detach listeners when hiding the 'Add roles' popup
If the submit event listener is not correctly closed, then the submit event
calls the relevant callback multiple times incorrectly.

When hiding the Add role dialogue, we need to detach any event listeners
which are applied to it.
2013-01-28 09:58:39 +00:00
Andrew Robert Nicols 15652ea93c MDL-37697 Use the user selected editor format for new course forums 2013-01-28 09:55:13 +00:00
Dan Marsden 481e8f7105 MDL-34231 SCORM: Lock after final attempt when using skip content structure or direct navigation to player.php 2013-01-28 21:20:39 +13:00
Sam Hemelryk a9c75fdc75 Merge branch 'w04_MDL-37638_m24_rolecloning' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-28 17:59:48 +13:00
Sam Hemelryk 151d0c574d Merge branch 'w04_MDL-37713_m24_testdir' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-28 17:53:42 +13:00
Sam Hemelryk 611314c096 Merge branch 'MDL-37548-m24' of git://github.com/andrewnicols/moodle into MOODLE_24_STABLE 2013-01-28 17:46:02 +13:00
Sam Hemelryk 3e72333f0c Merge branch 'wip-MDL-29723_M24' of git://github.com/lazydaisy/moodle into MOODLE_24_STABLE 2013-01-28 17:34:51 +13:00
Sam Hemelryk e7a68ca017 Merge branch 'MDL-37172_24' of git://github.com/jmvedrine/moodle into MOODLE_24_STABLE 2013-01-28 17:29:09 +13:00
Sam Hemelryk 72e5445732 Merge branch 'MDL-13805_others_messages_24' of git://github.com/andyjdavis/moodle into MOODLE_24_STABLE 2013-01-28 16:06:58 +13:00
Andrew Davis 799be0ba8c MDL-13805 core_message: fixed the admin's ability to read another users messages 2013-01-28 10:19:42 +08:00
David Monllao db246a14e0 MDL-37634 lesson: readquestion visibility to protected 2013-01-28 13:45:36 +13:00
Sam Hemelryk 4d572da1b3 Merge branch 'MDL-37628-24' of git://github.com/grabs/moodle into MOODLE_24_STABLE 2013-01-28 13:41:54 +13:00
Sam Hemelryk e86e05ebf0 Merge branch 'w04_MDL-37407_m24_chineseunzip' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-28 13:31:54 +13:00
Sam Hemelryk 452a704ae9 Merge branch 'MDL-37414_m24' of https://github.com/markn86/moodle into MOODLE_24_STABLE 2013-01-28 13:28:52 +13:00
Sam Hemelryk 362b124e69 Merge branch 'MDL-19069_m24' of git://github.com/rwijaya/moodle into MOODLE_24_STABLE 2013-01-28 11:32:41 +13:00
Sam Hemelryk 4636cf771c MDL-37545 cache: fixed bug during initialisation and updating of cache config 2013-01-28 10:40:49 +13:00
Sam Hemelryk a50cdcc0fd MDL-36363 cache: clean up pre-integration 2013-01-28 10:39:07 +13:00
Matteo Scaramuccia 86afa1d00f MDL-36363 Override instance_deleted() for all cache stores performing just a cleanup() when this action successfully applies over all the definitions of the cache store 2013-01-28 10:39:07 +13:00
Matteo Scaramuccia 233046ea5e MDL-36363 Adding/Removing a file store cache instance cleanups the folder too 2013-01-28 10:39:07 +13:00
Matteo Scaramuccia 5d7411e92b MDL-36363 Added cache_store::instance_created() and cache_store::instance_deleted() 2013-01-28 10:39:07 +13:00
Petr Škoda 54b96ced13 MDL-37713 let phpunit bootstrap create test dataroot if necessary 2013-01-26 14:59:55 +01:00
Andreas Grabs 70328cc2e7 MDL-37628 feedback - Coding error in Recent Activity 2013-01-26 11:26:00 +01:00
Jean-Michel Vedrine d53ba71a24 MDL-37172 Hardcoded strings in some question imports formats
AMOS BEGIN
CPY [unknownorunhandledtype,qformat_blackboard_six],[unknownorunhandledtype,question]
AMOS END
2013-01-25 22:45:47 +01:00
Petr Škoda 4fb6eeb518 MDL-37638 fix name of duplicate role 2013-01-25 19:36:17 +01:00
Petr Škoda 401dc3dbb9 MDL-37407 add support for zh_cn unicode unzip 2013-01-25 15:56:45 +01:00
Tim Hunt c257025ccd MDL-37694 move quiz unit tests to the right place.
Follow-on from MDL-37684.
2013-01-25 12:14:10 +00:00
Dan Poltawski df93b156a7 MDL-37684 - phpunit add missing definitions to phpunit.xml.dist 2013-01-25 16:27:50 +08:00
Dan Poltawski 9c0349b416 weekly release 2.4.1+ 2013-01-25 15:58:09 +08:00
Dan Poltawski f0e846b410 Merge branch 'install_24_STABLE' of git://git.moodle.cz/moodle-install into MOODLE_24_STABLE 2013-01-25 15:57:52 +08:00
Dan Poltawski 87eb1d645f Merge branch 'MDL-37473b-24' of git://github.com/srynot4sale/moodle into MOODLE_24_STABLE 2013-01-25 12:35:55 +08:00
Aaron Barnes fb28b75b74 MDL-37473 completion: Add missing cap checks to tracked users functions
Namely get_num_tracked_users and is_tracked_user()
2013-01-25 17:11:02 +13:00
Andrew Robert Nicols a64df7558c MDL-37548 Show the incorrect value in a colour picker after validation 2013-01-24 10:15:34 +00:00
Stephen Bourget ad4d0c5e05 MDL-37533 Assign: Fix grading filters to show only assignments needing grading
Conflicts:

	mod/assign/gradingtable.php
2013-01-24 11:07:41 +08:00
Damyon Wiese 95755113bf MDL-37533 Assign: Use the constant for the submitted status in the query (and parameterize the query) 2013-01-24 11:06:46 +08:00
Stephen Bourget 153292da44 MDL-37533 Assign: assign_print_overview does not correctly display assignments that need grading
Conflicts:

	mod/assign/lib.php
2013-01-24 11:06:33 +08:00
AMOS bot fa85892b0a Automatically generated installer lang files 2013-01-24 00:46:49 +00:00
Jerome Mouneyrac 7e2184125c MDL-37476 course_create unit test fails if course completion is enabled 2013-01-23 13:57:24 +08:00
Mary Evans b213281ba1 MDL-29723 mod/quiz: Modified show/hide button in edit.php and added some extra CSS rules to styles.css to make Question bank block more compatible/adaptable with themes. 2013-01-23 00:58:26 +00:00
Damyon Wiese 8ca54dbbf3 MDL-37619 Assign - Fix regression assign_print_overview caused by MDL-37527 2013-01-23 08:47:00 +08:00
Sam Hemelryk 7700ec42c1 Merge branch 'MDL-34435-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE
Conflicts:
	version.php
2013-01-23 11:08:14 +13:00
Eloy Lafuente (stronk7) d31a080f91 Merge branch 'wip-MDL-15930-24' of git://github.com/abgreeve/moodle into MOODLE_24_STABLE 2013-01-22 20:33:06 +01:00
Justin Filip 990c247841 MDL-37625 auth_radius Updated to latest version (1.5.0) of included PEAR Crypt_CHAP library. 2013-01-22 10:41:54 -05:00
Aparup Banerjee 1c7c33b314 Merge branch 'wip-mdl-37339-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2013-01-22 16:28:39 +08:00
Dan Poltawski 13d03939a6 Merge branch 'wip-mdl-32526-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2013-01-22 14:00:34 +08:00
Dan Poltawski 83d4aee03c Merge branch 'MDL-27164-MOODLE_24_STABLE' of git://github.com/micaherne/moodle into MOODLE_24_STABLE 2013-01-22 12:51:59 +08:00
Dan Poltawski c57ed76265 Merge branch 'm24_MDL-36853' of git://github.com/danmarsden/moodle into MOODLE_24_STABLE 2013-01-22 12:49:26 +08:00
Dan Poltawski 1bb2d65bb2 Merge branch 'MDL-37275_m24' of git://github.com/markn86/moodle into MOODLE_24_STABLE 2013-01-22 12:46:16 +08:00
Dan Poltawski 3dae8bcedd Merge branch 'MDL-37375_m24' of git://github.com/rwijaya/moodle into MOODLE_24_STABLE 2013-01-22 12:43:55 +08:00
Dan Poltawski 9f8b8bbd37 Merge branch 'w03_MDL-37593_m24_httpslogineditor' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-22 12:36:06 +08:00
Dan Poltawski 82cb942bff Merge branch 'MDL-37430-24' of github.com:damyon/moodle into MOODLE_24_STABLE 2013-01-22 11:53:38 +08:00
Dan Poltawski facd17c1ce Merge branch 'MDL-35357_m24' of git://github.com/rwijaya/moodle into MOODLE_24_STABLE 2013-01-22 11:48:16 +08:00
Dan Poltawski 76c98ace9a Merge branch 'MDL-37599_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-01-22 11:40:14 +08:00
Dan Poltawski f5222c7416 Merge branch 'MDL-37473-24' of git://github.com/srynot4sale/moodle into MOODLE_24_STABLE 2013-01-22 11:14:32 +08:00
Aparup Banerjee 3a6152ceac Merge branch 'MDL-37540-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-01-22 10:59:53 +08:00
Aparup Banerjee 0e5bf3c4af Merge branch 'MDL-37543-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-01-22 10:56:38 +08:00
Mark Nelson 528b5b7dac MDL-37414 blocks: re-added the ability to add some blocks to the My Moodle 2013-01-22 10:54:13 +08:00
Dan Poltawski bd541e24b3 Merge branch 'MDL-37355-stable24' of git://github.com/mouneyrac/moodle into MOODLE_24_STABLE 2013-01-22 09:06:30 +08:00
Eloy Lafuente (stronk7) d828e8c678 Merge branch 'MDL-36104_m24' of https://github.com/markn86/moodle into MOODLE_24_STABLE 2013-01-22 01:19:52 +01:00
Eloy Lafuente (stronk7) b1886826de Merge branch 'MDL-37539-24' of github.com:damyon/moodle into MOODLE_24_STABLE 2013-01-22 01:06:13 +01:00
Eloy Lafuente (stronk7) 4e63dc5e5d Merge branch 'MDL-28512_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-01-22 01:02:22 +01:00
Eloy Lafuente (stronk7) cf3e5c4965 Merge branch 'wip-mdl-37432-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2013-01-22 00:52:53 +01:00
Aaron Barnes 349fc3edfc MDL-37473 completion: Add missing cap checks to tracked users functions
Namely get_num_tracked_users and is_tracked_user()
2013-01-22 11:18:31 +13:00
Sam Hemelryk dc5e0d1665 Merge branch 'MDL-37563-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-01-22 09:10:31 +13:00
Eloy Lafuente (stronk7) be8bc2de54 Merge branch 'MDL-37577_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-01-21 20:01:46 +01:00
Eloy Lafuente (stronk7) e081622b9b Merge branch 'MDL-35924_m24' of https://github.com/markn86/moodle into MOODLE_24_STABLE 2013-01-21 19:44:14 +01:00
Eloy Lafuente (stronk7) ebe2f5a19c Merge branch 'MDL-34050_m24' of git://github.com/rwijaya/moodle into MOODLE_24_STABLE 2013-01-21 16:47:32 +01:00
Tim Hunt 876ba8faec MDL-37577 quiz overdue handling: optimise database query
This is the standard trick of adding a redundant WHERE clause to a
subquery to help the database realise that it does not have to inspect
so many rows.
2013-01-21 13:23:27 +00:00
Tim Hunt 9970d909a3 MDL-37599 question import: add missing string.
AMOS BEGIN
 MOV [matcherror,question],[invalidgrade,question]
AMOS END
2013-01-21 12:16:15 +00:00
Petr Škoda a8dc59fc54 MDL-37593 use https for editor script if required 2013-01-21 09:41:01 +01:00
Michael de Raadt e6052102ec MDL-35357 Lesson Module: fixed undefined property for $answerformat 2013-01-21 15:38:48 +08:00
Aparup Banerjee 72389d1133 Merge branch 'w03_MDL-37559_m24_otherusers' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-21 15:26:32 +08:00
Rossiani Wijaya 3895b3459e MDL-37375 Report: fixed blog post link from course activity report 2013-01-21 14:58:20 +08:00
Mark Nelson 55cf5dfd8b MDL-36104 mod_assign: added hidden labels to the feedback input fields 2013-01-21 12:51:38 +08:00
Andrew Davis 3396c400eb MDL-37352 core_grade:fixed some ajax display issues 2013-01-21 12:27:52 +08:00
Rossiani Wijaya 58d633f0b2 MDL-19069 RSS feed block: Removed link for remote RSS feeds on navigation 2013-01-21 12:01:14 +08:00
Rajesh Taneja a19a913d7d MDL-37432 Calendar: If Calendar url is invalid then remove invalid subscription 2013-01-21 10:48:30 +08:00
Rajesh Taneja 76657ed83c MDL-37432 Calendar: Added check for empty calendar url 2013-01-21 10:48:30 +08:00
Dan Poltawski 4ef2160966 Merge branch 'MDL-30769_iframe_m24' of git://github.com/rwijaya/moodle into MOODLE_24_STABLE 2013-01-21 10:25:51 +08:00
Dan Poltawski 171c3af461 Merge branch 'wip-mdl-36674-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2013-01-21 10:15:22 +08:00
Dan Poltawski c44fe3050e Merge branch 'MDL-35074_24_2' of git://github.com/pauln/moodle into MOODLE_24_STABLE 2013-01-21 10:08:58 +08:00
Dan Poltawski 6ee3f386bd Merge branch 'MDL-37527-24' of github.com:damyon/moodle into MOODLE_24_STABLE 2013-01-21 10:03:49 +08:00
Dan Poltawski cf82c45de9 Merge branch 'm24_MDL-36421' of git://github.com/danmarsden/moodle into MOODLE_24_STABLE 2013-01-21 09:01:13 +08:00
AMOS bot 537e4d1897 Automatically generated installer lang files 2013-01-21 00:44:53 +00:00
Sam Hemelryk bf14c15fb5 Merge branch 'MDL-37295-m24' of git://github.com/ankitagarwal/moodle into MOODLE_24_STABLE 2013-01-21 10:18:21 +13:00
Sam Hemelryk 9afa0e696e Merge branch 'MDL-35817_m24' of git://github.com/rwijaya/moodle into MOODLE_24_STABLE 2013-01-21 09:46:14 +13:00
Sam Hemelryk c5d97a96e4 Merge branch 'MDL-36757_hidden_24' of git://github.com/andyjdavis/moodle into MOODLE_24_STABLE 2013-01-21 09:31:23 +13:00
Petr Škoda 55fc886ea7 MDL-37559 fix display of multiple roles of other users
Credit goes to Tyron Delean, thanks.
2013-01-19 16:51:29 +01:00
Tim Hunt 2b18a45e61 MDL-28512 qtype essay: clean up properly when a question is deleted. 2013-01-18 11:51:47 +00:00
Mark Nelson 2d8e189825 MDL-35924 filemanager: added label for the input field when creating a new folder 2013-01-18 15:36:05 +08:00
Mark Nelson 0147636391 MDL-37275 webservices: ensure a webservice function is chosen before attempting to add to service 2013-01-18 15:34:06 +08:00
Dan Poltawski 7def53379b weekly release 2.4.1+ 2013-01-18 14:30:35 +08:00
Dan Poltawski 425894422b Merge branch 'install_24_STABLE' of git://git.moodle.cz/moodle-install into MOODLE_24_STABLE 2013-01-18 14:30:30 +08:00
Petr Skoda feb30eda03 MDL-30769 - URL module: always use iframe instead of problematic object tag 2013-01-18 11:24:53 +08:00
Ankit Agarwal 065a7d5b4f MDL-37295 forum: Parse old log entries during restore 2013-01-17 14:33:33 +08:00
Damyon Wiese f2130033d4 MDL-37563 Assignment upgrade: Upgrade conditional activity settings.
Conflicts:

	mod/assign/upgradelib.php
2013-01-17 14:08:52 +08:00
Dan Poltawski cf75be653b Merge branch 'wip-mdl-29534-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2013-01-17 13:47:44 +08:00
Rajesh Taneja e8835af020 MDL-29534 Forum: Fixed userfrom reference problem 2013-01-17 13:46:49 +08:00
Rossiani Wijaya 6b519ea6cc MDL-35817 login: convert html tag to use html_writer and change <a> tag id to be more specific to login 2013-01-17 13:05:52 +08:00
Rossiani Wijaya 999a594039 MDL-35817 Login: set page focus to error message for login error 2013-01-17 13:05:33 +08:00
Damyon Wiese 48410be620 MDL-37539 Assignment upgrade: Disable submission comments if allow notes was not enabled.
For advanced upload of files only - this setting was stored in var2.

Conflicts:

	mod/assign/submission/comments/locallib.php
2013-01-17 12:16:32 +08:00
Rajesh Taneja c21089c81e MDL-35780 Administration: current user email should be always displayed on participants page 2013-01-17 11:56:56 +08:00
Damyon Wiese 36d7050ded MDL-37540 Assignment upgrade: Upgrade setting "Hide description before due date"
Advanced upload of files has this setting which is stored in var3.
2013-01-17 11:54:27 +08:00
Andrew Davis e7052c0349 MDL-36757 course: avoid accidently overwriting the hidden/visible values set on grade items 2013-01-17 11:37:14 +08:00
Damyon Wiese 5132e88b10 MDL-37543 Assignment upgrade: convert advanced upload files "Send for marking" setting
Advanced upload files assignment type has "Enable send for marking" setting instead
of "Allow resubmissions". Needs special handling in upgrade code to convert to
"Require students click submit button".

Conflicts:

	mod/assign/submission/file/locallib.php
2013-01-17 11:22:35 +08:00
Dan Poltawski 2540839f58 Merge branch 'MDL-37374_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-01-17 10:23:07 +08:00
Eloy Lafuente (stronk7) 7b85d7a014 MDL-37555 Apply realpath() 2 CFG->phpunit_dataroot 2013-01-16 20:54:33 +01:00
Tim Hunt e4863a1668 MDL-31616 blocks: ensure showinsubcontexts is only 0 or 1 in the DB. 2013-01-16 19:15:20 +01:00
Tim Hunt db1f584cc2 MDL-37374 questions: fix property_exists calls. 2013-01-16 11:20:58 +00:00
Rajesh Taneja 3fc3fcd333 MDL-32526 Course: After creating course user should be redirected to newly created course
After creating a new course if user has capability to enrol users then
enrol user page should be visible else user should see newly created course
2013-01-16 16:29:11 +08:00
Dan Poltawski 9044bc2f8b Merge branch 'wip-MDL-37536-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-01-16 13:52:07 +08:00
Rajesh Taneja c5a078b25e MDL-35873 Blocks: Made alt-text on block control icons more descriptive 2013-01-16 18:26:27 +13:00
Damyon Wiese 6aafb32f8b MDL-37527 Assignment - Change query for print_overview so it uses an index (postgres)
Reported by Mark Neilsen.

Conflicts:

	mod/assign/lib.php
2013-01-16 13:19:11 +08:00
Davo Smith d8613ef967 MDL-31484 backup - repeated restores with anonymised users now works correctly 2013-01-16 11:45:43 +08:00
sam marshall 90cbde0cb7 MDL-34612 Grade condition range validation allows impossible conditions 2013-01-16 09:56:51 +08:00
Rajesh Taneja 30595c294a MDL-37339 Administration: Unique custom profile should not be checked if it's empty.
Currently we have two options for custom profile fields 'Unique' and 'Required'
If value s not entered for unique and not required field then we should allow
duplicate empty values. If value is entered then we should check for unique input.
In case field is unique and required then it should be always checked as required
field can't be empty.
2013-01-16 09:45:51 +08:00
Dan Poltawski d08da96c20 MDL-37313 question: fix trailing whitespace 2013-01-16 09:40:40 +08:00
Dan Poltawski 7a82b70970 Merge branch 'MDL-37313_24' of git://github.com/jmvedrine/moodle into MOODLE_24_STABLE 2013-01-16 09:39:54 +08:00
Sam Hemelryk 69f83828fc MDL-37536 cache: fixed typo 2013-01-16 14:23:16 +13:00
AMOS bot e08dbd1076 Automatically generated installer lang files 2013-01-16 00:43:43 +00:00
Sam Hemelryk 7288582633 Merge branch 'wip-MDL-35818-stable24' of git://github.com/phalacee/moodle into MOODLE_24_STABLE 2013-01-16 11:03:23 +13:00
Eloy Lafuente (stronk7) 6babcc30ad Merge branch 'MDL-37173-m24' of git://github.com/andrewnicols/moodle into MOODLE_24_STABLE 2013-01-15 21:56:40 +01:00
Eloy Lafuente (stronk7) c7e4ebf3f3 Merge branch 'MDL-37354-stable24' of git://github.com/mouneyrac/moodle into MOODLE_24_STABLE 2013-01-15 21:51:00 +01:00
Tim Hunt 70688fd72e MDL-31616 block editing: show in subcontexts does not work on category pages.
Thanks to Ian David Wild for pointing to the proper fix.
2013-01-15 20:16:03 +01:00
Eloy Lafuente (stronk7) 38d2c7642d Merge branch 'wip-mdl-37062-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2013-01-15 20:06:12 +01:00
Eloy Lafuente (stronk7) 0baee36398 NOBUG: 1 more whitespace, was hurting my eyes all the time. 2013-01-15 19:19:52 +01:00
Eloy Lafuente (stronk7) 5bd1e381aa MDL-33117 Whitespace fixes 2013-01-15 19:10:40 +01:00
Eloy Lafuente (stronk7) c1a8fb414e Merge branch 'MDL-34883_unit_tests_24' of git://github.com/andyjdavis/moodle into MOODLE_24_STABLE 2013-01-15 18:21:27 +01:00
Eloy Lafuente (stronk7) 0218dd4ccb Merge branch 'MDL-37395-m24' of git://github.com/sammarshallou/moodle into MOODLE_24_STABLE 2013-01-15 18:17:24 +01:00
Ben Johnson d8088a359e MDL-36421 SCORM: fix SCORM course format new window popups 2013-01-15 23:17:10 +13:00
Dan Poltawski 37784b037e Merge branch 'MDL-37381-stable24' of git://github.com/mouneyrac/moodle into MOODLE_24_STABLE 2013-01-15 14:29:50 +08:00
Dan Poltawski 9d49ca31b1 Merge branch 'MDL-36708-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-01-15 13:56:26 +08:00
Dan Poltawski a79b88e20c Merge branch 'MDL-37162_24' of git://github.com/pauln/moodle into MOODLE_24_STABLE 2013-01-15 13:33:53 +08:00
Dan Poltawski d9babbcce1 Merge branch 'MDL-37374_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-01-15 12:59:46 +08:00
Jason Fowler d4c4b845b8 MDL-30316 - Libraries - improving pagination output to allow a shifting start page for displays of less than 18 pages -- original code provided by Martha (martha dot morelos at gmail dot com) 2013-01-15 12:49:57 +08:00
Dan Poltawski 391e361387 Merge branch 'MDL-29835_24' of git://github.com/pauln/moodle into MOODLE_24_STABLE 2013-01-15 12:41:46 +08:00
Dan Poltawski 03e63438da Merge branch 'MDL-36616-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-01-15 11:48:18 +08:00
Rossiani Wijaya 96d6ab3a12 MDL-34050 Lesson Module: Fixed spacing and removed array_unique() for responses 2013-01-15 11:19:55 +08:00
Damyon Wiese 545b77c8f2 MDL-37430 Course - Make modules created in hidden sections visible when section is made visible. 2013-01-15 11:17:43 +08:00
Dan Poltawski 3b8535a386 Merge branch 'MDL-37413-m24' of git://github.com/andrewnicols/moodle into MOODLE_24_STABLE 2013-01-15 10:58:36 +08:00
Dan Poltawski b4d896505b Merge branch 'MDL-37194-stable24' of git://github.com/mouneyrac/moodle into MOODLE_24_STABLE 2013-01-15 10:43:29 +08:00
Eloy Lafuente (stronk7) c01b82d4e4 Merge branch 'MDL-37431_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-01-15 00:16:27 +01:00
Marina Glancy b3e8f06d20 MDL-37453 fixing regression from MDL-36550 - label show/hide in AJAX works incorrectly 2013-01-15 00:09:56 +01:00
Petr Škoda 17c88e6ec9 MDL-37483 improve require_login redirect when activity not accessible 2013-01-14 23:30:28 +01:00
Eloy Lafuente (stronk7) bff4fc86e1 Merge branch 'MDL-37485_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-01-14 23:21:53 +01:00
Marina Glancy f939cf3159 MDL-37206 preload course format renderer in course/view.php
Also fixed bug with hardcoded default 'weeks' format
2013-01-15 10:49:13 +13:00
Sam Hemelryk 2dcbaaa68c Merge branch 'MDL-37378_24' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2013-01-15 10:42:52 +13:00
Damyon Wiese f6d09222a2 MDL-37030 Assignment: Fix error on download all submissions.
When group submissions and blind marking are enabled, an error is thrown
when a teacher trys to download all submissions in a zip. The fix is to
move the url rewriting from the plugin to the assign class so it is
done in a standard way by all modules. The rewriting is done to make images
in a text editor field resolve correctly.
2013-01-15 10:40:43 +13:00
Rajesh Taneja 8cb601ad4d MDL-36674 Administration: out_as_local_url will check for both http and https url's
out_as_local_url will first check if url passed in wwwroot, if it's not then it will check
if loginhttps is enabled and url is httpswwwroot
2013-01-14 16:01:01 +08:00
Dan Poltawski ee8044f2e6 Merge branch 'wip-MDL-30797-24' of git://github.com/abgreeve/moodle into MOODLE_24_STABLE 2013-01-14 15:26:16 +08:00
Adrian Greeve 93b38fc5a6 MDL-30797 - backup groups: Added a parameter to the groups_assign_grouping function.
$timeadded has now been included so that the backup / restore functions can now use
this API rather than duplicating the code.
2013-01-14 15:12:49 +08:00
Adam Olley b03d9255ee MDL-30797 backup: Use correct API call for mapping groups to groupings on import/restore 2013-01-14 15:12:29 +08:00
Dan Poltawski 00dba5bb11 MDL-36297 - increment version number 2013-01-14 15:05:56 +08:00
Dan Poltawski 94c4afe13a Merge branch 'wip-MDL-36297-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2013-01-14 15:05:23 +08:00
Dan Poltawski b90eab06c7 Merge branch 'wip-mdl-29534-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2013-01-14 14:59:30 +08:00
Anthony Borrow 88d7468a3b MDL-15930 - admin: reorganize logic to allow ->fullnamedisplay to be used as default sort. 2013-01-14 10:34:02 +08:00
Jason Fowler a809b827f1 MDL-35818 - Enrolment - Changing all enrolment method icon alt text attributes to include the name of the course 2013-01-14 09:47:03 +08:00
Sam Hemelryk b54015e60d Merge branch 'MDL-37048-m24' of git://github.com/ankitagarwal/moodle into MOODLE_24_STABLE 2013-01-14 14:08:45 +13:00
Davo Smith 6cf6c3806f MDL-35568 course dndupload - resources created with the same visibility as the section they are dragged onto 2013-01-14 13:55:59 +13:00
Sam Hemelryk 7e7c23fcad Merge branch 'wip-MDL-35885-stable24' of git://github.com/phalacee/moodle into MOODLE_24_STABLE 2013-01-14 13:39:53 +13:00
Sam Hemelryk 625098abc5 Merge branch 'MDL-36095-m24' of git://github.com/sammarshallou/moodle into MOODLE_24_STABLE 2013-01-14 12:23:49 +13:00
Sam Hemelryk 7977c782e8 Merge branch 'MDL-36511-24' of git://github.com/srynot4sale/moodle into MOODLE_24_STABLE 2013-01-14 12:12:41 +13:00
Sam Hemelryk 842524812a Merge branch 'm24_MDL-37394' of git://github.com/danmarsden/moodle into MOODLE_24_STABLE 2013-01-14 11:46:01 +13:00
Sam Hemelryk 80b6e318fb Merge branch 'MDL-37397-m24' of git://github.com/andrewnicols/moodle into MOODLE_24_STABLE 2013-01-14 11:04:40 +13:00
Sam Hemelryk 7c2046b727 Merge branch 'wip-mdl-35780-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2013-01-14 10:59:47 +13:00
Eloy Lafuente (stronk7) 3e90b10ad8 Moodle release 2.4.1 2013-01-11 22:23:29 +01:00
Tim Hunt 8c11e08765 MDL-37431 question preview: cron performance problem.
This query was performing badly. The solution seems to be to add a
redundant JOIN and WHERE to the subquery.

I renamed the table aliases in the subquery to avoid name collisions
elsewhere. I am afraid that makes the diff rather unhelpful. The
    AND subq_qu.component = :qubacomponent2
line is new. The other lines have just had subq_ added.
2013-01-11 13:05:07 +00:00
Tim Hunt ffdca1520b MDL-37378 quiz restore: timecheckstate not in old backups.
We need to avoid a notice. If the value is missing, setting it to 0 is
fine. It will get sorted out the next time cron is run.
2013-01-11 13:04:50 +00:00
Tim Hunt 4dcede552e MDL-37374 questions: use property_exists rather than isset
$a->field = null; isset($a->field) returns false, which is typical PHP.
I also improve the error handling a bit.
2013-01-11 13:04:31 +00:00
Tim Hunt 198279d303 MDL-37485 plugins overview: require_login before _capability. 2013-01-11 12:52:26 +00:00
Andrew Robert Nicols 283f877719 MDL-37397 Test for a valid select in formautosubmit
Ideally we shouldn't get into this situation, but in cases where the
generated select element is incorrectly configured, we should try and
handle it gracefully with a warning.
2013-01-11 11:50:52 +00:00
Eloy Lafuente (stronk7) 8a646b55f7 weekly release 2.4+ 2013-01-11 12:33:57 +01:00
Michael Aherne 53c07f1644 MDL-27164 groups Do not show multiple instances of the same role as multiple 2013-01-11 11:31:46 +00:00
Eloy Lafuente (stronk7) 72cece6ff4 Merge branch 'install_24_STABLE' of git://git.moodle.cz/moodle-install into MOODLE_24_STABLE 2013-01-11 12:16:34 +01:00
Dan Marsden 1e503b8925 MDL-37394 SCORM: Aicc direct url fails with new nav as it has a single sco with no children - allow these to be navigated correctly. 2013-01-11 23:50:05 +13:00
Eloy Lafuente (stronk7) 9b7b6fa33c MDL-37420 rework pg schema (partial backport of 92b00c3) 2013-01-11 10:33:33 +01:00
Jean-Michel Vedrine dce48cf576 MDL-37313 Sample files with images for XML import 2013-01-11 09:37:44 +01:00
Jean-Michel Vedrine af8a122872 MDL-37313 Moodle XML import format should use draft file areas, not arrays 2013-01-11 09:37:42 +01:00
Andrew Robert Nicols e75fe1a7bd MDL-37413 Use correct variable in chooserdialogue 2013-01-11 08:21:14 +00:00
Ashley Holman a78ba9a827 MDL-36616 repository: Fix direct linking to images in Flickr Public. 2013-01-11 15:34:03 +08:00
Jason Fowler 487a6fcc8c MDL-35885 - Wiki - add a legend element to the search wikis form 2013-01-11 15:30:46 +08:00
Dan Marsden 840193d514 MDL-36853 SCORM: get first valid sco instead of array of scos - thanks to Jamie Smith for the fix - fixes PHP warnings when returning to an existing attempt. 2013-01-11 19:51:32 +13:00
Rossiani Wijaya 324e0aa540 MDL-34050 Lesson Module: improved matching question logic for checking user response. This patch will also resolved MDL-36343. 2013-01-11 13:52:40 +08:00
Rossiani Wijaya 69199e4aa2 MDL-34050 Lesson module: Fixed undefined variable for $qtype 2013-01-11 13:52:28 +08:00
Joseph Rézeau e893d6b032 MDL-34050: Lesson module: fixed matching answer format to use text 2013-01-11 13:52:18 +08:00
Damyon Wiese 1c5d23e281 MDL-32341 calendar: get_file_by_hash() expects a hash 2013-01-11 11:56:59 +08:00
Rajesh Taneja 0b55c44e68 MDL-35780 Administration: email display on user profile view page will respect user capability 2013-01-11 10:16:34 +08:00
Eloy Lafuente (stronk7) 43bfcff941 Merge branch 'MDL-37467-blogs_24' of git://github.com/mudrd8mz/moodle into MOODLE_24_STABLE 2013-01-10 18:20:48 +01:00
David Mudrák a4611b9d02 MDL-37467 Do not provide blog posts via RSS when blogging is disabled 2013-01-10 16:57:10 +01:00
Mark Nelson 5be009245b MDL-36741 mod_forum: fixed the function forum_rss_newstuff that was using count_records_sql incorrectly as well as generating RSS content when no data exists 2013-01-10 11:13:45 +01:00
Frederic Massart 5a2c33b107 MDL-34435 reports: Log category actions
Conflicts:

	version.php
2013-01-10 15:14:38 +08:00
Andrew Robert Nicols a50bf852e4 MDL-36600 Add missing sesskey check when previewing the message 2013-01-10 10:20:45 +08:00
AMOS bot 9c3ef35763 Automatically generated installer lang files 2013-01-10 00:44:11 +00:00
Rajesh Taneja be8868900d MDL-29534 Forum: if forum_replytouser is not set then send forum email using noreplyaddress. 2013-01-09 14:53:04 +08:00
Isaac Marco Blancas 3c3ca35fee MDL-29534 Forum: If forum_replytouser is not set then don't display from user email" 2013-01-09 14:53:04 +08:00
Jerome Mouneyrac ada5df1069 MDL-37354 clean return value for each externallib PHPUnit tests 2013-01-09 13:55:54 +08:00
Aaron Barnes e014ed78dd MDL-36511 course: Save "completion starts on enrolment" disabled state 2013-01-09 15:33:13 +13:00
Marina Glancy 562782a48d MDL-37404 add class 'format-xxx' to the body for the current course format 2013-01-09 14:35:31 +13:00
Eloy Lafuente (stronk7) b56324b829 Merge branch 'w51_MDL-37420_m24_pgschema' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-09 01:32:33 +01:00
Paul Nicholls 490e604bae MDL-37162: Use CSS to make mod show/hide icons not look "clickable" in hidden sections
Previously, the resource toolbox initialiser was using JS to find the show/hide icon, then find its section ancestor, then check if the section was hidden - only to pointlessly set pointer:auto if it was.  That didn't meet the aim stated in the comments ("Disable" show/hide icons (change cursor to not look clickable) if section is hidden), but this patch meets that goal with a single CSS rule.
2013-01-09 11:26:06 +13:00
Andrew Robert Nicols 47ee76344e MDL-36600 user: improve course messaging checks 2013-01-09 09:22:08 +13:00
Eloy Lafuente (stronk7) 844cb63fed Merge branch 'w51_MDL-37152_m24_smtp' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-08 18:02:37 +01:00
Petr Škoda a668f57e75 MDL-37420 add support for db schemas in enrol test 2013-01-08 17:35:59 +01:00
Petr Škoda 543fc34ed9 MDL-37420 add support for more PostgreSQL schemas 2013-01-08 17:35:51 +01:00
sam marshall c3775f93ab MDL-37395 Add .jar filetype so Moodle doesn't incorrectly call it a zip file 2013-01-08 12:50:17 +00:00
Jean-Michel Vedrine 0a32dca4bb MDL-28183 fix for problem during integration
Conflicts:
	question/type/multianswer/question.php
2013-01-08 12:05:45 +01:00
Eloy Lafuente (stronk7) 65a550c484 Merge branch 'MDL-37220_dnd_icon_24' of git://github.com/davosmith/moodle into MOODLE_24_STABLE 2013-01-08 11:54:31 +01:00
Jerome Mouneyrac 7c08fb89fb MDL-37194 activity chooser displays entire list of default activities/resources 2013-01-08 18:03:47 +08:00
Andrew Robert Nicols 38727c6bc6 MDL-37173 Stop attempting to set User-Agent from core JS
This leads to some browsers throwing warnings that it is unsafe to set the
User-Agent. It doesn't help us in any way particularly either.
2013-01-08 09:56:24 +00:00
Eloy Lafuente (stronk7) 0f83a143b0 Merge branch 'w51_MDL-37186_m24_tinymceconfig' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-08 10:34:15 +01:00
Eloy Lafuente (stronk7) 793c431543 Merge branch 'w51_MDL-37323_m24_dlgstrings' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-08 10:22:15 +01:00
Jerome Mouneyrac 7059a421ef MDL-37381 core_external::get_component_strings returns wrong format value 2013-01-08 16:25:24 +08:00
Dan Poltawski 2e25f806fb Merge branch 'MDL-32639-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-01-08 14:46:25 +08:00
Petr Škoda f923f7aefe MDL-xxxx show appropriate instance status on user enrolments page 2013-01-08 14:22:28 +08:00
Jason Fowler cb838a36b2 MDL-36620 - Blog, RSS - Preventing Guests from viewing the RSS of site level blogs 2013-01-08 14:06:47 +08:00
Ankit Agarwal 56f4d0ed80 MDL-37106 calendar: Proper capability checks should be done before processing an ical request 2013-01-08 14:02:54 +08:00
Ankit Agarwal 6c806e8384 MDL-36738 calendar: Display events imported details
We should display a the status of events when a new subscription is added. Although this means we need to redirect through an itermediate page.
2013-01-08 13:58:21 +08:00
Ankit Agarwal 5b6e74c85f MDL-36738 calendar: Ical subscription list should display type of event 2013-01-08 13:58:21 +08:00
Dan Poltawski c33a96f676 MDL-28183 - fix trailing whitespace 2013-01-08 12:18:31 +08:00
Dan Poltawski 9910a5d7eb Merge branch 'MDL-28183_24' of git://github.com/jmvedrine/moodle into MOODLE_24_STABLE 2013-01-08 12:17:58 +08:00
Dan Poltawski 7c8fb69b1c Merge branch 'w51_MDL-37191_m24_plugindelete' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-08 11:16:49 +08:00
Paul Nicholls 3dcd751a4b MDL-29835: filemanager - zero means zero, not unlimited
The form_filemanager constructor was using empty() rather than !isset(),
so overwrote maxfiles=0 with the default (-1).  In addition, the JS UI
treated 0 as unlimited - but the non-JS fallback UI treated it as zero.
This would result in a file manager which allowed files to be
chosen/uploaded, which would then vanish into the void when the backend
saw that the maximum number of files was 0.
2013-01-08 16:11:36 +13:00
Dan Poltawski ef42830b87 Merge branch 'MDL-31641_drag_drop_help_24' of git://github.com/davosmith/moodle into MOODLE_24_STABLE 2013-01-08 10:54:14 +08:00
Charles Fulton 05f8741cee MDL-35130 shibboleth: remove hard-coded string 2013-01-08 10:51:17 +08:00
Dan Poltawski 9a1ac11640 Merge branch 'MDL-36456-24' of git://github.com/FMCorz/moodle into MOODLE_24_STABLE 2013-01-08 10:30:58 +08:00
Dan Poltawski 04ab55dd4f Merge branch 'w51_MDL-37301_m24_coursecatinfoas' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-08 10:27:00 +08:00
Dan Poltawski b2e3fb3dc9 Merge branch 'w51_MDL-37254_m24_courseinfoas' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-08 10:24:11 +08:00
Sam Hemelryk d72a0aa2c8 Merge branch 'wip-mdl-36958-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2013-01-08 14:06:50 +13:00
Sam Hemelryk 2be82d5e13 Merge branch 'w51_MDL-35893_m24_perfinstall' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-08 14:00:23 +13:00
David Mudrák 019cc4eae4 MDL-36977 Be more picky when it comes to migrating files in moodle1 backups 2013-01-08 08:54:20 +08:00
David Mudrák 2726d2a6a4 MDL-36977 Add more unit tests for moodle1 backup conversion 2013-01-08 08:54:20 +08:00
Paul Nicholls 9f1396fb23 MDL-35074: grader report - Ease limit on number of students per page
The limit imposed by max_input_vars "applies only to each nesting level of
a multi-dimensional input array"
(http://www.php.net/manual/en/info.configuration.php#ini.max-input-vars).

Turning the grader report fields into arrays (they were all top-level form
fields, i.e. elements of the top-level array) makes the number of students
become the only limiting factor, thereby allowing us to relax the limit on
number of students per page greatly (to 1 less than max_input_vars, for
safety).
2013-01-08 13:16:25 +13:00
Thanh Le 0c49b6c445 MDL-35794 quiz: config for whether Outcomes are advanced settings 2013-01-07 22:40:31 +01:00
Thanh Le 83a23ea878 MDL-35792 question preview: way to update options without restarting.
It is useful, and possible, to update the display options without
restarting the question. You now only have to restart if you are
changing the maximum mark or the behaviour.
2013-01-07 22:36:17 +01:00
sam marshall 331bbb7f05 MDL-36095 Section availability: Make behaviour consistent with activities 2013-01-07 15:56:16 +00:00
Eloy Lafuente (stronk7) f849d1f6fc Merge branch 'w51_MDL-36807_m24_mysocket' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-07 11:44:54 +01:00
Frederic Massart 217d7979b9 MDL-36708 files: Checking the size limit of a draft area does include references 2013-01-07 17:29:04 +08:00
Davo Smith 2e8da707a0 MDL-31641 filemanager - display help message when drag and drop upload is not supported 2013-01-07 08:14:13 +00:00
Didier Raboud f4537d5676 MDL-37157: Normalize short answers before comparison
This ensures that ambiguous Unicode representations can be compared sanely.
Also add some tests to ensure it keeps working.

Thanks to Tim Hunt for the syntax check.
2013-01-07 14:00:13 +08:00
Dan Poltawski 850aa189e4 Merge branch 'w51_MDL-37128_m24_rssrestore' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-07 13:57:02 +08:00
Dan Poltawski c5e96ad32f Merge branch 'w51_MDL-36893_m24_mnetestrict' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-07 13:53:19 +08:00
Dan Poltawski 9acc49eb93 Merge branch 'MDL-27884-m24' of git://github.com/ankitagarwal/moodle into MOODLE_24_STABLE 2013-01-07 13:30:34 +08:00
Andrew Davis 662cfbc7e1 MDL-33117 grade: adding unit tests for the user report function inject_rowspans() 2013-01-07 11:59:58 +08:00
Damyon Wiese d389a2f7f4 MDL-37244 Assignment: Submission comments plugin does not implement comments callbacks.
This allows anyone to view or modify anyone elses submission comments.
2013-01-07 10:49:12 +08:00
Ankit Agarwal 321554d35f MDL-33340 completion: Incorrect logic in hidden field check
Credit to Jody Steele
2013-01-07 10:37:26 +08:00
Simon Coggins 102903f7ab MDL-35991 - use PARAM_LOCALURL for local urls 2013-01-07 10:10:22 +08:00
Rajesh Taneja da2ea965dc MDL-37062 Course: Show one 'Add new course' button
Currently if there is no course and admin/course creator go to create course, he/she see two
'Add new course' buttons.
2013-01-07 09:46:06 +08:00
Dan Poltawski 181b7f5fea Merge branch 'MDL-36667-24' of git://github.com/damyon/moodle into MOODLE_24_STABLE 2013-01-07 09:44:59 +08:00
Sam Hemelryk e04f57c95b Merge branch 'MDL-37161-moodle24' of https://github.com/StudiUM/moodle into MOODLE_24_STABLE 2013-01-07 14:15:17 +13:00
Sam Hemelryk b9639c524d Merge branch 'w51_MDL-36212_m24_entities' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-07 13:44:54 +13:00
Tim Hunt 56003ca491 MDL-37068 qformat_learnwise: fix UTF8 and other issues. 2013-01-07 13:40:24 +13:00
Sam Hemelryk 192cb8f894 Merge branch 'w51_MDL-37281_m24_othersnav' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-07 13:35:04 +13:00
Sam Hemelryk 2d7c42275f Merge branch 'MDL-36855-m24' of git://github.com/ankitagarwal/moodle into MOODLE_24_STABLE 2013-01-07 12:05:07 +13:00
Charles Fulton ac41913cea MDL-4781 forum: show discussion link when user has ability to view discussion 2013-01-07 11:15:32 +13:00
Davo Smith 359c790b1c MDL-35887 course dndupload - correct default used for completion tracking when resources created by drag and drop 2013-01-07 11:07:37 +13:00
Sam Hemelryk 49a66d4b68 Merge branch 'MDL-16730-m24' of git://github.com/ankitagarwal/moodle into MOODLE_24_STABLE 2013-01-07 10:15:11 +13:00
Sam Hemelryk 1a5a5f8e9c Merge branch 'w51_MDL-37105_m24_catlimit' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-07 09:52:50 +13:00
Mark Nelson 3735e3d289 MDL-37359 groups: fixing typo in the web service function create_groupings_parameters 2013-01-07 09:47:43 +13:00
Sam Hemelryk 2c6b79365b Merge branch 'MDL-29327_none_24' of git://github.com/andyjdavis/moodle into MOODLE_24_STABLE 2013-01-07 09:35:07 +13:00
Mark Nelson 1565171e07 MDL-36741 mod_forum: fixed SQL that was generated when either timed posts or groups were enabled 2013-01-07 09:16:35 +13:00
Sam Hemelryk 0c1be2af21 Merge branch 'w51_MDL-37315_m24_ldappaging' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2013-01-07 09:09:25 +13:00
Jean-Philippe Gaudreau e5d70123c9 MDL-37161 Backup: Database error caused by grade book settings when importing or restoring a course 2013-01-04 09:54:42 -05:00
Damyon Wiese 3d6b1bf4e3 MDL-36712: Assignment - Do not always send feedback available emails when grade is created
The entry in the assign_grades table contains grades feedback and other settings such as locked.
Only send the student an email about new feedback if it is actually grades or feedback that
has been added. This is done by using another state for the mailed flag (2) which means "unset".
2013-01-04 14:52:14 +08:00
Jerome Mouneyrac 0d268d71d2 MDL-37355 Fix the REST server that didn't send back the cleaned values 2013-01-04 14:37:06 +08:00
Andrew Davis b164a8904a MDL-29327 core_grade: removing some code that is messing up the categories and items screen when no grade categories are used 2013-01-04 08:58:34 +08:00
Ankit Agarwal 78ac8558e0 MDL-36855 scorm: update to api get_scorm_question_count()
get_scorm_question_count() should return 0 not 1 when no attempt is made in a scorm by any student
2013-01-03 14:42:39 +08:00
Sam Hemelryk 118e933e2d MDL-36297 caching: added for HTML purified text 2013-01-03 10:54:57 +13:00
Ankit Agarwal 363ed37e76 MDL-27884 Implement proper username validation during csv import 2013-01-02 14:10:30 +08:00
Ankit Agarwal 3b800be056 MDL-27884 blocks: Correcting config title string
AMOS BEGIN
 CPY [configtitle,block_html],[configtitle,block_tags]
AMOS END
2013-01-02 10:56:58 +08:00
Petr Škoda ef227f1e0f MDL-35893 do not track performance before installation 2013-01-01 15:51:06 +01:00
Petr Škoda 6606784c3f MDL-37323 add support for _dlg strings in our TinyMCE subplugins
Credit goes to Étienne FLORENT, thanks.
2013-01-01 15:26:27 +01:00
AMOS bot a17b3a200e Automatically generated installer lang files 2013-01-01 00:42:59 +00:00
Eloy Lafuente (stronk7) d63a406b02 weekly release 2.4+ 2012-12-30 01:06:09 +01:00
Petr Škoda e6a3c6e1a1 MDL-37315 fix connection reopening in ldap paging 2012-12-30 00:58:20 +01:00
Eloy Lafuente (stronk7) 356513cc80 Merge branch 'install_24_STABLE' of git://git.moodle.cz/moodle-install into MOODLE_24_STABLE 2012-12-30 00:56:49 +01:00
Petr Škoda b1dc798512 MDL-36893 fix mnet E_STRICT issue 2012-12-27 14:33:09 +01:00
Petr Škoda 697871ddcf MDL-37105 prevent fatal error when category limit reached 2012-12-27 13:52:50 +01:00
Petr Škoda 602150068a MDL-37128 fix E_STRICT rss restore issue 2012-12-27 13:40:47 +01:00
AMOS bot eeeac779c8 Automatically generated installer lang files 2012-12-27 00:42:49 +00:00
Petr Škoda c0333c98ea MDL-37301 fix missing AS in select
This was breaking pg 8.3. Credit goes to Thomas Robb, thanks.
2012-12-26 22:31:47 +01:00
Damyon Wiese d59467dfc9 MDL-37037 Assignment Some minor refactoring of the previous patch
This just makes the control flow a bit easier to read.

I also added a continue button to take you back to the grading page.
2012-12-24 12:23:33 +08:00
Michael Aherne c731018d50 MDL-37037 assign Show message if no files to download 2012-12-24 12:23:33 +08:00
Dan Poltawski e17644cca3 Merge branch 'w51_MDL-37233_m24_skype' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-24 11:34:45 +08:00
Dan Poltawski d71b142446 Merge branch 'wip-MDL-37263-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2012-12-24 11:22:48 +08:00
Dan Poltawski b61dd8b299 Merge branch 'wip-MDL-37290-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2012-12-24 10:55:24 +08:00
Dan Poltawski 41bbc35471 Merge branch 'w51_MDL-37283_m24_spell' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-24 10:35:40 +08:00
Sam Hemelryk 0af4bf40ee MDL-37290 course: fixed up navbar when editing categories 2012-12-24 13:06:52 +13:00
Sam Hemelryk b09c5ac837 Merge branch 'wip-MDL-35833-stable24' of git://github.com/phalacee/moodle into MOODLE_24_STABLE 2012-12-24 11:43:46 +13:00
Raymond Wijaya 3f897939b2 MDL-36966 Assignment: Bug - Student submission appears graded by themselves.
Fix a bug when a student editing his submission after it has been graded, it changes the 'graded by' details to the student's name in the feeback summary
2012-12-24 11:18:43 +13:00
Sam Hemelryk 3124654247 Merge branch 'wip-mdl-37015-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2012-12-24 10:55:19 +13:00
Sam Hemelryk 9a57563b9f Merge branch 'wip-MDL-35653-MOODLE_24_STABLE' of git://github.com/abgreeve/moodle into MOODLE_24_STABLE 2012-12-24 09:40:44 +13:00
Brian King 190b5e7cbe MDL-37225 reset cachstore_static store when purging 2012-12-24 09:36:13 +13:00
Mark Nelson a8f8537965 MDL-36455 blocks: removed ability to add blocks to the My Moodle page that did not make sense in that context 2012-12-24 09:31:02 +13:00
Petr Škoda f938b1a89b MDL-37283 import tinymce spellchecker 2.0.6.1 2012-12-22 16:45:22 +01:00
Petr Škoda 2a39a4e01c MDL-37281 fix other users current navigation node 2012-12-22 14:59:12 +01:00
Petr Škoda ab7d4ea7ba MDL-37152 remove bogus $mail->IsSMTP() breaking non-smtp mailing
Credit goes to Aurelijus Bruzas, thanks.
2012-12-22 14:48:25 +01:00
Petr Škoda ac4404e0cc MDL-37254 add missing AS keyword 2012-12-22 14:12:30 +01:00
Petr Škoda 0fe16db123 MDL-37233 do not show skype status icon on https sites
Funny that the same company that implemented the IE security warnings is unable to set up SSL on the Skype status server…
2012-12-21 17:27:12 +01:00
Petr Škoda 5c0dd1fadd MDL-37191 do not timeout when uninstalling plugins 2012-12-21 15:59:15 +01:00
Jean-Michel Vedrine a7eec81ec6 MDL-28183 add num parts correct and clear wrong to multianswer 2012-12-21 05:18:02 +01:00
Sam Hemelryk e03782efdd MDL-37263 cache: fixed event invalidation coding error 2012-12-21 10:50:24 +13:00
Petr Škoda eb2d6a23ab MDL-36212 rework html entity conversions
This should resolve all html entity conversion problems in different PHP versions.
2012-12-20 22:48:30 +01:00
Petr Škoda a48b376978 MDL-36807 use our mysql socket logic in adodb tests 2012-12-20 22:41:57 +01:00
Petr Škoda 544f0f9b11 MDL-37186 add the ultimate TinyMCE custom parameter setting 2012-12-20 22:24:46 +01:00
Eloy Lafuente (stronk7) 322af447f5 weekly release 2.4+ 2012-12-20 21:12:50 +01:00
Eloy Lafuente (stronk7) ec39bd51dd Merge branch 'install_24_STABLE' of git://git.moodle.cz/moodle-install into MOODLE_24_STABLE 2012-12-20 20:57:11 +01:00
Eloy Lafuente (stronk7) bbb750e1ba Merge branch 'w50_MDL-37171_m24_outdatedexcel' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-20 10:41:55 +01:00
Jason Fowler 73dd2ee2d5 MDL-35833 - Blocks - Adding alt and title attributes to the docked-block panel close button 2012-12-20 10:28:23 +08:00
Rajesh Taneja a1ccc146ac MDL-37015 Resource: link in onclick should not contain html special char 2012-12-20 10:26:29 +08:00
Dan Poltawski 7a6f073415 Revert "MDL-36704: wrap pending conditions in span tags"
This reverts commit 5e9fd83df8.
2012-12-20 08:45:15 +08:00
AMOS bot 76fa287781 Automatically generated installer lang files 2012-12-20 00:40:36 +00:00
Tim Hunt 94c5a8fe82 MDL-32245 question bank: update URL after moving question between categories.
Also, improve the URL when you go to edit the questions in a category.
2012-12-20 12:12:28 +13:00
Petr Škoda d3fdafc358 MDL-37171 fix some more E_STRICT issues
Credit goes to Mark Nelson, thanks.
2012-12-19 09:55:25 +01:00
Davo Smith 606c07ae3e MDL-37220 course dndupload - improved 'add files' icon 2012-12-19 07:46:23 +00:00
Adrian Greeve c6b458edce MDL-35653 - mod/wiki: Force format now lets users edit wiki pages.
Thanks to Tõnis Tartes for part of this solution.

When force format was selected in the options, trying to view the
wiki would redirect to the front page with a message saying that
you do not have permission to edit this page. Students had no way
of viewing any entries or creating the first page.

When in force format it skips a page , which would be considered
uncessary for students, but this means that the group id is not set
and this is what is causing most of the problems.

I also have included a check to see if the title is default and whether
the user has permission to view all groups. In these situations the
intermediate page is displayed.
2012-12-19 08:51:48 +08:00
Eloy Lafuente (stronk7) a8ccdd2880 Merge branch 'w50_MDL-36245_m24_convert' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-18 23:42:53 +01:00
Marina Glancy 656581fa2c MDL-36339 Modify themes to add course headers and footers provided by course format 2012-12-18 21:37:05 +01:00
Matt Oquist 785a713b82 MDL-36958 Forum: Replaced hard-coded numbers with proper defines 2012-12-18 17:24:31 +08:00
Jay Knight cf04387947 MDL-36704: wrap pending conditions in span tags 2012-12-18 15:09:55 +08:00
Dan Poltawski eddec24752 Merge branch 'MDL-37014_webdav_folders_24' of git://github.com/davosmith/moodle into MOODLE_24_STABLE 2012-12-18 14:52:33 +08:00
Dan Poltawski f454c9884f MDL-36259 - change case of table alias to match definition 2012-12-18 14:27:40 +08:00
Thanh Le 53f7c0c641 MDL-36259 course short names: ensure it displays when enabled in admin
Fixed 5 Moodle pages that does not display the course short name even if "Display extended course names" setting is on.  In fixing this, search.php also included related minor code to change to minimise DB calls to improve performance.
2012-12-18 14:26:02 +08:00
Dan Poltawski 2de5b09d84 Merge branch 'MDL-30899_24' of git://github.com/dmonllao/moodle into MOODLE_24_STABLE 2012-12-18 09:11:02 +08:00
Damyon Wiese 70c31beef7 MDL-35740 Assignment: Change the assignment index page to use a renderer.
This also cleans up the patch to prevent students from seeing the number of submissions for the assignment.
2012-12-18 08:44:59 +08:00
Raymond Wijaya 901dd625f8 MDL-35740 Assignment: Hide the number of assignment submissions for all students that was visible to all students through the activities block 2012-12-18 08:44:59 +08:00
Tim Hunt 7d3341b000 MDL-36842 quiz: update accessrule upgrade.txt file in master. 2012-12-18 00:18:59 +01:00
Eloy Lafuente (stronk7) 1f60fe8a23 Merge branch 'w50_MDL-37171_m24_outdatedexcel' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-18 00:13:55 +01:00
Sam Hemelryk 730271af49 Merge branch 'w50_MDL-36475_m24_zindexesgrrr' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-18 10:42:49 +13:00
Sam Hemelryk 8a35efacd7 Merge branch 'MDL-36490_M24' of git://github.com/lazydaisy/moodle into MOODLE_24_STABLE 2012-12-18 10:40:32 +13:00
Adrian Fish cfa9c7e1d0 MDL-37035 Pass user locale after course locale. 2012-12-18 10:32:24 +13:00
Sam Hemelryk acb011dc20 Merge branch 'w50_MDL-37111_m24_forumsinglefirst' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-18 10:24:42 +13:00
Sam Hemelryk a7a1adf4e0 Merge branch 'MDL-37176_24' of git://github.com/stronk7/moodle into MOODLE_24_STABLE 2012-12-18 10:12:22 +13:00
Rossiani Wijaya e60bae3575 MDL-35530 Lesson Module: Add question text to facilitate grading 2012-12-18 10:08:53 +13:00
Sam Hemelryk ddb5fb5980 Merge branch 'wip-MDL-35056-stable24' of git://github.com/phalacee/moodle into MOODLE_24_STABLE 2012-12-18 09:57:11 +13:00
Tim Hunt b70a545c88 MDL-32245 question bank: fix coding style in categories.php 2012-12-18 09:52:30 +13:00
Thanh Le c383f33bbf MDL-32245 question bank: fix moving categories between contexts. 2012-12-18 09:52:30 +13:00
Sam Hemelryk 13683200d6 MDL-36812 grader_report: Fixed whitespace on integration 2012-12-18 09:48:01 +13:00
Nadav Kavalerchik 7be97bd89d MDL-36812 - Enabling grade_report_fixedstudents, shows the user's list on the left side of the page, in RTL mode (theme/standard) 2012-12-18 09:48:01 +13:00
Sam Hemelryk cd281ce1b4 Merge branch 'MDL-29733_master' of git://github.com/andyjdavis/moodle into MOODLE_24_STABLE 2012-12-18 09:42:41 +13:00
David Monllao adc1d7b2a5 MDL-30899 moodle-core-notification Overridding default footer padding 2012-12-17 16:27:30 +08:00
David Monllao b4454b133f MDL-30899 moodle-core-notification Adding ARIA attributes 2012-12-17 16:27:08 +08:00
David Monllao 520a601f14 MDL-30899 moodle-core-notification Adding close button title for accessibility 2012-12-17 16:27:01 +08:00
David Monllao 0409483d5f MDL-30899 moodle-core-notification Adding focus to non modal windows 2012-12-17 16:26:56 +08:00
David Monllao 2d07933c17 MDL-30899 moodle-core-notification Adding H1 to notifications headers 2012-12-17 16:26:43 +08:00
David Monllao 6eabdb6d8c MDL-30899 block_community Changing from overlay to panel references 2012-12-17 16:26:09 +08:00
David Monllao 291455cecd MDL-30899 modchooser Changing from overlay to panel references 2012-12-17 16:26:03 +08:00
David Monllao b76204d589 MDL-30899 moodle-core-notification Replacing Y.Overlay for Y.Panel
References to lightbox are still there to maintain the same
external API but are converted to a modal attribute internally,
same with closeButton, now it uses the Y.Panel close button
2012-12-17 16:25:51 +08:00
Dan Poltawski e8e9393e76 Merge branch 'w50_MDL-36493_m24_mysql' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-17 15:29:07 +08:00
Joseph Rezeau 231f758404 MDL-37114 quiz form validation: feedback boundaries.
The feedback boundaries must either be a number or a percentage.
We were not correctly validating the non-percentage case.
2012-12-17 15:26:07 +08:00
Andrew Davidson e92d664dd2 MDL-37034 - Added appropriate name to category settings navigation node 2012-12-17 15:21:57 +08:00
Dan Poltawski 973fe984cd Merge branch 'w50_MDL-36597_m24_courselang' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-17 13:53:06 +08:00
Mark Nelson 4548df3155 MDL-29334 mod_data: if site-wide presets created in <= 1.9 exist convert them to 2.x 2012-12-17 13:48:15 +08:00
Rajesh Taneja c874cee03a MDL-36736 course: Availability information should not be visible for hidden modules
If user is viewing hidden module, availability information should only be visible to
user when editing and module is visible. If editing and module is hidden, then hide
availablilty information as it's invalid.
When user is not editing and activity is hidden then don't add availability information.
2012-12-17 12:09:30 +08:00
Rajesh Taneja caeb7f90b0 MDL-36736 course: Availability information will use hide class for hidding 2012-12-17 12:09:30 +08:00
Dan Poltawski da264959f2 Merge branch 'wip-MDL-25928-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2012-12-17 12:05:12 +08:00
Dan Poltawski 41e1109c5f Merge branch 'wip-MDL-35874-stable24' of git://github.com/phalacee/moodle into MOODLE_24_STABLE 2012-12-17 11:52:59 +08:00
Dan Poltawski 209b2f7b3e Merge branch 'wip-MDL-35979-s24' of git://github.com/phalacee/moodle into MOODLE_24_STABLE 2012-12-17 11:48:39 +08:00
Dan Poltawski 503325ddcb Merge branch 'MDL-37078-m24' of git://github.com/sammarshallou/moodle into MOODLE_24_STABLE 2012-12-17 11:37:02 +08:00
Damyon Wiese 41575c5571 MDL-37165 Assignment: Oracle fix for count_submissions_with_status (and friends).
Oracle does not like the use of AS after a join.
2012-12-17 11:31:31 +08:00
Sam Hemelryk 73f60c1886 MDL-25928 course: Fixed course info on the combo list to be a popup 2012-12-17 16:03:34 +13:00
Petr Škoda dc7c91ae67 MDL-37171 fix multiple spreadsheet related PHP4isms 2012-12-15 12:38:12 +01:00
Petr Škoda 15dbd27efa MDL-36245 add tests for the buggy utf-8 to utf-8 conversion 2012-12-15 11:50:44 +01:00
Petr Škoda 9a05bd0f8f MDL-36245 try to workaround buggy iconv() when converting text from utf-8 to utf-8 2012-12-15 11:50:43 +01:00
Petr Škoda 524e1ce789 MDL-36475 tweak zIndexes once more
The expected ranges are now:
* 0-1000 for normal code
* 5000-5999 for TinyMCE
* 7000-8999 for filepicker and filemanager

This patch fixes also incorrect location of "MDL-25736 - French spellchecker fixes." modification reminder.
2012-12-15 11:47:16 +01:00
Petr Škoda 3d4de0bc4e MDL-36493 improve timeout handling in mysql upgrade
Credit goes to Mark Nielsen, thanks.
2012-12-15 11:44:18 +01:00
Petr Škoda 1264dd11a0 MDL-36493 improve performance of mysql unsigned/lob upgrade 2012-12-15 11:44:18 +01:00
Petr Škoda 599e7fe006 MDL-37111 copy first post files in single type forum using intro options
This patch also removed the delete button from the first post in single
discussion type forum.

Edit button in the first post leads to the forum edit page now, this should
prevent other problems throwing first post and intro out of sync.
2012-12-15 11:24:16 +01:00
Petr Škoda b768c6f77a MDL-36597 strip '_utf8' from all course.lang fields 2012-12-15 11:16:12 +01:00
Eloy Lafuente (stronk7) 4651e4e464 MDL-37176 timezones: updated to 2012j 2012-12-14 20:08:19 +01:00
Eloy Lafuente (stronk7) 4c7e6ea021 weekly release 2.4+ 2012-12-14 13:31:08 +01:00
Frederic Massart 46b0673732 MDL-36456 repository: S3 handles errors in a nicer way 2012-12-14 17:57:19 +08:00
Damyon Wiese 9c2d41fce2 MDL-30700 tablelib: Fixed get_sort_for_table to work with text sorting columns for oracle
This change stores the list of columns that require text sorting in the session,
so the static function "get_sort_for_table" can work without any additional parameters.
2012-12-13 10:32:23 +01:00
Jason Fowler c5148e0ab6 MDL-35874 - Blocks - Adding a label to the 'Add a block' block's select field 2012-12-13 15:09:45 +08:00
Jason Fowler 8bd65e7aaa MDL-35056 - Backup/Restore - Converting the 'Unmet Dependencies' Message to be a Developer Debug message to make moodle less confusing to the average user 2012-12-13 11:10:56 +08:00
Tim Hunt 4dbdc18fd8 MDL-36897 quiz review: fixup previous commit. 2012-12-13 09:54:28 +08:00
sam marshall 9789d825c2 MDL-37078: Restore - section restore fails with multiple availability conditions 2012-12-12 12:15:41 +00:00
Davo Smith 8f0019214e MDL-37014 repository_webdav - strip the server URL from file & folder paths returned by webdav lib (if present) 2012-12-12 08:55:17 +00:00
Frederic Massart 45cff73a1b MDL-32639 files: Zipping a folder does not overwrite existing files 2012-12-12 14:50:10 +08:00
Frederic Massart aa0cd4a7ef MDL-32639 files: Improved File Manager download and zip support
Conflicts:

	lib/filestorage/zip_packer.php
2012-12-12 14:50:10 +08:00
Vadim Dvorovenko 785e3deb4d MDL-32639 files: Removing '0' start folder in archives created with filemanager
Signed-off-by: Vadim Dvorovenko <vadimon@mail.ru>

Conflicts:

	lib/filestorage/zip_archive.php
2012-12-12 14:43:45 +08:00
Sam Hemelryk 7a4b7c5e18 MDL-33448 enrol_manual: Reduced JS get_string calls for the yui widget 2012-12-12 09:37:36 +08:00
Sam Hemelryk dc5c56e90c MDL-33448 enrol_manual: Reordered things to improve JS performance when enrolling users 2012-12-12 09:37:36 +08:00
Cathal O'Riordan 26679bee33 MDL-36644 Assignment: prepend the course upload limit to the options array
Ensure that the course upload limit is the first option in the list of available choices for the Maximum submission size select.
2012-12-12 08:57:13 +08:00
Dan Marsden 1076d79905 MDL-35737 SCORM: when scorm_parse is called and external scorm manifest use always update the package. 2012-12-12 08:44:00 +08:00
Paul Nicholls 0034f04164 MDL-27619: Prevent teachers from turning course Outcomes into site-wide ones
Similar to the issue which allowed teachers to create site-wide scales by editing a course-specific scale (MDL-24682), teachers could also promote a course-specific scale to a site-wide (standard) by editing it.  As with MDL-24682, removing the course ID check (leaving just the capability check) prevents this unauthorised creation of site-wide (standard) outcomes.
2012-12-12 11:10:35 +13:00
Paul Nicholls 1ff2b56319 MDL-32880: Add moodle1 backup converter for rss_client block.
Creates a shell rss_client.xml file, which contains no feeds.  This makes it behave the same as restoring a Moodle 1.9 backup into a different 1.9 site - the block is created, its title is as per the original course, but it has no feeds selected (and none are added to the site's feed list).
2012-12-11 22:49:13 +01:00
Paul Nicholls 4d9b4e9782 MDL-32880: Add moodle1 backup converter for html block.
This converter processes the HTML block's content, migrating any referenced files.
2012-12-11 22:49:05 +01:00
Paul Nicholls f51fdc9bb7 MDL-32880: moodle1 backup converter: add generic block handler
This handler will automatically be used for any block which does not provide its own handler, and should be subclassed by any block which needs to do anything extra (or different).

This commit incorporates contributions from Mike Churchward and API design suggestions from David Mudrak.
2012-12-11 22:48:54 +01:00
Matteo Scaramuccia f1c403dcec MDL-36641 Missing HTTP check when using an external resource 2012-12-11 22:42:42 +01:00
Sam Hemelryk ab1f9aa3a4 MDL-29805 redirect: added check REQUIRE_CORRECT_ACCESS is true 2012-12-12 09:46:55 +13:00
Sam Hemelryk 1ce6bdd1dd Merge branch 'MDL-29805-24' of git://github.com/mouneyrac/moodle into MOODLE_24_STABLE 2012-12-12 09:45:17 +13:00
Jerome Mouneyrac e20e67161c MDL-35593 core_webservice_get_site_info returns version number set to PARAM_TEXT and PARAM_FLOAT 2012-12-12 09:39:04 +13:00
Sam Hemelryk c545dcad4f Merge branch 'wip_24_mdl-37088_bad_operator_ldap_sync_user' of https://github.com/iarenaza/moodle into MOODLE_24_STABLE 2012-12-12 09:34:44 +13:00
Sam Hemelryk 9e9dd64c35 Merge branch 'MDL-36321_message_participants_24' of git://github.com/andyjdavis/moodle into MOODLE_24_STABLE 2012-12-12 09:29:12 +13:00
Damyon Wiese c6c7a7be8c MDL-30700 Assignment 2.2: Added text_sorting function to tablelib
Allows oracle to sort by text (clob) columns (should be used sparingly).
2012-12-11 19:57:57 +01:00
Eloy Lafuente (stronk7) e958133ca6 MDL-37032 upgrade: define all the 2.4.0 points 2012-12-11 13:12:03 +01:00
Dan Poltawski 9261144beb Merge branch 'w49_MDL-36447_m24_gdtest' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-11 17:54:37 +08:00
Tim Hunt 71cc181bac MDL-37098 quiz: event handler fails deleting group with no overrides
This was a regression from MDL-35717.
2012-12-11 17:52:04 +08:00
Jean-Michel Vedrine cf617e112f MDL-36243 question->questiontext and question->generalfeedback should always be strings 2012-12-11 16:24:24 +08:00
Dan Poltawski 865485fc54 Merge branch 'wip-MDL-36108-stable24' of git://github.com/phalacee/moodle into MOODLE_24_STABLE 2012-12-11 16:03:34 +08:00
Jason Fowler a595b4dacb MDL-36108 - Blocks - Online User block's user image's alt attribute is now empty to prevent repetition of text for screen readers 2012-12-11 15:50:31 +08:00
Dan Poltawski 7c431a345f Merge branch 'wip-MDL-36938-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2012-12-11 15:19:08 +08:00
Damyon Wiese 4dbc9b0a64 MDL-36712: Assignment grading with custom scale is affected by the current language 2012-12-11 14:01:01 +08:00
Damyon Wiese 9242214612 MDL-36591 Assignment - rewrite image urls in online text summaries 2012-12-11 13:56:58 +08:00
Tim Hunt 4832c70022 MDL-36897 quiz: redirect teachers from summary to review page.
There is already logic like this at the top of attempt.php. If the
teacher arrives at one of these pages for a student's attempt, for
example by clicking a link in the logs, then they should be redirected
to the review page to see the students attempt in its current state.
2012-12-11 13:54:47 +08:00
Andrew Robert Nicols 54fdd4c0e9 MDL-34791 AJAX Update a graded activity's title in the gradebook on rename 2012-12-11 13:22:56 +08:00
sam marshall 0324045e4f MDL-36808 Completion: Incorrect escaping for activity name in completion tickbox 2012-12-11 12:19:32 +08:00
Dan Poltawski fac9ba991b Merge branch 'w49_MDL-36983_m24_ordertext' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-11 12:09:34 +08:00
Dan Poltawski ae5ecea065 Merge branch 'w49_MDL-36892_m24_enrolreadme' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-11 12:07:13 +08:00
Tim Hunt 6357dd08b6 MDL-36845 excel export: don't output invalid sheet names.
We should clean any proposed worksheet name, to remove the characters
that Excel does not allow.
2012-12-11 11:59:20 +08:00
Adam Olley c15b286f88 MDL-36828: mod_scorm: Allow deletion of scorm modules if no scorm_scoes data exists 2012-12-11 11:44:24 +08:00
Dan Poltawski 4afa0b50c7 Merge branch 'wip-MDL-36110-s24' of git://github.com/phalacee/moodle into MOODLE_24_STABLE 2012-12-11 11:33:14 +08:00
Dan Poltawski b90b9b83bd Merge branch 'wip-MDL-35884-s24' of git://github.com/phalacee/moodle into MOODLE_24_STABLE 2012-12-11 11:17:33 +08:00
Tim Hunt 79bf1e37ca MDL-36650 don't change question timecreated or timemodified on restore. 2012-12-11 16:11:17 +13:00
Matt Petro 95ae9d9e5e MDL-36025 qtype calculated: Fix handling of "-0" 2012-12-11 11:07:24 +08:00
Sam Hemelryk 7027fe4538 Merge branch 'w49_MDL-36731_m24_uploadestrict' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-11 16:04:19 +13:00
Damyon Wiese 50f3d7b5ea MDL-35476 Assignment: Make submissions_open public so it can be used by plugins 2012-12-11 10:49:30 +08:00
Rossiani Wijaya 22fc0c5e9b MDL-36905 accessibility for assignment grading: add label for grading actions and operations select options 2012-12-11 15:44:57 +13:00
Sam Hemelryk 6ff1745873 Merge branch 'MDL-36916' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2012-12-11 15:42:08 +13:00
Luke Tucker 505530eaf5 MDL-34052 assignment - Disable submission and feedback plugins based on assign type when upgrading 2012-12-11 10:39:32 +08:00
Sam Hemelryk a2630c08ae Merge branch 'w49_MDL-36936_m24_composerdev' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-11 15:35:04 +13:00
Dan Poltawski fddbdb79db Merge branch 'w49_MDL-31424_m24_paypalcase' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-11 10:31:36 +08:00
Sam Hemelryk 1c90b9976d Merge branch 'w49_MDL-37060_m24_sessinit' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-11 15:27:14 +13:00
Sam Hemelryk 35cb0e4a4c Merge branch 'MDL-36942' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2012-12-11 15:04:22 +13:00
Sam Hemelryk ada098890b Merge branch 'MDL-36954' of git://github.com/timhunt/moodle into MOODLE_24_STABLE 2012-12-11 15:00:00 +13:00
Jerome Mouneyrac 2e8b836243 MDL-36773 timezone inconsistency => some number support decimal other don\'t - Original patch author: Nathan Mares 2012-12-11 09:57:22 +08:00
Sam Hemelryk b004c163ee Merge branch 'wip-mdl-37017-m24' of git://github.com/rajeshtaneja/moodle into MOODLE_24_STABLE 2012-12-11 14:53:49 +13:00
Sam Hemelryk 6d0c04c208 Merge branch 'w49_MDL-37061_m24_invalidlang' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-11 14:44:21 +13:00
Andrew Davis 29a7d7a1c1 MDL-36321 core_message: made the course participants list correctly show if course participants are contacts or not 2012-12-11 08:55:16 +08:00
Sam Hemelryk eda1d3f37a Merge branch 'w49_MDL-29442_m24_entityutf8' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-11 10:22:06 +13:00
Damyon Wiese 6466396f38 MDL-36263 Assignment: Do not count submissions of unenrolled users 2012-12-11 10:12:26 +13:00
Damyon Wiese 5b2313c26c MDL-36908 Assignment: Additional fixes for preventing empty submissions 2012-12-11 10:12:23 +13:00
Charles Fulton 473eadfe10 MDL-37020 auth_shibboleth: check if target variable is actually set 2012-12-11 09:48:41 +13:00
Sam Hemelryk 52d4168038 Merge branch 'MDL-36601-master' of git://git.luns.net.uk/moodle into MOODLE_24_STABLE 2012-12-11 09:42:29 +13:00
Sam Hemelryk c6bd16545e Merge branch 'MDL-36805-master' of git://git.luns.net.uk/moodle into MOODLE_24_STABLE 2012-12-11 09:16:43 +13:00
Adrian Greeve 517a2dbe84 MDL-37011 - themes: Fixed the alignment of the edit and help icon on the participants page. 2012-12-11 08:43:19 +13:00
Iñaki Arenaza 88d48cd51f MDL-37088 auth_ldap: bad operator in ldap sync_user() method 2012-12-10 16:51:49 +01:00
Dan Poltawski a5ff28cc9f MDL-36755 course_overview block: fix for fix.
I will stop commiting now.
2012-12-10 19:44:26 +08:00
Dan Poltawski 1b2cf98bb0 MDL-36755 course_overview block: fix idiot version
I will shoot the programmer responsible for this mess.
2012-12-10 19:42:29 +08:00
Dan Poltawski 86e28894f4 Merge branch 'w49_MDL-36737_m24_glossstrict' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-10 19:37:31 +08:00
Dan Poltawski c125bb553d Merge branch 'MDL-36755_master' of git://github.com/markn86/moodle into MOODLE_24_STABLE
Conflicts:
	blocks/course_overview/version.php
2012-12-10 19:33:21 +08:00
Dan Poltawski 4ac455d9a4 MDL-36167 fix trailing whitespace 2012-12-10 17:36:31 +08:00
Damyon Wiese 3b7a18f2e5 MDL-36167: Assignment quickgrading fix when there is no grade (ensure feedback still saves)
This patch modifies the previous on by Luke Tucker so that the lastmodified hidden field
is always added to the quickgrading form even if there is no grade for the assignment. This
ensures that the lastmodified checks still work (to prevent teachers overwriting each
others feedback) and feedback is saved when there is no grade.
2012-12-10 17:36:31 +08:00
Luke Tucker a13a1707bc MDL-36167: Update all users in assignment quickgrade form to ensure feedback is saved 2012-12-10 17:36:30 +08:00
Tim Hunt 6812769f8f MDL-36732 Cloze qtype: review marks should not depend on feedback.
The various review options should be independent.
2012-12-10 15:18:14 +08:00
Rossiani Wijaya 2f860b4ded MDL-36549 Lesson module: fixed strict standards errors 2012-12-10 14:18:55 +08:00
Kirill Astashov d84c21dfcc MDL-36856: Fix method name misspelled in two places in mod_assign 2012-12-10 14:04:37 +08:00
Damyon Wiese 0e3c1231da MDL-36835 Assignment: Do not show javascript warning when toggling quickgrading 2012-12-10 14:02:14 +08:00
Dan Poltawski 71e8ee1c33 Merge branch 'MDL-36538_webdav_memory_24' of git://github.com/davosmith/moodle into MOODLE_24_STABLE 2012-12-10 13:13:03 +08:00
Dan Poltawski 8938f0848e Merge branch 'w49_MDL-35456_m24_paypal' of git://github.com/skodak/moodle into MOODLE_24_STABLE 2012-12-10 12:03:23 +08:00
Tim Hunt 0e73e16460 MDL-35404 question export: make it work with slasharguments off.
Thanks to Brian King for working out the problem and how to fix it. I am
just committing his patch.
2012-12-10 11:37:17 +08:00
Dan Poltawski 9321379b10 Merge branch 'wip-MDL-36939-m24' of git://github.com/samhemelryk/moodle into MOODLE_24_STABLE 2012-12-10 11:08:51 +08:00
Jerome Mouneyrac c91c7fcded MDL-30961 get_course_contents: returned activity name should not be check against PARAM_TEXT, it could be anything 2012-12-10 15:00:00 +13:00
Andrew Davis 0663096dc6 MDL-36680 core_grade: fixed grade_report::blank_hidden_total() and added unit tests 2012-12-10 09:56:45 +08:00
Michael Aherne 7a9e253405 MDL-36946 theme Use server default theme before standard 2012-12-10 14:43:56 +13:00
Sam Hemelryk 5e6b64571c Merge branch 'MDL-34592_M24' of git://github.com/lazydaisy/moodle into MOODLE_24_STABLE 2012-12-10 14:28:33 +13:00
Sam Hemelryk c446a0fca2 Merge branch 'MDL-36608_M24' of git://github.com/lazydaisy/moodle into MOODLE_24_STABLE 2012-12-10 14:24:18 +13:00
Sam Hemelryk 07f89a017c Merge branch 'MDL-36978_M24' of git://github.com/lazydaisy/moodle into MOODLE_24_STABLE 2012-12-10 14:21:25 +13:00
Sam Hemelryk b8b1926e2f Merge branch 'MDL-36579_modLtiBackupFields' of git://github.com/moodlerooms/moodle into MOODLE_24_STABLE 2012-12-10 14:15:54 +13:00
Mark Nielsen 4d5970ea63 MDL-36607: Improve block drag and drop
* Adding support for subpage
* Adding support for regions that do not start with "side-"
2012-12-10 14:12:50 +13:00
Mark Nelson 656cea20a6 MDL-35954 javascript: prevent JS from being triggered on select box by clicking on already selected option 2012-12-10 14:08:52 +13:00
Mary Evans e9f8261131 MDL-34592 theme_magazine: Fixes the report grader fixed column misalignment in magazine/style/core.css theme, plus fixes all CORE themes with minor adjustment to grade/report/grader/style.css 2012-12-09 23:32:04 +00:00
Itamar Tzadok d87a55fc2b MDL-36433 Forms lib - Added dash escaping to validation script getter. 2012-12-10 12:13:54 +13:00
Dan Poltawski b0c87306a6 MDL-36764 ddl/oracle: fix misleading comment 2012-12-10 11:54:28 +13:00
Dan Poltawski 38ab68e6ab MDL-36778 course - prevent undefined index warnings
When logged in as a guest the mform didn't set userid.
2012-12-10 11:51:57 +13:00
Dan Poltawski 0e7cadca03 MDL-36887 quiz: reorder upgrade.txt's 2012-12-10 11:49:03 +13:00
Andrew Robert Nicols efd08cdc2b MDL-36640 Logging: Correct testing of log->info.
log->info sometimes contains additional information which can be looked up
from other tables. This should only be attempted if the field is numeric,
but the CSV, XLS, and ODS outputs were not making this check.

There is an additional case for the print_mnet_log function which has not
been covered - this is because the mnet logging is currently broken beyond
the scope of this bug rendering this section untestable. These issues are
raised in MDL-36642.
2012-12-10 11:43:35 +13:00
Andrew Robert Nicols 7e61737f3d MDL-36918 Decode HTML entities on ajax update title 2012-12-10 11:15:55 +13:00
Andrew Davis 138025470f MDL-36162 core_message: string clean up 2012-12-10 11:04:18 +13:00
Andrew Davis 8b72167d0e MDL-36162 core_message: removed the unnecessary and confusing course URL parameter as well as fixing the broken breadcrumb 2012-12-10 11:04:13 +13:00
Andrew Davis f92305bfa9 MDL-36761 core_grade:shifted a call to count() out of a loop 2012-12-10 10:54:43 +13:00
Sam Hemelryk 0b4767ca50 Merge branch 'MDL-34591_24' of git://github.com/grabs/moodle into MOODLE_24_STABLE 2012-12-10 10:48:59 +13:00
Kevin Wiliarty 1c50e53a05 MDL-35221 mod_feedback: replace checkbox with advcheckbox for all requirable feedback question types 2012-12-10 10:41:48 +13:00
Adrian Greeve a3301036d6 MDL-36906 - mod_data: Latitude and Logitude error fix.
Thanks to Marcus Boon for providing a patch for this issue.

mod/data/field/latlong/kml.php was missing a context variable.
This was causing an error when trying to download a kml file for
google earth. This variable has now been included.
2012-12-10 10:34:29 +13:00
Adrian Greeve c7a34ab704 MDL-36915 - mod/data: A database with no entries no longer displays the export to portfolio button. 2012-12-10 10:27:42 +13:00
Sam Hemelryk 1b696de61b Merge branch 'wip-MDL-37026-MOODLE_24_STABLE' of git://github.com/abgreeve/moodle into MOODLE_24_STABLE 2012-12-10 10:23:44 +13:00
Adam Olley f4d4c73899 MDL-33125: core_backup: Prevent import/activity duplication from duplicating manual grade items 2012-12-10 10:20:03 +13:00
Petr Škoda da0cf7f883 MDL-36447 skip file preview test if GD not available 2012-12-09 19:22:36 +01:00
Andreas Grabs 7c3f70812e MDL-34591 - paypal does not allow unenrol 2012-12-09 19:10:26 +01:00
Mary Evans f5eabd12db MDL-36490 theme_standard: reduces the 15px radius down to 3px in style/css3.css for .generalbox objects 2012-12-09 18:05:03 +00:00
Mary Evans db1dd3e550 MDL-36608 theme_sky_high: Fixes missing background in sdmin pages by removing incorrect CSS in style/admin.css 2012-12-09 17:44:37 +00:00
Petr Škoda f48902e139 MDL-29442 add missing utf-8 to entity html encoding and decoding 2012-12-09 18:22:16 +01:00
Petr Škoda 7b03292e24 MDL-37061 always validate lang when setting session user
This should resolve problems with TinyMCE langs and some unknown MUCH caching issue.
2012-12-09 11:30:05 +01:00
Mary Evans 2a6e3435d0 MDL-36978 theme_standardold: fixes misplaced block region check in layout/frontpage.php which, with hindsight should have been fixed in MDL-23226. 2012-12-08 22:50:33 +00:00
Petr Škoda 0411eed2cb MDL-36737 fix random glossary E_STRICT issue 2012-12-08 14:44:49 +01:00
Petr Škoda 365ef195b5 MDL-31424 compare PayPal emails case-insensitively
Credit goes to Chris Follin, thanks!
2012-12-08 13:17:10 +01:00
Petr Škoda 8c3547554b MDL-37060 prevent notice in session_get_instance() 2012-12-08 12:31:40 +01:00
Petr Škoda 324efa55e3 MDL-35456 use HTTP 1.1 for PayPal IPN 2012-12-08 11:58:43 +01:00
Eloy Lafuente (stronk7) 0b7c52dd4c weekly release 2.4+ 2012-12-08 02:56:23 +01:00
Petr Škoda cf31390c6f MDL-36936 require phpunit as composer --dev only 2012-12-07 18:20:42 +01:00
Petr Škoda 5af62aa90a MDL-36892 delete outdated enrol info 2012-12-07 17:16:28 +01:00
Davo Smith cf839b4396 MDL-36538 repository_webdav - save files directly to local filesystem, rather than buffering in memory 2012-12-07 09:19:21 +00:00
Jason Fowler 257a5d1299 MDL-35884 - Course - Remove text from ALT attribute for activity chooser 2012-12-07 13:52:32 +08:00
Rajesh Taneja e6d4708fcf MDL-37017 My Moodle: Course name should be fullname of course 2012-12-07 11:58:07 +08:00
Sam Hemelryk f9870842bd MDL-36939 cache: instance form validation now handles errors properly 2012-12-07 08:37:03 +13:00
Sam Hemelryk 2d7173d0c7 MDL-36938 cache: test performance script checks requirements now 2012-12-07 08:36:56 +13:00
Petr Škoda 4682fc7c38 MDL-36983 fix incorrect test method name
Credit goes to David Scotson, thanks.
2012-12-06 15:32:46 +01:00
Petr Škoda 15a77653e4 MDL-36731 fix E_STRICt issue when creating new groups in user upload 2012-12-06 13:15:41 +01:00
Dan Poltawski 9b1f784178 Merge branch 'wip-MDL-36960-m24' of git://github.com/amygroshek/moodle into MOODLE_24_STABLE 2012-12-06 12:04:08 +08:00
Adrian Greeve 44bfbe1e15 MDL-37026 - lib: The function user_can_assign() returns true for admins. 2012-12-06 11:04:34 +08:00
Dan Poltawski 0c767bf6cc Merge branch 'MDL-36963-deployment-backup_24' of git://github.com/mudrd8mz/moodle into MOODLE_24_STABLE 2012-12-06 10:57:13 +08:00
David Mudrák 81c89dd705 MDL-36963 Do not attempt to remove the root folder of a plugin during the update deployment
There is no need to move the root folder of a plugin during the update
deployment. We just need to operate with its contents. So the web server
process can have the write access for the plugin folder only.
2012-12-06 02:45:16 +01:00
David Mudrák b46ee168ef MDL-36963 Add unit tests for directory operations in mdeploy.php 2012-12-06 02:45:16 +01:00
David Mudrák e399d32694 MDL-36963 Improve mdeploy worker::remove_directory() method
The additional parameter allows to use this method without actual
removing the root of the path. That is, it is now possible to remove
the content of a folder only.
2012-12-06 02:35:22 +01:00
David Mudrák 606e2c8ebe MDL-36963 Improve mdeploy worker::move_directory() method
The additional parameter allows to use this method without actual
removing the root of the source location. That is, it is now possible to
move the content of a folder only.

Also, a small refactoring happened here as we will need a variant of
this method that does not throw exception if the target already exists.
2012-12-06 02:31:36 +01:00
Sam Hemelryk c6e0d385c3 MDL-36341 calendar: fixed JS bug with popup node setter 2012-12-06 02:25:14 +01:00
David Mudrák 31a3bcc933 MDL-37003 Fix repeated line in update notification email
There was a problem experienced after 2.4.0 release because the version
of the 2.4.0 release was the same as 2.5dev release. So the version
value matched twice in the loop and the line was repeated in the email.
2012-12-06 01:50:32 +01:00
David Mudrák acade5443f MDL-36943 Do not notify about already installed updates
Before this patch, the available_update_checker::cron_notifications()
method accessed the availableupdates property. But for plugins, that property
basically contains the most recent version available. So we were missing
the check against the actual version installed.

The fix was simple - obtain available updates via the available_updates()
method that performs the check.
2012-12-06 01:50:21 +01:00
Marina Glancy 113105bf9c MDL-36840 Set course.format to 'site' for site-course 2012-12-05 10:28:12 +08:00
Jason Fowler dd9f2b1cca MDL-35979 - Commenting - Adding an empty alt attribute to the javascript generated delete icon for comments 2012-12-05 10:02:31 +08:00
Amy Groshek 90d740364b MDL-36960 - fix broken horizontal positioning of titles for docked blocks 2012-12-04 18:07:25 -06:00
Jason Fowler 89bc7e7b6e MDL-36110 - Blocks - Community finder icon alt attribute is now empty 2012-12-04 15:17:07 +08:00
Jerome Mouneyrac 5c58a540ea MDL-29805 add REQUIRE_CORRECT_ACCESS define + return error code when AJAX_SCRIPT fails 2012-12-04 13:44:48 +08:00
Eloy Lafuente (stronk7) 325e266e95 NOBUG: Bump backup version for 2.4 2012-12-03 21:46:18 +01:00
27626 changed files with 1219346 additions and 3659010 deletions
-312
View File
@@ -1,312 +0,0 @@
{
'plugins': [
'babel',
'promise',
'jsdoc',
],
'env': {
'browser': true,
// Enable ES6+ features by default.
// See http://eslint.org/docs/user-guide/configuring#specifying-environments
// Note: The YUI override must exactly match this when disabling the ES6+ version because those features are not supported by Shifter.
'es2020': true,
'amd': true
},
'globals': {
'M': true,
'Y': true
},
'rules': {
// See http://eslint.org/docs/rules/ for all rules and explanations of all
// rules.
// === Possible Errors ===
'comma-dangle': 'off',
'no-compare-neg-zero': 'error',
'no-cond-assign': 'error',
'no-console': 'error',
'no-constant-condition': 'error',
'no-control-regex': 'error',
'no-debugger': 'error',
'no-dupe-args': 'error',
'no-dupe-keys': 'error',
'no-duplicate-case': 'error',
'no-empty': 'warn',
'no-empty-character-class': 'error',
'no-ex-assign': 'error',
'no-extra-boolean-cast': 'error',
'no-extra-parens': 'off',
'no-extra-semi': 'error',
'no-func-assign': 'error',
'no-inner-declarations': 'error',
'no-invalid-regexp': 'error',
'no-irregular-whitespace': 'error',
'no-obj-calls': 'error',
'no-prototype-builtins': 'off',
'no-regex-spaces': 'error',
'no-sparse-arrays': 'error',
'no-unexpected-multiline': 'error',
'no-unreachable': 'warn',
'no-unsafe-finally': 'error',
'no-unsafe-negation': 'error',
'use-isnan': 'error',
'valid-jsdoc': ['warn', { 'requireReturn': false, 'requireParamDescription': false, 'requireReturnDescription': false }],
'valid-typeof': 'error',
// === Best Practices ===
// (these mostly match our jshint config)
'array-callback-return': 'warn',
'block-scoped-var': 'warn',
'complexity': 'warn',
'consistent-return': 'warn',
'curly': 'error',
'dot-notation': 'warn',
'no-alert': 'warn',
'no-caller': 'error',
'no-case-declarations': 'error',
'no-div-regex': 'error',
'no-empty-pattern': 'error',
'no-empty-function': 'warn',
'no-eq-null': 'error',
'no-eval': 'error',
'no-extend-native': 'error',
'no-extra-bind': 'warn',
'no-fallthrough': 'error',
'no-floating-decimal': 'warn',
'no-global-assign': 'warn',
'no-implied-eval': 'error',
'no-invalid-this': 'error',
'no-iterator': 'error',
'no-labels': 'error',
'no-loop-func': 'error',
'no-multi-spaces': 'warn',
'no-multi-str': 'error',
'no-new-func': 'error',
'no-new-wrappers': 'error',
'no-octal': 'error',
'no-octal-escape': 'error',
'no-proto': 'error',
'no-redeclare': 'warn',
'no-restricted-globals': ['error', { 'name': 'Notification' }],
'no-return-assign': 'error',
'no-script-url': 'error',
'no-self-assign': 'error',
'no-self-compare': 'error',
'no-sequences': 'warn',
'no-throw-literal': 'warn',
'no-unmodified-loop-condition': 'error',
'no-unused-expressions': 'error',
'no-unused-labels': 'error',
'no-useless-call': 'warn',
'no-useless-escape': 'warn',
'no-with': 'error',
'wrap-iife': ['error', 'any'],
// === Variables ===
'no-delete-var': 'error',
'no-undef': 'error',
'no-undef-init': 'error',
'no-unused-vars': ['error', { 'caughtErrors': 'none' }],
// === Stylistic Issues ===
'array-bracket-spacing': 'warn',
'block-spacing': 'warn',
'brace-style': ['warn', '1tbs'],
'camelcase': 'warn',
'capitalized-comments': ['warn', 'always', { 'ignoreConsecutiveComments': true }],
'comma-spacing': ['warn', { 'before': false, 'after': true }],
'comma-style': ['warn', 'last'],
'computed-property-spacing': 'error',
'consistent-this': 'off',
'eol-last': 'off',
'func-call-spacing': ['warn', 'never'],
'func-names': 'off',
'func-style': 'off',
// indent currently not doing well with our wrapping style, so disabled.
'indent': ['off', 4, { 'SwitchCase': 1 }],
'key-spacing': ['warn', { 'beforeColon': false, 'afterColon': true, 'mode': minimum }],
'keyword-spacing': 'warn',
'linebreak-style': ['error', 'unix'],
'lines-around-comment': 'off',
'max-len': ['error', 132],
'max-lines': 'off',
'max-depth': 'warn',
'max-nested-callbacks': ['warn', 5],
'max-params': 'off',
'max-statements': 'off',
'max-statements-per-line': ['warn', { max: 2 }],
'new-cap': ['warn', { 'properties': false }],
'new-parens': 'warn',
'newline-after-var': 'off',
'newline-before-return': 'off',
'newline-per-chained-call': 'off',
'no-array-constructor': 'off',
'no-bitwise': 'error',
'no-continue': 'off',
'no-inline-comments': 'off',
'no-lonely-if': 'off',
'no-mixed-operators': 'off',
'no-mixed-spaces-and-tabs': 'error',
'no-multiple-empty-lines': 'warn',
'no-negated-condition': 'off',
'no-nested-ternary': 'warn',
'no-new-object': 'off',
'no-plusplus': 'off',
'no-tabs': 'error',
'no-ternary': 'off',
'no-trailing-spaces': 'error',
'no-underscore-dangle': 'off',
'no-unneeded-ternary': 'off',
'no-whitespace-before-property': 'warn',
'object-curly-newline': 'off',
'object-curly-spacing': 'warn',
'object-property-newline': 'off',
'one-var': 'off',
'one-var-declaration-per-line': ['warn', 'initializations'],
'operator-assignment': 'off',
'operator-linebreak': 'off',
'padded-blocks': 'off',
'quote-props': ['warn', 'as-needed', {'unnecessary': false, 'keywords': true, 'numbers': true}],
'quotes': 'off',
'require-jsdoc': 'warn',
'semi': 'error',
'semi-spacing': ['warn', {'before': false, 'after': true}],
'sort-vars': 'off',
'space-before-blocks': 'warn',
'space-before-function-paren': ['warn', 'never'],
'space-in-parens': 'warn',
'space-infix-ops': 'warn',
'space-unary-ops': 'warn',
'spaced-comment': 'warn',
'unicode-bom': 'error',
'wrap-regex': 'off',
// === Promises ===
'promise/always-return': 'warn',
'promise/no-return-wrap': 'warn',
'promise/param-names': 'warn',
'promise/catch-or-return': ['warn', {terminationMethod: ['catch', 'fail']}],
'promise/no-native': 'warn',
'promise/no-promise-in-callback': 'warn',
'promise/no-callback-in-promise': 'warn',
'promise/avoid-new': 'warn',
// === Deprecations ===
"no-restricted-properties": ['warn', {
'object': 'M',
'property': 'str',
'message': 'Use AMD module "core/str" or M.util.get_string()'
}],
},
overrides: [
{
files: ["**/yui/src/**/*.js"],
'env': {
// Disable ES6+ for YUI files.
'es2020': false,
},
// Disable some rules which we can't safely define for YUI rollups.
rules: {
'no-undef': 'off',
'no-unused-vars': 'off',
'no-unused-expressions': 'off',
// === JSDocs ===
"jsdoc/check-access": 'off',
"jsdoc/check-alignment": 'off',
"jsdoc/check-param-names": 'off',
"jsdoc/check-property-names": 'off',
"jsdoc/empty-tags": 'off',
"jsdoc/implements-on-classes": 'off',
"jsdoc/multiline-blocks": 'off',
"jsdoc/require-jsdoc": 'off',
"jsdoc/require-param": 'off',
"jsdoc/require-param-name": 'off',
"jsdoc/require-param-type": 'off',
"jsdoc/require-property": 'off',
"jsdoc/require-property-name": 'off',
"jsdoc/require-property-type": 'off',
}
},
{
files: ["**/amd/src/*.js", "**/amd/src/**/*.js", "Gruntfile.js", ".grunt/*.js", ".grunt/tasks/*.js", "jsdoc.conf.js"],
// We're using babel transpiling so use their parser
// for linting.
parser: '@babel/eslint-parser',
// Check AMD with some slightly stricter rules.
rules: {
'no-unused-vars': 'error',
'no-implicit-globals': 'error',
// Disable all of the rules that have babel versions.
'new-cap': 'off',
// Not using this rule for the time being because it isn't
// compatible with jQuery and ES6.
'no-invalid-this': 'off',
'object-curly-spacing': 'off',
'quotes': 'off',
'semi': 'off',
'no-unused-expressions': 'off',
// Enable all of the babel version of these rules.
'babel/new-cap': ['warn', { 'properties': false }],
// Not using this rule for the time being because it isn't
// compatible with jQuery and ES6.
'babel/no-invalid-this': 'off',
'babel/object-curly-spacing': 'warn',
// This is off in the original style int.
'babel/quotes': 'off',
'babel/semi': 'error',
'babel/no-unused-expressions': 'error',
// === Promises ===
// We have Promise now that we're using ES6.
'promise/no-native': 'off',
'promise/avoid-new': 'off',
// === JSDocs ===
"jsdoc/check-access": [
'error',
],
"jsdoc/check-alignment": 1, // Recommended.
"jsdoc/check-param-names": [
'error',
],
"jsdoc/check-property-names": [
'error',
],
"jsdoc/empty-tags": [
'error',
],
"jsdoc/implements-on-classes": [
'error',
],
"jsdoc/multiline-blocks": [
'error',
],
"jsdoc/require-jsdoc": [
'error',
],
"jsdoc/require-param": [
'error',
],
"jsdoc/require-param-name": [
'error',
],
"jsdoc/require-param-type": [
'error',
],
"jsdoc/require-property": [
'error',
],
"jsdoc/require-property-name": [
'error',
],
"jsdoc/require-property-type": [
'error',
],
},
parserOptions: {
'sourceType': 'module',
'requireConfigFile': false,
}
}
]
}
-24
View File
@@ -1,24 +0,0 @@
{
"indentation": ["on",{
"Feature": 0,
"Background": 2,
"Scenario": 2,
"Examples": 4,
"example": 6,
"Step": 4,
"given": 4,
"and": 4
}],
"no-dupe-feature-names": "on",
"no-dupe-scenario-names": "off",
"no-empty-file": "on",
"no-files-without-scenarios": "on",
"no-multiple-empty-lines": "on",
"no-partially-commented-tag-lines": "on",
"no-trailing-spaces": "on",
"no-unnamed-features": "on",
"no-unnamed-scenarios": "on",
"no-scenario-outlines-without-examples": "on",
"no-examples-in-scenarios": "on",
"new-line-at-eof": ["on", "yes"]
}
-3
View File
@@ -1,3 +0,0 @@
**/yui/build/** -diff
**/amd/build/** -diff
lib/dml/oci_native_moodle_package.sql text eol=lf
-2
View File
@@ -1,2 +0,0 @@
# Primary donations pages.
custom: ["https://moodle.com/donations/", moodle.org]
-71
View File
@@ -1,71 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Template configuraton file for github actions CI/CD.
*
* @package core
* @copyright 2020 onwards Eloy Lafuente (stronk7) {@link https://stronk7.com}
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// This cannot be used out from a github actions workflow, so just exit.
getenv('GITHUB_WORKFLOW') || die; // phpcs:ignore moodle.Files.MoodleInternal.MoodleInternalGlobalState
unset($CFG);
global $CFG;
$CFG = new stdClass();
$CFG->dbtype = getenv('dbtype');
$CFG->dblibrary = 'native';
$CFG->dbhost = '127.0.0.1';
$CFG->dbname = 'test';
$CFG->dbuser = 'test';
$CFG->dbpass = 'test';
$CFG->prefix = 'm_';
$CFG->dboptions = ['dbcollation' => 'utf8mb4_bin'];
$host = 'localhost';
$CFG->wwwroot = "http://{$host}";
$CFG->dataroot = realpath(dirname(__DIR__)) . '/moodledata';
$CFG->admin = 'admin';
$CFG->directorypermissions = 0777;
// Debug options - possible to be controlled by flag in future.
$CFG->debug = (E_ALL | E_STRICT); // DEBUG_DEVELOPER.
$CFG->debugdisplay = 1;
$CFG->debugstringids = 1; // Add strings=1 to url to get string ids.
$CFG->perfdebug = 15;
$CFG->debugpageinfo = 1;
$CFG->allowthemechangeonurl = 1;
$CFG->passwordpolicy = 0;
$CFG->cronclionly = 0;
$CFG->pathtophp = getenv('pathtophp');
$CFG->phpunit_dataroot = realpath(dirname(__DIR__)) . '/phpunitdata';
$CFG->phpunit_prefix = 't_';
define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://localhost:8080');
define('TEST_EXTERNAL_FILES_HTTPS_URL', 'http://localhost:8080');
define('TEST_SESSION_REDIS_HOST', 'localhost');
define('TEST_CACHESTORE_REDIS_TESTSERVERS', 'localhost');
// TODO: add others (solr, mongodb, memcached, ldap...).
// Too much for now: define('PHPUNIT_LONGTEST', true); // Only leaves a few tests out and they are run later by CI.
require_once(__DIR__ . '/lib/setup.php');
-118
View File
@@ -1,118 +0,0 @@
name: Core
on:
push:
branches-ignore:
- master
- MOODLE_[0-9]+_STABLE
tags-ignore:
- v[0-9]+.[0-9]+.[0-9]+*
env:
php: 8.1
jobs:
Grunt:
runs-on: ubuntu-22.04
steps:
- name: Checking out code
uses: actions/checkout@v3
- name: Configuring node & npm
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
- name: Installing node stuff
run: npm install
- name: Running grunt
run: npx grunt
- name: Looking for uncommitted changes
# Add all files to the git index and then run diff --cached to see all changes.
# This ensures that we get the status of all files, including new files.
# We ignore npm-shrinkwrap.json to make the tasks immune to npm changes.
run: |
git add .
git reset -- npm-shrinkwrap.json
git diff --cached --exit-code
PHPUnit:
runs-on: ${{ matrix.os }}
services:
exttests:
image: moodlehq/moodle-exttests
ports:
- 8080:80
redis:
image: redis
ports:
- 6379:6379
strategy:
fail-fast: false
matrix:
include:
# MySQL builds always run with the lowest PHP supported version.
- os: ubuntu-22.04
php: 8.0
extensions:
db: mysqli
# PostgreSQL builds always run with the highest PHP supported version.
- os: ubuntu-22.04
php: 8.1
db: pgsql
steps:
- name: Setting up DB mysql
if: ${{ matrix.db == 'mysqli' }}
uses: moodlehq/mysql-action@v1
with:
collation server: utf8mb4_bin
mysql version: 8.0
mysql database: test
mysql user: test
mysql password: test
use tmpfs: true
tmpfs size: '1024M'
extra conf: --skip-log-bin
- name: Setting up DB pgsql
if: ${{ matrix.db == 'pgsql' }}
uses: m4nu56/postgresql-action@v1
with:
postgresql version: 13
postgresql db: test
postgresql user: test
postgresql password: test
- name: Configuring git vars
uses: rlespinasse/github-slug-action@v4
- name: Setting up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: ${{ matrix.extensions }}
ini-values: max_input_vars=5000
coverage: none
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
uses: actions/checkout@v3
- name: Setting up PHPUnit
env:
dbtype: ${{ matrix.db }}
run: |
echo "pathtophp=$(which php)" >> $GITHUB_ENV # Inject installed pathtophp to env. The template config needs it.
cp .github/workflows/config-template.php config.php
mkdir ../moodledata
sudo locale-gen en_AU.UTF-8
php admin/tool/phpunit/cli/init.php --no-composer-self-update
- name: Running PHPUnit tests
env:
dbtype: ${{ matrix.db }}
phpunit_options: ${{ secrets.phpunit_options }}
run: vendor/bin/phpunit $phpunit_options
-144
View File
@@ -1,144 +0,0 @@
name: Windows Testing
on:
workflow_dispatch
env:
php: 8.1
jobs:
Grunt:
runs-on: windows-latest
steps:
- name: Set git to use LF
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checking out code
uses: actions/checkout@v3
- name: Configuring node & npm
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
- name: Installing node stuff
run: npm ci
- name: Running grunt
run: npx grunt
- name: Looking for uncommitted changes
# Add all files to the git index and then run diff --cached to see all changes.
# This ensures that we get the status of all files, including new files.
# We ignore npm-shrinkwrap.json to make the tasks immune to npm changes.
run: |
git add .
git reset -- npm-shrinkwrap.json
git diff --cached --exit-code
PHPUnit:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
php: 8.1
# Ideally we should use mysql/mariadb, but they are 4x slower without tweaks and configuration
# so let's run only postgres (1.5h vs 6h) only, If some day we want to improve the mysql runs,
# this is the place to enable them.
# db: mysqli
db: pgsql
extensions: exif, fileinfo, gd, intl, pgsql, mysql, redis, soap, sodium
- os: windows-latest
php: 8.0
db: pgsql
extensions: exif, fileinfo, gd, intl, pgsql, mysql, redis, soap, sodium
steps:
- name: Setting up DB mysql
if: ${{ matrix.db == 'mysqli' }}
uses: shogo82148/actions-setup-mysql@v1
with:
mysql-version: 8.0
user: test
password: test
- name: Creating DB mysql
if: ${{ matrix.db == 'mysqli' }}
run: mysql --host 127.0.0.1 -utest -ptest -e 'CREATE DATABASE IF NOT EXISTS test COLLATE = utf8mb4_bin;';
- name: Setting up DB pgsql
if: ${{ matrix.db == 'pgsql' }}
run: |
# TODO: Remove these conf. modifications when php74 or php80 are lowest.
# Change to old md5 auth, because php73 does not support it.
# #password_encryption = scram-sha-256
(Get-Content "$env:PGDATA\postgresql.conf"). `
replace('#password_encryption = scram-sha-256', 'password_encryption = md5') | `
Set-Content "$env:PGDATA\postgresql.conf"
(Get-Content "$env:PGDATA\pg_hba.conf"). `
replace('scram-sha-256', 'md5') | `
Set-Content "$env:PGDATA\pg_hba.conf"
$pgService = Get-Service -Name postgresql*
Set-Service -InputObject $pgService -Status running -StartupType automatic
Start-Process -FilePath "$env:PGBIN\pg_isready" -Wait -PassThru
& $env:PGBIN\psql --command="CREATE USER test PASSWORD 'test'" --command="\du"
- name: Creating DB pgsql
if: ${{ matrix.db == 'pgsql' }}
run: |
& $env:PGBIN\createdb --owner=test test
$env:PGPASSWORD = 'test'
& $env:PGBIN\psql --username=test --host=localhost --list test
- name: Configuring git vars
uses: rlespinasse/github-slug-action@v4
- name: Setting up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: ${{ matrix.extensions }}
ini-values: max_input_vars=5000
coverage: none
- name: Set git to use LF
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
uses: actions/checkout@v3
# Needs to be done after php is available, git configured and Moodle checkout has happened.
- name: Setting up moodle-exttests service
run: |
git clone https://github.com/moodlehq/moodle-exttests.git
nssm install php-built-in C:\tools\php\php.exe -S localhost:8080 -t D:\a\moodle\moodle\moodle-exttests
nssm start php-built-in
- name: Setting up redis service
run: |
choco install redis-64 --version 3.0.503 --no-progress
nssm install redis redis-server
nssm start redis
- name: Setting up PHPUnit
env:
dbtype: ${{ matrix.db }}
shell: bash
run: |
echo "pathtophp=$(which php)" >> $GITHUB_ENV # Inject installed pathtophp to env. The template config needs it.
cp .github/workflows/config-template.php config.php
mkdir ../moodledata
php admin/tool/phpunit/cli/init.php --no-composer-self-update
- name: Running PHPUnit tests
env:
dbtype: ${{ matrix.db }}
phpunit_options: ${{ secrets.phpunit_options }}
run: vendor/bin/phpunit $phpunit_options
+5 -30
View File
@@ -9,23 +9,15 @@
#
# See gitignore(5) man page for more details
#
# Swap files (vim)
[._]*.s[a-v][a-z]
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Temporary files including undo
*~
#
/config.php
/lib/editor/tinymce/extra/tools/temp/
*~
*.swp
/tags
/TAGS
/cscope.*
/.patches/
/.idea/
.phpstorm.*
/nbproject/
CVS
.DS_Store
@@ -33,25 +25,8 @@ CVS
/.project
/.buildpath
/.cache
.phpunit.result.cache
phpunit.xml
# Composer support. Do not ignore composer.json, or composer.lock. These should be shipped by us.
# Composer support - only composer.json is to be in git, the rest is installed in each checkout.
composer.phar
composer.lock
/vendor/
/behat.yml
*/yui/build/*/*-coverage.js
/lib/yuilib/*/build/*/*-coverage.js
# lib/yuilib/version/module/module-coverage.js
/lib/yuilib/*/*/*-coverage.js
atlassian-ide-plugin.xml
/node_modules/
/.vscode/
moodle-plugin-ci.phar
.eslintignore
.stylelintignore
/jsdoc
/admin/tool/componentlibrary/docs
/admin/tool/componentlibrary/hugo/site/data/my-index.json
.hugo_build.lock
phpcs.xml
jsconfig.json
-169
View File
@@ -1,169 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This is a babel plugin to add the Moodle module names to the AMD modules
* as part of the transpiling process.
*
* In addition it will also add a return statement for the default export if the
* module is using default exports. This is a highly specific Moodle thing because
* we're transpiling to AMD and none of the existing Babel 7 plugins work correctly.
*
* This will fix the issue where an ES6 module using "export default Foo" will be
* transpiled into an AMD module that returns {default: Foo}; Instead it will now
* just simply return Foo.
*
* Note: This means all other named exports in that module are ignored and won't be
* exported.
*
* @copyright 2018 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
/* eslint-env node */
module.exports = ({template, types}) => {
const fs = require('fs');
const path = require('path');
const cwd = process.cwd();
const ComponentList = require(path.join(process.cwd(), '.grunt', 'components.js'));
/**
* Search the list of components that match the given file name
* and return the Moodle component for that file, if found.
*
* Throw an exception if no matching component is found.
*
* @throws {Error}
* @param {string} searchFileName The file name to look for.
* @return {string} Moodle component
*/
function getModuleNameFromFileName(searchFileName) {
searchFileName = fs.realpathSync(searchFileName);
const relativeFileName = searchFileName.replace(`${cwd}${path.sep}`, '').replace(/\\/g, '/');
const [componentPath, file] = relativeFileName.split('/amd/src/');
const fileName = file.replace('.js', '');
// Check subsystems first which require an exact match.
const componentName = ComponentList.getComponentFromPath(componentPath);
if (componentName) {
return `${componentName}/${fileName}`;
}
// This matches the previous PHP behaviour that would throw an exception
// if it couldn't parse an AMD file.
throw new Error(`Unable to find module name for ${searchFileName} (${componentPath}::${file}}`);
}
/**
* This is heavily inspired by the babel-plugin-add-module-exports plugin.
* See: https://github.com/59naga/babel-plugin-add-module-exports
*
* This is used when we detect a module using "export default Foo;" to make
* sure the transpiled code just returns Foo directly rather than an object
* with the default property (i.e. {default: Foo}).
*
* Note: This means that we can't support modules that combine named exports
* with a default export.
*
* @param {String} path
* @param {String} exportObjectName
*/
function addModuleExportsDefaults(path, exportObjectName) {
const rootPath = path.findParent(path => {
return path.key === 'body' || !path.parentPath;
});
// HACK: `path.node.body.push` instead of path.pushContainer(due doesn't work in Plugin.post).
// This is hardcoded to work specifically with AMD.
rootPath.node.body.push(template(`return ${exportObjectName}.default`)());
}
return {
pre() {
this.seenDefine = false;
this.addedReturnForDefaultExport = false;
},
visitor: {
// Plugin ordering is only respected if we visit the "Program" node.
// See: https://babeljs.io/docs/en/plugins.html#plugin-preset-ordering
//
// We require this to run after the other AMD module transformation so
// let's visit the "Program" node.
Program: {
exit(path) {
path.traverse({
CallExpression(path) {
// If we find a "define" function call.
if (!this.seenDefine && path.get('callee').isIdentifier({name: 'define'})) {
// We only want to modify the first instance of define that we find.
this.seenDefine = true;
// Get the Moodle component for the file being processed.
var moduleName = getModuleNameFromFileName(this.file.opts.filename);
// The function signature of `define()` is:
// define = function (name, deps, callback) {...}
// Ensure that if the moduel supplied its own name that it is replaced.
if (path.node.arguments.length > 0) {
// Ensure that there is only one name.
if (path.node.arguments[0].type === 'StringLiteral') {
// eslint-disable-next-line
console.log(`Replacing module name '${path.node.arguments[0].extra.rawValue}' with ${moduleName}`);
path.node.arguments.shift();
}
}
// Add the module name as the first argument to the define function.
path.node.arguments.unshift(types.stringLiteral(moduleName));
// Add a space after the define function in the built file so that previous versions
// of Moodle will not try to add the module name to the file when it's being served
// by PHP. This forces the regex in PHP to not match for this file.
path.node.callee.name = 'define ';
}
// Check for any Object.defineProperty('exports', 'default') calls.
if (!this.addedReturnForDefaultExport && path.get('callee').matchesPattern('Object.defineProperty')) {
const [identifier, prop] = path.get('arguments');
const objectName = identifier.get('name').node;
const propertyName = prop.get('value').node;
if ((objectName === 'exports' || objectName === '_exports') && propertyName === 'default') {
addModuleExportsDefaults(path, objectName);
this.addedReturnForDefaultExport = true;
}
}
},
AssignmentExpression(path) {
// Check for an exports.default assignments.
if (
!this.addedReturnForDefaultExport &&
(
path.get('left').matchesPattern('exports.default') ||
path.get('left').matchesPattern('_exports.default')
)
) {
const objectName = path.get('left.object.name').node;
addModuleExportsDefaults(path, objectName);
this.addedReturnForDefaultExport = true;
}
}
}, this);
}
}
}
};
};
-394
View File
@@ -1,394 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Helper functions for working with Moodle component names, directories, and sources.
*
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
/* eslint-env node */
/** @var {Object} A list of subsystems in Moodle */
const componentData = {};
/**
* Load details of all moodle modules.
*
* @returns {object}
*/
const fetchComponentData = () => {
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const gruntFilePath = process.cwd();
if (!Object.entries(componentData).length) {
componentData.subsystems = {};
componentData.pathList = [];
// Fetch the component definiitions from the distributed JSON file.
const components = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/components.json`));
// Build the list of moodle subsystems.
componentData.subsystems.lib = 'core';
componentData.pathList.push(process.cwd() + path.sep + 'lib');
for (const [component, thisPath] of Object.entries(components.subsystems)) {
if (thisPath) {
// Prefix "core_" to the front of the subsystems.
componentData.subsystems[thisPath] = `core_${component}`;
componentData.pathList.push(process.cwd() + path.sep + thisPath);
}
}
// The list of components incldues the list of subsystems.
componentData.components = componentData.subsystems;
// Go through each of the plugintypes.
Object.entries(components.plugintypes).forEach(([pluginType, pluginTypePath]) => {
// We don't allow any code in this place..?
glob.sync(`${pluginTypePath}/*/version.php`).forEach(versionPath => {
const componentPath = fs.realpathSync(path.dirname(versionPath));
const componentName = path.basename(componentPath);
const frankenstyleName = `${pluginType}_${componentName}`;
componentData.components[`${pluginTypePath}/${componentName}`] = frankenstyleName;
componentData.pathList.push(componentPath);
// Look for any subplugins.
const subPluginConfigurationFile = `${componentPath}/db/subplugins.json`;
if (fs.existsSync(subPluginConfigurationFile)) {
const subpluginList = JSON.parse(fs.readFileSync(fs.realpathSync(subPluginConfigurationFile)));
Object.entries(subpluginList.plugintypes).forEach(([subpluginType, subpluginTypePath]) => {
glob.sync(`${subpluginTypePath}/*/version.php`).forEach(versionPath => {
const componentPath = fs.realpathSync(path.dirname(versionPath));
const componentName = path.basename(componentPath);
const frankenstyleName = `${subpluginType}_${componentName}`;
componentData.components[`${subpluginTypePath}/${componentName}`] = frankenstyleName;
componentData.pathList.push(componentPath);
});
});
}
});
});
}
return componentData;
};
/**
* Get the list of component paths.
*
* @param {string} relativeTo
* @returns {array}
*/
const getComponentPaths = (relativeTo = '') => fetchComponentData().pathList.map(componentPath => {
return componentPath.replace(relativeTo, '');
});
/**
* Get the list of paths to build AMD sources.
*
* @returns {Array}
*/
const getAmdSrcGlobList = () => {
const globList = [];
fetchComponentData().pathList.forEach(componentPath => {
globList.push(`${componentPath}/amd/src/*.js`);
globList.push(`${componentPath}/amd/src/**/*.js`);
});
return globList;
};
/**
* Get the list of paths to build YUI sources.
*
* @param {String} relativeTo
* @returns {Array}
*/
const getYuiSrcGlobList = relativeTo => {
const globList = [];
fetchComponentData().pathList.forEach(componentPath => {
const relativeComponentPath = componentPath.replace(relativeTo, '');
globList.push(`${relativeComponentPath}/yui/src/**/*.js`);
});
return globList;
};
/**
* Get the list of paths to thirdpartylibs.xml.
*
* @param {String} relativeTo
* @returns {Array}
*/
const getThirdPartyLibsList = relativeTo => {
const fs = require('fs');
const path = require('path');
return fetchComponentData().pathList
.map(componentPath => path.relative(relativeTo, componentPath) + '/thirdpartylibs.xml')
.map(componentPath => componentPath.replace(/\\/g, '/'))
.filter(path => fs.existsSync(path))
.sort();
};
/**
* Get the list of thirdparty library paths.
*
* @returns {array}
*/
const getThirdPartyPaths = () => {
const DOMParser = require('@xmldom/xmldom').DOMParser;
const fs = require('fs');
const path = require('path');
const xpath = require('xpath');
const thirdpartyfiles = getThirdPartyLibsList(fs.realpathSync('./'));
const libs = ['node_modules/', 'vendor/'];
const addLibToList = lib => {
if (!lib.match('\\*') && fs.statSync(lib).isDirectory()) {
// Ensure trailing slash on dirs.
lib = lib.replace(/\/?$/, '/');
}
// Look for duplicate paths before adding to array.
if (libs.indexOf(lib) === -1) {
libs.push(lib);
}
};
thirdpartyfiles.forEach(function(file) {
const dirname = path.dirname(file);
const xmlContent = fs.readFileSync(file, 'utf8');
const doc = new DOMParser().parseFromString(xmlContent);
const nodes = xpath.select("/libraries/library/location/text()", doc);
nodes.forEach(function(node) {
let lib = path.posix.join(dirname, node.toString());
addLibToList(lib);
});
});
return libs;
};
/**
* Find the name of the component matching the specified path.
*
* @param {String} path
* @returns {String|null} Name of matching component.
*/
const getComponentFromPath = path => {
const componentList = fetchComponentData().components;
if (componentList.hasOwnProperty(path)) {
return componentList[path];
}
return null;
};
/**
* Check whether the supplied path, relative to the Gruntfile.js, is in a known component.
*
* @param {String} checkPath The path to check. This can be with either Windows, or Linux directory separators.
* @returns {String|null}
*/
const getOwningComponentDirectory = checkPath => {
const path = require('path');
// Fetch all components into a reverse sorted array.
// This ensures that components which are within the directory of another component match first.
const pathList = Object.keys(fetchComponentData().components).sort().reverse();
for (const componentPath of pathList) {
// If the componentPath is the directory being checked, it will be empty.
// If the componentPath is a parent of the directory being checked, the relative directory will not start with ..
if (!path.relative(componentPath, checkPath).startsWith('..')) {
return componentPath;
}
}
return null;
};
/**
* Get the latest tag in a remote GitHub repository.
*
* @param {string} url The remote repository.
* @returns {Array}
*/
const getRepositoryTags = async(url) => {
const gtr = require('git-tags-remote');
try {
const tags = await gtr.get(url);
if (tags !== undefined) {
return tags;
}
} catch (error) {
return [];
}
return [];
};
/**
* Get the list of thirdparty libraries that could be upgraded.
*
* @returns {Array}
*/
const getThirdPartyLibsUpgradable = async() => {
const libraries = getThirdPartyLibsData().filter((library) => !!library.repository);
const upgradableLibraries = [];
const versionCompare = (a, b) => {
if (a === b) {
return 0;
}
const aParts = a.split('.');
const bParts = b.split('.');
for (let i = 0; i < Math.min(aParts.length, bParts.length); i++) {
const aPart = parseInt(aParts[i], 10);
const bPart = parseInt(bParts[i], 10);
if (aPart > bPart) {
// 1.1.0 > 1.0.9
return 1;
} else if (aPart < bPart) {
// 1.0.9 < 1.1.0
return -1;
} else {
// Same version.
continue;
}
}
if (aParts.length > bParts.length) {
// 1.0.1 > 1.0
return 1;
}
// 1.0 < 1.0.1
return -1;
};
for (let library of libraries) {
upgradableLibraries.push(
getRepositoryTags(library.repository).then((tagMap) => {
library.version = library.version.replace(/^v/, '');
const currentVersion = library.version.replace(/moodle-/, '');
const currentMajorVersion = library.version.split('.')[0];
const tags = [...tagMap]
.map((tagData) => tagData[0])
.filter((tag) => !tag.match(/(alpha|beta|rc)/))
.map((tag) => tag.replace(/^v/, ''))
.sort((a, b) => versionCompare(b, a));
if (!tags.length) {
library.warning = "Unable to find any comparable tags.";
return library;
}
library.latestVersion = tags[0];
tags.some((tag) => {
if (!tag) {
return false;
}
// See if the version part matches.
const majorVersion = tag.split('.')[0];
if (majorVersion === currentMajorVersion) {
library.latestSameMajorVersion = tag;
return true;
}
return false;
});
if (versionCompare(currentVersion, library.latestVersion) > 0) {
// Moodle somehow has a newer version than the latest version.
library.warning = `Newer version found: ${currentVersion} > ${library.latestVersion} for ${library.name}`;
return library;
}
if (library.version !== library.latestVersion) {
// Delete version and add it again at the end of the array. That way, current and new will stay closer.
delete library.version;
library.version = currentVersion;
return library;
}
return null;
})
);
}
return (await Promise.all(upgradableLibraries)).filter((library) => !!library);
};
/**
* Get the list of thirdparty libraries.
*
* @returns {Array}
*/
const getThirdPartyLibsData = () => {
const DOMParser = require('@xmldom/xmldom').DOMParser;
const fs = require('fs');
const xpath = require('xpath');
const path = require('path');
const libraryList = [];
const libraryFields = [
'location',
'name',
'version',
'repository',
];
const thirdpartyfiles = getThirdPartyLibsList(fs.realpathSync('./'));
thirdpartyfiles.forEach(function(libraryPath) {
const xmlContent = fs.readFileSync(libraryPath, 'utf8');
const doc = new DOMParser().parseFromString(xmlContent);
const libraries = xpath.select("/libraries/library", doc);
for (const library of libraries) {
const libraryData = [];
for (const field of libraryFields) {
libraryData[field] = xpath.select(`${field}/text()`, library)?.toString();
}
libraryData.location = path.join(path.dirname(libraryPath), libraryData.location);
libraryList.push(libraryData);
}
});
return libraryList.sort((a, b) => a.location.localeCompare(b.location));
};
module.exports = {
fetchComponentData,
getAmdSrcGlobList,
getComponentFromPath,
getComponentPaths,
getOwningComponentDirectory,
getYuiSrcGlobList,
getThirdPartyLibsList,
getThirdPartyPaths,
getThirdPartyLibsUpgradable,
};
-19
View File
@@ -1,19 +0,0 @@
# Moodle JavaScript Documentation
```
.-..-.
_____ | || |
/____/-.---_ .---. .---. .-.| || | .---.
| | _ _ |/ _ \/ _ \/ _ || |/ __ \
* | | | | | || |_| || |_| || |_| || || |___/
|_| |_| |_|\_____/\_____/\_____||_|\_____)
Moodle - the world's open source learning platform
```
## About
This generated documentation includes API documentation for JavaScript written in the AMD and ES2015 module formats within Moodle.
## Related information
See [https://docs.moodle.org/dev](https://docs.moodle.org/dev) for other related Developer Documentation.
-131
View File
@@ -1,131 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Helper functions for working with Moodle component names, directories, and sources.
*
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
"use strict";
/* eslint-env node */
// Do not include any plugins as stanard.
const plugins = [];
plugins.push('plugins/markdown');
/**
* Get the source configuration.
*
* @return {Object}
*/
const getSource = () => {
const glob = require('glob');
const path = require('path');
const ComponentList = require(path.resolve('.grunt/components.js'));
const thirdPartyPaths = ComponentList.getThirdPartyPaths();
const source = {
include: [],
includePattern: ".+\\.js$",
};
let includeList = [];
ComponentList.getAmdSrcGlobList().forEach(async pattern => {
includeList.push(...glob.sync(pattern));
});
const cwdLength = process.cwd().length + 1;
includeList.forEach(path => {
if (source.include.indexOf(path) !== -1) {
// Ensure no duplicates.
return;
}
const relPath = path.substring(cwdLength);
if (thirdPartyPaths.indexOf(relPath) !== -1) {
return;
}
source.include.push(path);
});
source.include.push('.grunt/jsdoc/README.md');
return source;
};
const tags = {
// Allow the use of unknown tags.
// We have a lot of legacy uses of these.
allowUnknownTags: true,
// We make use of jsdoc and closure dictionaries as standard.
dictionaries: [
'jsdoc',
'closure',
],
};
// Template configuraiton.
const templates = {
cleverLinks: false,
monospaceLinks: false,
};
module.exports = {
opts: {
destination: "./jsdoc/",
template: "node_modules/docdash",
},
plugins,
recurseDepth: 10,
source: getSource(),
sourceType: 'module',
tags,
templates,
docdash: {
collapse: true,
search: true,
sort: true,
sectionOrder: [
"Namespaces",
"Modules",
"Events",
"Classes",
"Externals",
"Mixins",
"Tutorials",
"Interfaces"
],
"menu": {
"Developer Docs": {
href: "https://docs.moodle.org/dev",
target: "_blank",
"class": "menu-item",
id: "devdocs"
},
"MDN Docs": {
href: "https://developer.mozilla.org/en-US/docs/Web/JavaScript",
target: "_blank",
"class": "menu-item",
id: "mdndocs",
},
},
typedefs: true,
},
};
-142
View File
@@ -1,142 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* Component Library build tasks.
*
* @copyright 2021 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = grunt => {
/**
* Get a child path of the component library.
*
* @param {string} path
* @returns {string}
*/
const getCLPath = path => `admin/tool/componentlibrary/${path}`;
/**
* Get a spawn handler.
*
* This is a generic function to write the spawn output, and then to exit if required and mark the async task as
* complete.
*
* @param {Promise} done
* @returns {function}
*/
const getSpawnHandler = done => (error, result, code) => {
grunt.log.write(result);
if (error) {
grunt.log.error(result.stdout);
process.exit(code);
}
done();
};
/**
* Spawn a function against Node with the provided args.
*
* @param {array} args
* @returns {object}
*/
const spawnNodeCall = (args) => grunt.util.spawn({
cmd: 'node',
args,
}, getSpawnHandler(grunt.task.current.async()));
/**
* Build the docs using Hugo.
*
* @returns {Object} Reference to the spawned task
*/
const docsBuild = () => spawnNodeCall([
'node_modules/hugo-bin/cli.js',
'--config', getCLPath('config.yml'),
'--cleanDestinationDir',
]);
/**
* Build the docs index using the hugo-lunr-indexer.
*
* @returns {Object} Reference to the spawned task
*/
const indexBuild = () => spawnNodeCall([
'node_modules/hugo-lunr-indexer/bin/hli.js',
'-i', getCLPath('content/**'),
'-o', getCLPath('hugo/site/data/my-index.json'),
'-l', 'yaml',
'-d', '---',
]);
/**
* Build the hugo CSS.
*
* @returns {Object} Reference to the spawned task
*/
const cssBuild = () => spawnNodeCall([
'node_modules/sass/sass.js',
'--style', 'expanded',
'--source-map',
'--embed-sources',
'--precision', 6,
'--load-path', process.cwd(),
getCLPath('hugo/scss/docs.scss'),
getCLPath('hugo/dist/css/docs.css'),
]);
// Register the various component library tasks.
grunt.registerTask('componentlibrary:docsBuild', 'Build the component library', docsBuild);
grunt.registerTask('componentlibrary:cssBuild', 'Build the component library', cssBuild);
grunt.registerTask('componentlibrary:indexBuild', 'Build the component library', indexBuild);
grunt.registerTask('componentlibrary', 'Build the component library', [
'componentlibrary:docsBuild',
'componentlibrary:cssBuild',
'componentlibrary:indexBuild',
]);
grunt.config.merge({
watch: {
componentLibraryDocs: {
files: [
getCLPath('content/**/*.md'),
getCLPath('hugo'),
],
tasks: ['componentlibrary:docsBuild', 'componentlibrary:indexBuild'],
},
componentLibraryCSS: {
files: [
getCLPath('hugo/scss/**/*.scss'),
'hugo',
],
tasks: ['componentlibrary:cssBuild'],
},
},
});
// Add the 'componentlibrary' task as a startup task.
grunt.moodleEnv.startupTasks.push('componentlibrary');
return {
docsBuild,
cssBuild,
indexBuild,
};
};
-64
View File
@@ -1,64 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2021 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = grunt => {
const files = grunt.moodleEnv.files;
// Project configuration.
grunt.config.merge({
eslint: {
// Even though warnings dont stop the build we don't display warnings by default because
// at this moment we've got too many core warnings.
// To display warnings call: grunt eslint --show-lint-warnings
// To fail on warnings call: grunt eslint --max-lint-warnings=0
// Also --max-lint-warnings=-1 can be used to display warnings but not fail.
options: {
quiet: (!grunt.option('show-lint-warnings')) && (typeof grunt.option('max-lint-warnings') === 'undefined'),
maxWarnings: ((typeof grunt.option('max-lint-warnings') !== 'undefined') ? grunt.option('max-lint-warnings') : -1)
},
// Check AMD src files.
amd: {src: files ? files : grunt.moodleEnv.amdSrc},
// Check YUI module source files.
yui: {src: files ? files : grunt.moodleEnv.yuiSrc},
},
});
grunt.loadNpmTasks('grunt-eslint');
// On watch, we dynamically modify config to build only affected files. This
// method is slightly complicated to deal with multiple changed files at once (copied
// from the grunt-contrib-watch readme).
let changedFiles = Object.create(null);
const onChange = grunt.util._.debounce(function() {
const files = Object.keys(changedFiles);
grunt.config('eslint.amd.src', files);
grunt.config('eslint.yui.src', files);
changedFiles = Object.create(null);
}, 200);
grunt.event.on('watch', (action, filepath) => {
changedFiles[filepath] = action;
onChange();
});
};
-92
View File
@@ -1,92 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2021 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = grunt => {
/**
* Get the list of feature files to pass to the gherkin linter.
*
* @returns {Array}
*/
const getGherkinLintTargets = () => {
if (grunt.moodleEnv.files) {
// Specific files were requested. Only check these.
return grunt.moodleEnv.files;
}
if (grunt.moodleEnv.inComponent) {
return [`${grunt.moodleEnv.runDir}/tests/behat/*.feature`];
}
return ['**/tests/behat/*.feature'];
};
const handler = function() {
const done = this.async();
const options = grunt.config('gherkinlint.options');
// Grab the gherkin-lint linter and required scaffolding.
const linter = require('gherkin-lint/dist/linter.js');
const featureFinder = require('gherkin-lint/dist/feature-finder.js');
const configParser = require('gherkin-lint/dist/config-parser.js');
const formatter = require('gherkin-lint/dist/formatters/stylish.js');
// Run the linter.
return linter.lint(
featureFinder.getFeatureFiles(grunt.file.expand(options.files)),
configParser.getConfiguration(configParser.defaultConfigFileName)
)
.then(results => {
// Print the results out uncondtionally.
formatter.printResults(results);
return results;
})
.then(results => {
// Report on the results.
// The done function takes a bool whereby a falsey statement causes the task to fail.
return results.every(result => result.errors.length === 0);
})
.then(done); // eslint-disable-line promise/no-callback-in-promise
};
grunt.registerTask('gherkinlint', 'Run gherkinlint against the current directory', handler);
grunt.config.set('gherkinlint', {
options: {
files: getGherkinLintTargets(),
}
});
grunt.config.merge({
watch: {
gherkinlint: {
files: [grunt.moodleEnv.inComponent ? 'tests/behat/*.feature' : '**/tests/behat/*.feature'],
tasks: ['gherkinlint'],
},
},
});
// Add the 'gherkinlint' task as a startup task.
grunt.moodleEnv.startupTasks.push('gherkinlint');
return handler;
};
-100
View File
@@ -1,100 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2021 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = grunt => {
/**
* Generate the PHPCS configuration.
*
* @param {Object} thirdPartyPaths
*/
const phpcsIgnore = (thirdPartyPaths) => {
const {toXML} = require('jstoxml');
const config = {
_name: 'ruleset',
_attrs: {
name: "MoodleCore",
},
_content: [
{
rule: {
_attrs: {
ref: './phpcs.xml.dist',
},
},
},
],
};
thirdPartyPaths.forEach(library => {
config._content.push({
'exclude-pattern': library,
});
});
grunt.file.write('phpcs.xml', toXML(config, {
header: true,
indent: ' ',
}) + "\n");
};
/**
* Generate ignore files (utilising thirdpartylibs.xml data)
*/
const handler = function() {
const path = require('path');
const ComponentList = require(path.join(process.cwd(), '.grunt', 'components.js'));
// An array of paths to third party directories.
const thirdPartyPaths = ComponentList.getThirdPartyPaths();
// Generate .eslintignore.
const eslintIgnores = [
'# Generated by "grunt ignorefiles"',
// Do not ignore the .grunt directory.
'!/.grunt',
// Ignore all yui/src meta directories and build directories.
'*/**/yui/src/*/meta/',
'*/**/build/',
].concat(thirdPartyPaths);
grunt.file.write('.eslintignore', eslintIgnores.join('\n') + '\n');
// Generate .stylelintignore.
const stylelintIgnores = [
'# Generated by "grunt ignorefiles"',
'**/yui/build/*',
'theme/boost/style/moodle.css',
'theme/classic/style/moodle.css',
'jsdoc/styles/*.css',
'admin/tool/componentlibrary/hugo/dist/css/docs.css',
].concat(thirdPartyPaths);
grunt.file.write('.stylelintignore', stylelintIgnores.join('\n') + '\n');
phpcsIgnore(thirdPartyPaths);
};
grunt.registerTask('ignorefiles', 'Generate ignore files for linters', handler);
return handler;
};
-227
View File
@@ -1,227 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2021 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Function to generate the destination for the uglify task
* (e.g. build/file.min.js). This function will be passed to
* the rename property of files array when building dynamically:
* http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically
*
* @param {String} destPath the current destination
* @param {String} srcPath the matched src path
* @return {String} The rewritten destination path.
*/
const babelRename = function(destPath, srcPath) {
destPath = srcPath.replace(`amd/src`, `amd/build`);
destPath = destPath.replace(/\.js$/, '.min.js');
return destPath;
};
module.exports = grunt => {
// Load the Ignorefiles tasks.
require('./ignorefiles')(grunt);
// Load the Shifter tasks.
require('./shifter')(grunt);
// Load ESLint.
require('./eslint')(grunt);
// Load jsconfig.
require('./jsconfig')(grunt);
// Load JSDoc.
require('./jsdoc')(grunt);
const path = require('path');
// Register JS tasks.
grunt.registerTask('yui', ['eslint:yui', 'shifter']);
grunt.registerTask('amd', ['ignorefiles', 'eslint:amd', 'rollup']);
grunt.registerTask('js', ['amd', 'yui']);
// Register NPM tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-rollup');
const babelTransform = require('@babel/core').transform;
const babel = (options = {}) => {
return {
name: 'babel',
transform: (code, id) => {
grunt.log.debug(`Transforming ${id}`);
options.filename = id;
const transformed = babelTransform(code, options);
return {
code: transformed.code,
map: transformed.map
};
}
};
};
// Note: We have to use a rate limit plugin here because rollup runs all tasks asynchronously and in parallel.
// When we kick off a full run, if we kick off a rollup of every file this will fork-bomb the machine.
// To work around this we use a concurrent Promise queue based on the number of available processors.
const rateLimit = () => {
const queue = [];
let queueRunner;
const startQueue = () => {
if (queueRunner) {
return;
}
queueRunner = setTimeout(() => {
const limit = Math.max(1, require('os').cpus().length / 2);
grunt.log.debug(`Starting rollup with queue size of ${limit}`);
runQueue(limit);
}, 100);
};
// The queue runner will run the next `size` items in the queue.
const runQueue = (size = 1) => {
queue.splice(0, size).forEach(resolve => {
resolve();
});
};
return {
name: 'ratelimit',
// The options hook is run in parallel.
// We can return an unresolved Promise which is queued for later resolution.
options: async() => {
return new Promise(resolve => {
queue.push(resolve);
startQueue();
});
},
// When an item in the queue completes, start the next item in the queue.
buildEnd: () => {
runQueue();
},
};
};
const terser = require('rollup-plugin-terser').terser;
grunt.config.merge({
rollup: {
options: {
format: 'esm',
dir: 'output',
sourcemap: true,
treeshake: false,
context: 'window',
plugins: [
rateLimit(),
babel({
sourceMaps: true,
comments: false,
compact: false,
plugins: [
'transform-es2015-modules-amd-lazy',
'system-import-transformer',
// This plugin modifies the Babel transpiling for "export default"
// so that if it's used then only the exported value is returned
// by the generated AMD module.
//
// It also adds the Moodle plugin name to the AMD module definition
// so that it can be imported as expected in other modules.
path.resolve('.grunt/babel-plugin-add-module-to-define.js'),
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-syntax-import-meta',
['@babel/plugin-proposal-class-properties', {'loose': false}],
'@babel/plugin-proposal-json-strings'
],
presets: [
['@babel/preset-env', {
targets: {
browsers: [
">0.3%",
"last 2 versions",
"not ie >= 0",
"not op_mini all",
"not Opera > 0",
"not dead"
]
},
modules: false,
useBuiltIns: false
}]
]
}),
terser({
// Do not mangle variables.
// Makes debugging easier.
mangle: false,
}),
],
},
dist: {
files: [{
expand: true,
src: grunt.moodleEnv.files ? grunt.moodleEnv.files : grunt.moodleEnv.amdSrc,
rename: babelRename
}],
},
},
});
grunt.config.merge({
watch: {
amd: {
files: grunt.moodleEnv.inComponent
? ['amd/src/*.js', 'amd/src/**/*.js']
: ['**/amd/src/**/*.js'],
tasks: ['amd']
},
},
});
// Add the 'js' task as a startup task.
grunt.moodleEnv.startupTasks.push('js');
// On watch, we dynamically modify config to build only affected files. This
// method is slightly complicated to deal with multiple changed files at once (copied
// from the grunt-contrib-watch readme).
let changedFiles = Object.create(null);
const onChange = grunt.util._.debounce(function() {
const files = Object.keys(changedFiles);
grunt.config('rollup.dist.files', [{expand: true, src: files, rename: babelRename}]);
changedFiles = Object.create(null);
}, 200);
grunt.event.on('watch', function(action, filepath) {
changedFiles[filepath] = action;
onChange();
});
return {
babelRename,
};
};
-53
View File
@@ -1,53 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2022 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
const configuration = {
compilerOptions: {
baseUrl: ".",
paths: {
},
target: "es2015",
allowSyntheticDefaultImports: false,
},
exclude: [
"node_modules",
],
include: [],
};
module.exports = (grunt) => {
const handler = () => {
const jsconfigData = Object.assign({}, configuration);
const path = require('path');
const {fetchComponentData} = require(path.join(process.cwd(), '.grunt', 'components.js'));
const componentData = fetchComponentData().components;
for (const [thisPath, component] of Object.entries(componentData)) {
jsconfigData.compilerOptions.paths[`${component}/*`] = [`${thisPath}/amd/src/*`];
jsconfigData.include.push(`${thisPath}/amd/src/**/*`);
}
grunt.file.write('jsconfig.json', JSON.stringify(jsconfigData, null, " ") + "\n");
};
grunt.registerTask('jsconfig', 'Generate a jsconfig configuration compatible with the LSP', handler);
};
-36
View File
@@ -1,36 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2021 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = grunt => {
// Project configuration.
grunt.config.merge({
jsdoc: {
dist: {
options: {
configure: ".grunt/jsdoc/jsdoc.conf.js",
},
},
},
});
grunt.loadNpmTasks('grunt-jsdoc');
};
-40
View File
@@ -1,40 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2021 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = grunt => {
grunt.loadNpmTasks('grunt-sass');
grunt.config.merge({
sass: {
dist: {
files: {
"theme/boost/style/moodle.css": "theme/boost/scss/preset/default.scss",
"theme/classic/style/moodle.css": "theme/classic/scss/classicgrunt.scss"
}
},
options: {
implementation: require('sass'),
includePaths: ["theme/boost/scss/", "theme/classic/scss/"]
}
},
});
};
-155
View File
@@ -1,155 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2021 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/* eslint-env node */
module.exports = grunt => {
/**
* Shifter task. Is configured with a path to a specific file or a directory,
* in the case of a specific file it will work out the right module to be built.
*
* Note that this task runs the invidiaul shifter jobs async (becase it spawns
* so be careful to to call done().
*/
const handler = function() {
const done = this.async();
const options = grunt.config('shifter.options');
const async = require('async');
const path = require('path');
// Run the shifter processes one at a time to avoid confusing output.
async.eachSeries(options.paths, function(src, filedone) {
var args = [];
args.push(path.normalize(process.cwd() + '/node_modules/shifter/bin/shifter'));
// Always ignore the node_modules directory.
args.push('--excludes', 'node_modules');
// Determine the most appropriate options to run with based upon the current location.
if (grunt.file.isMatch('**/yui/**/*.js', src)) {
// When passed a JS file, build our containing module (this happen with
// watch).
grunt.log.debug('Shifter passed a specific JS file');
src = path.dirname(path.dirname(src));
options.recursive = false;
} else if (grunt.file.isMatch('**/yui/src', src)) {
// When in a src directory --walk all modules.
grunt.log.debug('In a src directory');
args.push('--walk');
options.recursive = false;
} else if (grunt.file.isMatch('**/yui/src/*', src)) {
// When in module, only build our module.
grunt.log.debug('In a module directory');
options.recursive = false;
} else if (grunt.file.isMatch('**/yui/src/*/js', src)) {
// When in module src, only build our module.
grunt.log.debug('In a source directory');
src = path.dirname(src);
options.recursive = false;
}
if (grunt.option('watch')) {
grunt.fail.fatal('The --watch option has been removed, please use `grunt watch` instead');
}
// Add the stderr option if appropriate
if (grunt.option('verbose')) {
args.push('--lint-stderr');
}
if (grunt.option('no-color')) {
args.push('--color=false');
}
var execShifter = function() {
grunt.log.ok("Running shifter on " + src);
grunt.util.spawn({
cmd: "node",
args: args,
opts: {cwd: src, stdio: 'inherit', env: process.env}
}, function(error, result, code) {
if (code) {
grunt.fail.fatal('Shifter failed with code: ' + code);
} else {
grunt.log.ok('Shifter build complete.');
filedone();
}
});
};
// Actually run shifter.
if (!options.recursive) {
execShifter();
} else {
// Check that there are yui modules otherwise shifter ends with exit code 1.
if (grunt.file.expand({cwd: src}, '**/yui/src/**/*.js').length > 0) {
args.push('--recursive');
execShifter();
} else {
grunt.log.ok('No YUI modules to build.');
filedone();
}
}
}, done);
};
// Register the shifter task.
grunt.registerTask('shifter', 'Run Shifter against the current directory', handler);
// Configure it.
grunt.config.set('shifter', {
options: {
recursive: true,
// Shifter takes a relative path.
paths: grunt.moodleEnv.files ? grunt.moodleEnv.files : [grunt.moodleEnv.runDir]
}
});
grunt.config.merge({
watch: {
yui: {
files: grunt.moodleEnv.inComponent
? ['yui/src/*.json', 'yui/src/**/*.js']
: ['**/yui/src/**/*.js'],
tasks: ['yui']
},
},
});
// On watch, we dynamically modify config to build only affected files. This
// method is slightly complicated to deal with multiple changed files at once (copied
// from the grunt-contrib-watch readme).
let changedFiles = Object.create(null);
const onChange = grunt.util._.debounce(function() {
const files = Object.keys(changedFiles);
grunt.config('shifter.options.paths', files);
changedFiles = Object.create(null);
}, 200);
grunt.event.on('watch', (action, filepath) => {
changedFiles[filepath] = action;
onChange();
});
return handler;
};
-46
View File
@@ -1,46 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2021 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = grunt => {
/**
* Generate ignore files (utilising thirdpartylibs.xml data)
*/
const handler = function() {
const path = require('path');
// Are we in a YUI directory?
if (path.basename(path.resolve(grunt.moodleEnv.cwd, '../../')) == 'yui') {
grunt.task.run('yui');
// Are we in an AMD directory?
} else if (grunt.moodleEnv.inAMD) {
grunt.task.run('amd');
} else {
// Run all of the requested startup tasks.
grunt.moodleEnv.startupTasks.forEach(taskName => grunt.task.run(taskName));
}
};
// Register the startup task.
grunt.registerTask('startup', 'Run the correct tasks for the current directory', handler);
return handler;
};
-35
View File
@@ -1,35 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2021 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = grunt => {
// Load the ignorefiles tasks.
require('./ignorefiles')(grunt);
// Load the Style Lint tasks.
require('./stylelint')(grunt);
// Load the SASS tasks.
require('./sass')(grunt);
// Add the 'css' task as a startup task.
grunt.moodleEnv.startupTasks.push('css');
};
-183
View File
@@ -1,183 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2021 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = grunt => {
const getCssConfigForFiles = files => {
return {
stylelint: {
css: {
// Use a fully-qualified path.
src: files,
options: {
configOverrides: {
rules: {
// These rules have to be disabled in .stylelintrc for scss compat.
"at-rule-no-unknown": true,
}
}
}
},
},
};
};
const getScssConfigForFiles = files => {
return {
stylelint: {
scss: {
options: {syntax: 'scss'},
src: files,
},
},
};
};
/**
* Register any stylelint tasks.
*
* @param {Object} grunt
* @param {Array} files
* @param {String} fullRunDir
*/
const registerStyleLintTasks = () => {
const glob = require('glob');
// The stylelinters do not handle the case where a configuration was provided but no files were included.
// Keep track of whether any files were found.
let hasCss = false;
let hasScss = false;
// The stylelint processors do not take a path argument. They always check all provided values.
// As a result we must check through each glob and determine if any files match the current directory.
const scssFiles = [];
const cssFiles = [];
const requestedFiles = grunt.moodleEnv.files;
if (requestedFiles) {
// Grunt was called with a files argument.
// Check whether each of the requested files matches either the CSS or SCSS source file list.
requestedFiles.forEach(changedFilePath => {
let matchesGlob;
// Check whether this watched path matches any watched SCSS file.
matchesGlob = grunt.moodleEnv.scssSrc.some(watchedPathGlob => {
return glob.sync(watchedPathGlob).indexOf(changedFilePath) !== -1;
});
if (matchesGlob) {
scssFiles.push(changedFilePath);
hasScss = true;
}
// Check whether this watched path matches any watched CSS file.
matchesGlob = grunt.moodleEnv.cssSrc.some(watchedPathGlob => {
return glob.sync(watchedPathGlob).indexOf(changedFilePath) !== -1;
});
if (matchesGlob) {
cssFiles.push(changedFilePath);
hasCss = true;
}
});
} else {
// Grunt was called without a list of files.
// The start directory (runDir) may be a child dir of the project.
// Check each scssSrc file to see if it's in the start directory.
// This means that we can lint just mod/*/styles.css if started in the mod directory.
grunt.moodleEnv.scssSrc.forEach(path => {
if (path.startsWith(grunt.moodleEnv.runDir)) {
scssFiles.push(path);
hasScss = true;
}
});
grunt.moodleEnv.cssSrc.forEach(path => {
if (path.startsWith(grunt.moodleEnv.runDir)) {
cssFiles.push(path);
hasCss = true;
}
});
}
// Register the tasks.
const scssTasks = ['sass'];
if (hasScss) {
grunt.config.merge(getScssConfigForFiles(scssFiles));
scssTasks.unshift('stylelint:scss');
}
scssTasks.unshift('ignorefiles');
const cssTasks = ['ignorefiles'];
if (hasCss) {
grunt.config.merge(getCssConfigForFiles(cssFiles));
cssTasks.push('stylelint:css');
}
// The tasks must be registered, even if empty to ensure a consistent command list.
// They jsut won't run anything.
grunt.registerTask('scss', scssTasks);
grunt.registerTask('rawcss', cssTasks);
};
// Register CSS tasks.
grunt.loadNpmTasks('grunt-stylelint');
// Register the style lint tasks.
registerStyleLintTasks();
grunt.registerTask('css', ['scss', 'rawcss']);
const getCoreThemeMatches = () => {
const scssMatch = 'scss/**/*.scss';
if (grunt.moodleEnv.inTheme) {
return [scssMatch];
}
if (grunt.moodleEnv.runDir.startsWith('theme')) {
return [`*/${scssMatch}`];
}
return [`theme/*/${scssMatch}`];
};
// Add the watch configuration for rawcss, and scss.
grunt.config.merge({
watch: {
rawcss: {
files: [
'**/*.css',
],
excludes: [
'**/moodle.css',
'**/editor.css',
'jsdoc/styles/*.css',
],
tasks: ['rawcss']
},
scss: {
files: getCoreThemeMatches(),
tasks: ['scss']
},
},
});
};
-42
View File
@@ -1,42 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* @copyright 2023 Sara Arjona <sara@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
module.exports = grunt => {
/**
* Generate upgradable third-party libraries (utilising thirdpartylibs.xml data)
*/
grunt.registerTask('upgradablelibs', 'Generate upgradable third-party libraries', async function() {
const done = this.async();
const path = require('path');
const ComponentList = require(path.join(process.cwd(), '.grunt', 'components.js'));
// An array of third party libraries that have a newer version in their repositories.
const thirdPartyLibs = await ComponentList.getThirdPartyLibsUpgradable({progress: true});
for (let library of thirdPartyLibs) {
grunt.log.ok(JSON.stringify(Object.assign({}, library), null, 4));
}
done();
});
};
-272
View File
@@ -1,272 +0,0 @@
/**
* This is a wrapper task to handle the grunt watch command. It attempts to use
* Watchman to monitor for file changes, if it's installed, because it's much faster.
*
* If Watchman isn't installed then it falls back to the grunt-contrib-watch file
* watcher for backwards compatibility.
*/
/* eslint-env node */
module.exports = grunt => {
/**
* This is a wrapper task to handle the grunt watch command. It attempts to use
* Watchman to monitor for file changes, if it's installed, because it's much faster.
*
* If Watchman isn't installed then it falls back to the grunt-contrib-watch file
* watcher for backwards compatibility.
*/
const watchHandler = function() {
const async = require('async');
const watchTaskDone = this.async();
let watchInitialised = false;
let watchTaskQueue = {};
let processingQueue = false;
const watchman = require('fb-watchman');
const watchmanClient = new watchman.Client();
// Grab the tasks and files that have been queued up and execute them.
var processWatchTaskQueue = function() {
if (!Object.keys(watchTaskQueue).length || processingQueue) {
// If there is nothing in the queue or we're already processing then wait.
return;
}
processingQueue = true;
// Grab all tasks currently in the queue.
var queueToProcess = watchTaskQueue;
// Reset the queue.
watchTaskQueue = {};
async.forEachSeries(
Object.keys(queueToProcess),
function(task, next) {
var files = queueToProcess[task];
var filesOption = '--files=' + files.join(',');
grunt.log.ok('Running task ' + task + ' for files ' + filesOption);
// Spawn the task in a child process so that it doesn't kill this one
// if it failed.
grunt.util.spawn(
{
// Spawn with the grunt bin.
grunt: true,
// Run from current working dir and inherit stdio from process.
opts: {
cwd: grunt.moodleEnv.fullRunDir,
stdio: 'inherit'
},
args: [task, filesOption]
},
function(err, res, code) {
if (code !== 0) {
// The grunt task failed.
grunt.log.error(err);
}
// Move on to the next task.
next();
}
);
},
function() {
// No longer processing.
processingQueue = false;
// Once all of the tasks are done then recurse just in case more tasks
// were queued while we were processing.
processWatchTaskQueue();
}
);
};
const originalWatchConfig = grunt.config.get(['watch']);
const watchConfig = Object.keys(originalWatchConfig).reduce(function(carry, key) {
if (key == 'options') {
return carry;
}
const value = originalWatchConfig[key];
const taskNames = value.tasks;
const files = value.files;
let excludes = [];
if (value.excludes) {
excludes = value.excludes;
}
taskNames.forEach(function(taskName) {
carry[taskName] = {
files,
excludes,
};
});
return carry;
}, {});
watchmanClient.on('error', function(error) {
// We have to add an error handler here and parse the error string because the
// example way from the docs to check if Watchman is installed doesn't actually work!!
// See: https://github.com/facebook/watchman/issues/509
if (error.message.match('Watchman was not found')) {
// If watchman isn't installed then we should fallback to the other watch task.
grunt.log.ok('It is recommended that you install Watchman for better performance using the "watch" command.');
// Fallback to the old grunt-contrib-watch task.
grunt.renameTask('watch-grunt', 'watch');
grunt.task.run(['watch']);
// This task is finished.
watchTaskDone(0);
} else {
grunt.log.error(error);
// Fatal error.
watchTaskDone(1);
}
});
watchmanClient.on('subscription', function(resp) {
if (resp.subscription !== 'grunt-watch') {
return;
}
resp.files.forEach(function(file) {
grunt.log.ok('File changed: ' + file.name);
var fullPath = grunt.moodleEnv.fullRunDir + '/' + file.name;
Object.keys(watchConfig).forEach(function(task) {
const fileGlobs = watchConfig[task].files;
var match = fileGlobs.some(function(fileGlob) {
return grunt.file.isMatch(`**/${fileGlob}`, fullPath);
});
if (match) {
// If we are watching a subdirectory then the file.name will be relative
// to that directory. However the grunt tasks expect the file paths to be
// relative to the Gruntfile.js location so let's normalise them before
// adding them to the queue.
var relativePath = fullPath.replace(grunt.moodleEnv.gruntFilePath + '/', '');
if (task in watchTaskQueue) {
if (!watchTaskQueue[task].includes(relativePath)) {
watchTaskQueue[task] = watchTaskQueue[task].concat(relativePath);
}
} else {
watchTaskQueue[task] = [relativePath];
}
}
});
});
processWatchTaskQueue();
});
process.on('SIGINT', function() {
// Let the user know that they may need to manually stop the Watchman daemon if they
// no longer want it running.
if (watchInitialised) {
grunt.log.ok('The Watchman daemon may still be running and may need to be stopped manually.');
}
process.exit();
});
// Initiate the watch on the current directory.
watchmanClient.command(['watch-project', grunt.moodleEnv.fullRunDir], function(watchError, watchResponse) {
if (watchError) {
grunt.log.error('Error initiating watch:', watchError);
watchTaskDone(1);
return;
}
if ('warning' in watchResponse) {
grunt.log.error('warning: ', watchResponse.warning);
}
var watch = watchResponse.watch;
var relativePath = watchResponse.relative_path;
watchInitialised = true;
watchmanClient.command(['clock', watch], function(clockError, clockResponse) {
if (clockError) {
grunt.log.error('Failed to query clock:', clockError);
watchTaskDone(1);
return;
}
// Generate the expression query used by watchman.
// Documentation is limited, but see https://facebook.github.io/watchman/docs/expr/allof.html for examples.
// We generate an expression to match any value in the files list of all of our tasks, but excluding
// all value in the excludes list of that task.
//
// [anyof, [
// [allof, [
// [anyof, [
// ['match', validPath, 'wholename'],
// ['match', validPath, 'wholename'],
// ],
// [not,
// [anyof, [
// ['match', invalidPath, 'wholename'],
// ['match', invalidPath, 'wholename'],
// ],
// ],
// ],
var matchWholeName = fileGlob => ['match', fileGlob, 'wholename'];
var matches = Object.keys(watchConfig).map(function(task) {
const matchAll = [];
matchAll.push(['anyof'].concat(watchConfig[task].files.map(matchWholeName)));
if (watchConfig[task].excludes.length) {
matchAll.push(['not', ['anyof'].concat(watchConfig[task].excludes.map(matchWholeName))]);
}
return ['allof'].concat(matchAll);
});
matches = ['anyof'].concat(matches);
var sub = {
expression: matches,
// Which fields we're interested in.
fields: ["name", "size", "type"],
// Add our time constraint.
since: clockResponse.clock
};
if (relativePath) {
/* eslint-disable camelcase */
sub.relative_root = relativePath;
}
watchmanClient.command(['subscribe', watch, 'grunt-watch', sub], function(subscribeError) {
if (subscribeError) {
// Probably an error in the subscription criteria.
grunt.log.error('failed to subscribe: ', subscribeError);
watchTaskDone(1);
return;
}
grunt.log.ok('Listening for changes to files in ' + grunt.moodleEnv.fullRunDir);
});
});
});
};
// Rename the grunt-contrib-watch "watch" task because we're going to wrap it.
grunt.renameTask('watch', 'watch-grunt');
// Register the new watch handler.
grunt.registerTask('watch', 'Run tasks on file changes', watchHandler);
grunt.config.merge({
watch: {
options: {
nospawn: true // We need not to spawn so config can be changed dynamically.
},
},
});
return watchHandler;
};
-2
View File
@@ -1,2 +0,0 @@
**/amd/**
/*.js
-58
View File
@@ -1,58 +0,0 @@
// NOTE: We use eslint now. This file is used only by shifter. We keep the configuration
// here because shifter uses jshint after modules have been concating. Eslint can't
// currently do this.
{
"asi": false,
"bitwise": true,
"boss": false,
"browser": true,
"curly": true,
"debug": false,
"eqeqeq": false,
"eqnull": false,
"es5": false,
"esnext": false,
"evil": false,
"expr": false,
"forin": false,
"funcscope": false,
"globalstrict": false,
"immed": true,
"indent": 4,
"iterator": false,
"lastsemic": false,
"latedef": true,
"laxbreak": true,
"laxcomma": false,
"loopfunc": false,
"maxerr": 500,
"maxlen": 132,
"multistr": false,
"newcap": true,
"noarg": true,
"noempty": true,
"nomen": false,
"onecase": false,
"onevar": false,
"passfail": false,
"plusplus": false,
"predef": [
"M",
"define",
"require"
],
"proto": false,
"regexdash": false,
"regexp": false,
"scripturl": false,
"shadow": false,
"smarttabs": false,
"strict": false,
"sub": false,
"supernew": false,
"trailing": true,
"undef": true,
"unused": true,
"white": false,
"yui": true
}
-1
View File
@@ -1 +0,0 @@
lts/gallium
-5
View File
@@ -1,5 +0,0 @@
{
"coverage": false,
"lint": "config",
"clean": true
}
-95
View File
@@ -1,95 +0,0 @@
{
"plugins": [
"stylelint-csstree-validator"
],
"rules": {
"csstree/validator": true,
"at-rule-empty-line-before": [ "always",
{"except": [ "blockless-after-blockless"], ignore: ["after-comment", "inside-block"]}
],
"at-rule-name-case": "lower",
"at-rule-name-space-after": "always-single-line",
"at-rule-no-unknown": null, # Enabled for non-scss in grunt.
"at-rule-semicolon-newline-after": "always",
"at-rule-semicolon-space-before": "never",
"block-closing-brace-newline-after": "always",
"block-closing-brace-newline-before": "always",
"block-closing-brace-space-before": "always-single-line",
"block-no-empty": true,
"block-opening-brace-newline-after": "always",
"block-opening-brace-space-after": "always-single-line",
"block-opening-brace-space-before": "always",
"color-hex-case": ["lower", { "severity": "warning" }],
"color-hex-length": ["short", { "severity": "warning" }],
"color-no-invalid-hex": true,
"declaration-bang-space-after": "never",
"declaration-bang-space-before": "always",
"declaration-block-no-duplicate-properties": true,
"declaration-block-no-shorthand-property-overrides": true,
"declaration-block-semicolon-newline-after": "always-multi-line",
"declaration-block-semicolon-space-after": "always-single-line",
"declaration-block-semicolon-space-before": "never",
"declaration-block-single-line-max-declarations": 1,
"declaration-block-trailing-semicolon": "always",
"declaration-colon-newline-after": "always-multi-line",
"declaration-colon-space-after": "always-single-line",
"declaration-colon-space-before": "never",
"declaration-no-important": true,
"font-family-no-duplicate-names": true,
"function-calc-no-unspaced-operator": true,
"function-comma-newline-after": "always-multi-line",
"function-comma-space-after": "always-single-line",
"function-comma-space-before": "never",
"function-linear-gradient-no-nonstandard-direction": true,
"function-max-empty-lines": 0,
"function-name-case": "lower",
"function-parentheses-newline-inside": "always-multi-line",
"function-parentheses-space-inside": "never-single-line",
"function-url-scheme-blacklist": ["data"],
"function-whitespace-after": "always",
"indentation": 4,
"keyframe-declaration-no-important": true,
"length-zero-no-unit": [true, { "severity": "warning" }],
"max-empty-lines": 2,
"max-line-length": [132, { "severity": "warning" }],
"media-feature-colon-space-after": "always",
"media-feature-colon-space-before": "never",
"media-feature-parentheses-space-inside": "never",
"media-feature-range-operator-space-after": "always",
"media-feature-range-operator-space-before": "always",
"media-query-list-comma-newline-after": "always-multi-line",
"media-query-list-comma-space-after": "always-single-line",
"media-query-list-comma-space-before": "never",
"no-empty-source": true,
"no-eol-whitespace": true,
"no-extra-semicolons": [true, { "severity": "warning" }],
"no-invalid-double-slash-comments": true,
"no-unknown-animations": true,
"property-case": "lower",
"property-no-unknown": true,
"selector-attribute-brackets-space-inside": "never",
"selector-attribute-operator-space-after": "never",
"selector-attribute-operator-space-before": "never",
"selector-combinator-space-after": "always",
"selector-combinator-space-before": "always",
"selector-list-comma-newline-after": "always",
"selector-list-comma-space-before": "never",
"selector-max-empty-lines": 0,
"selector-pseudo-class-case": "lower",
"selector-pseudo-class-no-unknown": true,
"selector-pseudo-class-parentheses-space-inside": "never",
"selector-pseudo-element-case": "lower",
"selector-pseudo-element-no-unknown": true,
"selector-type-case": "lower",
"selector-type-no-unknown": true,
"string-no-newline": true,
"time-min-milliseconds": 100,
"unit-blacklist": ["pt"],
"unit-case": "lower",
"unit-no-unknown": true,
"value-keyword-case": ["lower", {"ignoreKeywords": ["/(@|$)/"]}],
"value-list-comma-newline-after": "always-multi-line",
"value-list-comma-space-after": "always-single-line",
"value-list-comma-space-before": "never",
}
}
-56
View File
@@ -1,56 +0,0 @@
CONTRIBUTING TO MOODLE
======================
Moodle is made by people like you. We are members of a big worldwide community
of developers, designers, teachers, testers, translators and other users. We
work in universities, schools, companies and other places. You are very welcome
to join us and contribute to the project.
See <https://docs.moodle.org/dev/Contributing_to_Moodle> for the many ways you
can help, not only with coding.
Moodle is open to community contributions to core, though all code must go
through peer-review, automated behaviour testing, continuous integration and
human post-integration checks.
Pull requests
-------------
Please do not open pull requests via Github. The repository there is just a
mirror of the official repository at <https://git.moodle.org>. Issues are
reported and patches provided via <https://tracker.moodle.org>. See below for
more information.
Moodle core bug fixes and new features
--------------------------------------
During the years of intensive development, a mature process of including
submitted patches has evolved.
* Every bug fix or new feature must have a tracker issue.
* You publish the branch implementing the fix or new feature in your public
clone of the moodle.git repository (typically on Github).
* Your patch is peer-reviewed, discussed, integrated, tested and then released
as a part of moodle.git.
* New features are developed on the master branch. Bug fixes are also
backported to currently supported maintenance (stable) branches.
For further details, see <https://docs.moodle.org/dev/Process>.
Moodle plugins
--------------
Moodle has a framework for additional plugins to extend its functionality. We
have a Moodle plugins directory <https://moodle.org/plugins/> where you can
register and maintain your plugin. Plugins hosted in the plugins directory can
be easily installed and updated via the Moodle administration interface.
* You are expected to have a public source code repository with your plugin
code.
* After registering your plugin in the plugins directory it is reviewed before
being published.
* You are expected to continuously release updated versions of the plugin via
the plugins directory. We do not pull from your code repository; you must do
it explicitly.
For further details, see <https://docs.moodle.org/dev/Plugin_contribution>.
-267
View File
@@ -1,267 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/* jshint node: true, browser: false */
/* eslint-env node */
/**
* Grunt configuration for Moodle.
*
* @copyright 2014 Andrew Nicols
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Setup the Grunt Moodle environment.
*
* @param {Grunt} grunt
* @returns {Object}
*/
const setupMoodleEnvironment = grunt => {
const fs = require('fs');
const path = require('path');
const ComponentList = require(path.join(process.cwd(), '.grunt', 'components.js'));
const getAmdConfiguration = () => {
// If the cwd is the amd directory in the current component then it will be empty.
// If the cwd is a child of the component's AMD directory, the relative directory will not start with ..
let inAMD = !path.relative(`${componentDirectory}/amd`, cwd).startsWith('..');
// Globbing pattern for matching all AMD JS source files.
let amdSrc = [];
if (inComponent) {
amdSrc.push(
componentDirectory + "/amd/src/*.js",
componentDirectory + "/amd/src/**/*.js"
);
} else {
amdSrc = ComponentList.getAmdSrcGlobList();
}
return {
inAMD,
amdSrc,
};
};
const getYuiConfiguration = () => {
let yuiSrc = [];
if (inComponent) {
yuiSrc.push(componentDirectory + "/yui/src/**/*.js");
} else {
yuiSrc = ComponentList.getYuiSrcGlobList(gruntFilePath + '/');
}
return {
yuiSrc,
};
};
const getStyleConfiguration = () => {
const ComponentList = require(path.join(process.cwd(), '.grunt', 'components.js'));
// Build the cssSrc and scssSrc.
// Valid paths are:
// [component]/styles.css; and either
// [theme/[themename]]/scss/**/*.scss; or
// [theme/[themename]]/style/*.css.
//
// If a theme has scss, then it is assumed that the style directory contains generated content.
let cssSrc = [];
let scssSrc = [];
const checkComponentDirectory = componentDirectory => {
const isTheme = componentDirectory.startsWith('theme/');
if (isTheme) {
const scssDirectory = `${componentDirectory}/scss`;
if (fs.existsSync(scssDirectory)) {
// This theme has an SCSS directory.
// Include all scss files within it recursively, but do not check for css files.
scssSrc.push(`${scssDirectory}/*.scss`);
scssSrc.push(`${scssDirectory}/**/*.scss`);
} else {
// This theme has no SCSS directory.
// Only hte CSS files in the top-level directory are checked.
cssSrc.push(`${componentDirectory}/style/*.css`);
}
} else {
// This is not a theme.
// All other plugin types are restricted to a single styles.css in their top level.
cssSrc.push(`${componentDirectory}/styles.css`);
}
};
if (inComponent) {
checkComponentDirectory(componentDirectory);
} else {
ComponentList.getComponentPaths(`${gruntFilePath}/`).forEach(componentPath => {
checkComponentDirectory(componentPath);
});
}
return {
cssSrc,
scssSrc,
};
};
/**
* Calculate the cwd, taking into consideration the `root` option (for Windows).
*
* @param {Object} grunt
* @returns {String} The current directory as best we can determine
*/
const getCwd = grunt => {
let cwd = fs.realpathSync(process.env.PWD || process.cwd());
// Windows users can't run grunt in a subdirectory, so allow them to set
// the root by passing --root=path/to/dir.
if (grunt.option('root')) {
const root = grunt.option('root');
if (grunt.file.exists(__dirname, root)) {
cwd = fs.realpathSync(path.join(__dirname, root));
grunt.log.ok('Setting root to ' + cwd);
} else {
grunt.fail.fatal('Setting root to ' + root + ' failed - path does not exist');
}
}
return cwd;
};
// Detect directories:
// * gruntFilePath The real path on disk to this Gruntfile.js
// * cwd The current working directory, which can be overridden by the `root` option
// * relativeCwd The cwd, relative to the Gruntfile.js
// * componentDirectory The root directory of the component if the cwd is in a valid component
// * inComponent Whether the cwd is in a valid component
// * runDir The componentDirectory or cwd if not in a component, relative to Gruntfile.js
// * fullRunDir The full path to the runDir
const gruntFilePath = fs.realpathSync(process.cwd());
const cwd = getCwd(grunt);
const relativeCwd = path.relative(gruntFilePath, cwd);
const componentDirectory = ComponentList.getOwningComponentDirectory(relativeCwd);
const inComponent = !!componentDirectory;
const inTheme = !!componentDirectory && componentDirectory.startsWith('theme/');
const runDir = inComponent ? componentDirectory : relativeCwd;
const fullRunDir = fs.realpathSync(gruntFilePath + path.sep + runDir);
const {inAMD, amdSrc} = getAmdConfiguration();
const {yuiSrc} = getYuiConfiguration();
const {cssSrc, scssSrc} = getStyleConfiguration();
let files = null;
if (grunt.option('files')) {
// Accept a comma separated list of files to process.
files = grunt.option('files').split(',');
}
grunt.log.debug('============================================================================');
grunt.log.debug(`= Node version: ${process.versions.node}`);
grunt.log.debug(`= grunt version: ${grunt.package.version}`);
grunt.log.debug(`= process.cwd: '` + process.cwd() + `'`);
grunt.log.debug(`= process.env.PWD: '${process.env.PWD}'`);
grunt.log.debug(`= path.sep '${path.sep}'`);
grunt.log.debug('============================================================================');
grunt.log.debug(`= gruntFilePath: '${gruntFilePath}'`);
grunt.log.debug(`= relativeCwd: '${relativeCwd}'`);
grunt.log.debug(`= componentDirectory: '${componentDirectory}'`);
grunt.log.debug(`= inComponent: '${inComponent}'`);
grunt.log.debug(`= runDir: '${runDir}'`);
grunt.log.debug(`= fullRunDir: '${fullRunDir}'`);
grunt.log.debug('============================================================================');
if (inComponent) {
grunt.log.ok(`Running tasks for component directory ${componentDirectory}`);
}
return {
amdSrc,
componentDirectory,
cwd,
cssSrc,
files,
fullRunDir,
gruntFilePath,
inAMD,
inComponent,
inTheme,
relativeCwd,
runDir,
scssSrc,
yuiSrc,
};
};
/**
* Verify tha tthe current NodeJS version matches the required version in package.json.
*
* @param {Grunt} grunt
*/
const verifyNodeVersion = grunt => {
const semver = require('semver');
// Verify the node version is new enough.
var expected = semver.validRange(grunt.file.readJSON('package.json').engines.node);
var actual = semver.valid(process.version);
if (!semver.satisfies(actual, expected)) {
grunt.fail.fatal('Node version not satisfied. Require ' + expected + ', version installed: ' + actual);
}
};
/**
* Grunt configuration.
*
* @param {Grunt} grunt
*/
module.exports = function(grunt) {
// Verify that the Node version meets our requirements.
verifyNodeVersion(grunt);
// Setup the Moodle environemnt within the Grunt object.
grunt.moodleEnv = setupMoodleEnvironment(grunt);
/**
* Add the named task.
*
* @param {string} name
* @param {Grunt} grunt
*/
const addTask = (name, grunt) => {
const path = require('path');
const taskPath = path.resolve(`./.grunt/tasks/${name}.js`);
grunt.log.debug(`Including tasks for ${name} from ${taskPath}`);
require(path.resolve(`./.grunt/tasks/${name}.js`))(grunt);
};
// Startup tasks.
grunt.moodleEnv.startupTasks = [];
// Add Moodle task configuration.
addTask('gherkinlint', grunt);
addTask('ignorefiles', grunt);
addTask('javascript', grunt);
addTask('style', grunt);
addTask('componentlibrary', grunt);
addTask('watch', grunt);
addTask('startup', grunt);
addTask('upgradablelibs', grunt);
// Register the default task.
grunt.registerTask('default', ['startup']);
};
-20
View File
@@ -1,20 +0,0 @@
MOODLE INSTALLATION
===================
Here is a short summary of the installation process (which can take just a few
minutes):
1. Move the Moodle files into your web directory.
2. Create a single database for Moodle to store all its tables in (or choose an
existing database).
3. Visit your Moodle site with a browser. You should be taken to the
install.php script, which will lead you through creating a config.php file
and then setting up Moodle, creating an admin account etc.
4. Set up a cron task to call the file admin/cron.php every minute.
For more information, see <https://docs.moodle.org/en/Installing_Moodle>.
Good luck and have fun!
-7
View File
@@ -1,7 +0,0 @@
*** PLEASE DO NOT OPEN PULL REQUESTS VIA GITHUB ***
The moodle.git repository at Github is just a mirror of the official repository. We do not accept pull requests at Github.
See CONTRIBUTING.txt guidelines for how to contribute patches for Moodle. Thank you.
--
+22 -21
View File
@@ -1,28 +1,29 @@
.-..-.
_____ | || |
/____/-.---_ .---. .---. .-.| || | .---.
| | _ _ |/ _ \/ _ \/ _ || |/ __ \
* | | | | | || |_| || |_| || |_| || || |___/
|_| |_| |_|\_____/\_____/\_____||_|\_____)
QUICK INSTALL
=============
Moodle - the world's open source learning platform
For the impatient, here is a basic outline of the
installation process, which normally takes me only
a few minutes:
Moodle <https://moodle.org> is a learning platform designed to provide
educators, administrators and learners with a single robust, secure and
integrated system to create personalised learning environments.
1) Move the Moodle files into your web directory.
You can download Moodle <https://download.moodle.org> and run it on your own
web server, ask one of our Moodle Partners <https://moodle.com/partners/> to
assist you, or have a MoodleCloud site <https://moodle.com/cloud/> set up for
you.
2) Create a single database for Moodle to store all
its tables in (or choose an existing database).
Moodle is widely used around the world by universities, schools, companies and
all manner of organisations and individuals.
3) Visit your Moodle site with a browser, you should
be taken to the install.php script, which will lead
you through creating a config.php file and then
setting up Moodle, creating an admin account etc.
Moodle is provided freely as open source software, under the GNU General Public
License <https://docs.moodle.org/dev/License>.
4) Set up a cron task to call the file admin/cron.php
every five minutes or so.
Moodle is written in PHP and JavaScript and uses an SQL database for storing
the data.
See <https://docs.moodle.org> for details of Moodle's many features.
For more information, see the INSTALL DOCUMENTATION:
http://docs.moodle.org/en/Installing_Moodle
Good luck and have fun!
Martin Dougiamas, Lead Developer
+28 -60
View File
@@ -1,66 +1,34 @@
MOODLE TRADEMARKS POLICY
========================
The Moodle Trademark
--------------------
The brand and word "Moodle" has trade mark protection in many countries around
the world. Various Moodle™ trade marks are owned by either Moodle Pty Ltd or
one of its associated entities. The law obligates trade mark owners to police
their trade marks and prevent the use of confusingly similar names by
third parties.
We have created a more concise and thorough set of Trademark Guidelines
(https://moodle.com/wp-content/uploads/2023/02/Moodle-Trademark-Guidelines-2023-4.pdf)
to help you understand how to comply with Moodle's trade mark requirements.
The Trademark Guidelines will also assist our Moodle Certified Partners and the
community to understand some of the principles that inform Moodle's stance
whenever potential infringement has been detected by us or our community.
We need to be clear about use of the word "Moodle" and how we restrict its use
when promoting commercial Moodle™ branded services. The proper use of
trade marks reliably assures consumers about the quality of the associated
products or services and where they have been derived from. Because the
Moodle LMS is made available under the open source GNU General Public License'
that permits you to modify the copyrighted software, the distribution of such
modified software in combination with Moodle trade marks can potentially
mislead others in the community. To be clear, the GNU GPL does not include an
implied right or licence to use Moodle's trade marks.
We do all this to protect the very business model that allows us to continue
developing various Moodle software solutions for you.
Allowed uses of "Moodle"
------------------------
Moodle Trademark License
------------------------
The following uses don't require any permission at all:
The name Moodle™ is a registered trademark of the Moodle Trust.
* Referring to the software or the Moodle project as the "Moodle™ software"
or the "Moodle™ project"
* Describing your own implementation of the Moodle™ software platform
(including within corporate settings).
* Describing a Moodle-based community hub.
* Describing certain software you've made that integrates with Moodle™
branded software (e.g. a Moodle™ integration feature on another system).
A key part of the business model that allows us to produce and
distribute Moodle as completely Free open source software is that
we restrict the commercial use of the Moodle trademark to those
who have contracted to support Moodle development (Moodle Partners).
Restricted uses of "Moodle"
---------------------------
If you are intending to use the name (and/or logo) to advertise
generic Moodle™ services (eg Moodle Hosting, Moodle Support,
Moodle Certification, Moodle Training, Moodle Consulting,
Moodle Customisation, Moodle Courseware Development, Moodle
Theme design, Moodle Integrations, Moodle Installations, etc)
or as the name of a software package, then you must seek
direct permission in writing from the Moodle Trust via the
moodle.com helpdesk, in accordance with normal trademark
restrictions.
The following uses are generally prohibited without explicit and direct
permission being granted to you by Moodle Pty Ltd. We do this to protect the
Moodle™ project from software and sites which could confuse people. If in
doubt, reach out for clarification at <trademarks@moodle.com>
There are no restrictions on how you use the name in other
contexts (for example, if you use Moodle just to provide
courses then you can use the name freely to refer to it.)
* You can't use the word "Moodle" or any Moodle logos for commercial purposes
without prior written permission from Moodle HQ.
* You can't use "Moodle" in the name of your software (including Mobile apps).
* You can't use "Moodle" in your company name.
* You can't use "Moodle" in your domain name.
* You can't use "Moodle" in advertising-related keywords (such as Adsense).
* You can't use "Moodle" to describe services around Moodle
(such as hosting, training, support, consulting, course creation services,
theme development, customisation, installation, integration, analytics
and certification) that cause consumers to be confused that you are
associated with Moodle HQ if you are not.
This applies even if you do not charge for the services.
Note that usually only Moodle Partners have this permission.
If you aren't sure of a particular case, please ask us via
http://moodle.com/helpdesk: we'll be happy to either provide
you with official permission in writing or help you fix
your wording.
Martin Dougiamas
Executive Director
Moodle Trust
http://moodle.com
-3
View File
@@ -1,3 +0,0 @@
define("core_admin/block_management_table",["exports","./plugin_management_table","core_table/dynamic","core/ajax","core/pending","core/notification"],(function(_exports,_plugin_management_table,_dynamic,_ajax,_pending,_notification){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,_plugin_management_table=_interopRequireDefault(_plugin_management_table),_pending=_interopRequireDefault(_pending);class _default extends _plugin_management_table.default{constructor(){super(),this.addClickHandler(this.handleBlockProtectToggle)}setBlockProtectState(plugin,state){return(0,_ajax.call)([{methodname:"core_admin_set_block_protection",args:{plugin:plugin,state:state}}])[0]}async handleBlockProtectToggle(tableRoot,e){const stateToggle=e.target.closest('[data-action="toggleprotectstate"]');if(stateToggle){e.preventDefault();const pendingPromise=new _pending.default("core_table/dynamic:processAction");await this.setBlockProtectState(stateToggle.dataset.plugin,"1"===stateToggle.dataset.targetState?1:0);const[updatedRoot]=await Promise.all([(0,_dynamic.refreshTableContent)(tableRoot),(0,_notification.fetchNotifications)()]);updatedRoot.querySelector('[data-action="toggleprotectstate"][data-plugin="'.concat(stateToggle.dataset.plugin,'"]')).focus(),pendingPromise.resolve()}}}return _exports.default=_default,_exports.default}));
//# sourceMappingURL=block_management_table.min.js.map
@@ -1 +0,0 @@
{"version":3,"file":"block_management_table.min.js","sources":["../src/block_management_table.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\nimport PluginManagementTable from './plugin_management_table';\nimport {refreshTableContent} from 'core_table/dynamic';\nimport {call as fetchMany} from 'core/ajax';\nimport Pending from 'core/pending';\nimport {fetchNotifications} from 'core/notification';\n\nexport default class extends PluginManagementTable {\n constructor() {\n super();\n this.addClickHandler(this.handleBlockProtectToggle);\n }\n\n /**\n * Set the block protection state.\n *\n * @param {string} plugin\n * @param {number} state\n * @returns {Promise}\n */\n setBlockProtectState(plugin, state) {\n return fetchMany([{\n methodname: 'core_admin_set_block_protection',\n args: {\n plugin,\n state,\n },\n }])[0];\n }\n\n /**\n * Handle toggling of block protection.\n *\n * @param {HTMLElement} tableRoot\n * @param {Event} e\n */\n async handleBlockProtectToggle(tableRoot, e) {\n const stateToggle = e.target.closest('[data-action=\"toggleprotectstate\"]');\n if (stateToggle) {\n e.preventDefault();\n const pendingPromise = new Pending('core_table/dynamic:processAction');\n\n await this.setBlockProtectState(\n stateToggle.dataset.plugin,\n stateToggle.dataset.targetState === '1' ? 1 : 0\n );\n\n const [updatedRoot] = await Promise.all([\n refreshTableContent(tableRoot),\n fetchNotifications(),\n ]);\n\n // Refocus on the link that as pressed in the first place.\n updatedRoot.querySelector(`[data-action=\"toggleprotectstate\"][data-plugin=\"${stateToggle.dataset.plugin}\"]`).focus();\n pendingPromise.resolve();\n }\n }\n}\n"],"names":["PluginManagementTable","constructor","addClickHandler","this","handleBlockProtectToggle","setBlockProtectState","plugin","state","methodname","args","tableRoot","e","stateToggle","target","closest","preventDefault","pendingPromise","Pending","dataset","targetState","updatedRoot","Promise","all","querySelector","focus","resolve"],"mappings":"uhBAqB6BA,iCACzBC,2BAESC,gBAAgBC,KAAKC,0BAU9BC,qBAAqBC,OAAQC,cAClB,cAAU,CAAC,CACdC,WAAY,kCACZC,KAAM,CACFH,OAAAA,OACAC,MAAAA,UAEJ,kCASuBG,UAAWC,SAChCC,YAAcD,EAAEE,OAAOC,QAAQ,yCACjCF,YAAa,CACbD,EAAEI,uBACIC,eAAiB,IAAIC,iBAAQ,0CAE7Bd,KAAKE,qBACPO,YAAYM,QAAQZ,OACgB,MAApCM,YAAYM,QAAQC,YAAsB,EAAI,SAG3CC,mBAAqBC,QAAQC,IAAI,EACpC,gCAAoBZ,YACpB,wCAIJU,YAAYG,wEAAiEX,YAAYM,QAAQZ,cAAYkB,QAC7GR,eAAeS"}
-3
View File
@@ -1,3 +0,0 @@
define("core_admin/plugin_management_table",["exports","core_table/dynamic","core_table/local/dynamic/selectors","core/ajax","core/pending","core/notification"],(function(_exports,_dynamic,Selectors,_ajax,_pending,_notification){var obj;function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.default=void 0,Selectors=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(Selectors),_pending=(obj=_pending)&&obj.__esModule?obj:{default:obj};let watching=!1;return _exports.default=class{constructor(){!function(obj,key,value){key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value}(this,"clickHandlers",[]),this.addClickHandler(this.handleStateToggle),this.addClickHandler(this.handleMoveUpDown),this.registerEventListeners()}static init(){watching||(watching=!0,new this)}addClickHandler(handler){this.clickHandlers.push(handler.bind(this))}registerEventListeners(){document.addEventListener("click",function(e){const tableRoot=this.getTableRoot(e);tableRoot&&this.clickHandlers.forEach((handler=>handler(tableRoot,e)))}.bind(this))}getTableRoot(e){const tableRoot=e.target.closest(Selectors.main.region);return tableRoot||!1}setPluginState(methodname,plugin,state){return(0,_ajax.call)([{methodname:methodname,args:{plugin:plugin,state:state}}])[0]}setPluginOrder(methodname,plugin,direction){return(0,_ajax.call)([{methodname:methodname,args:{plugin:plugin,direction:direction}}])[0]}async handleStateToggle(tableRoot,e){const stateToggle=e.target.closest('[data-action="togglestate"][data-toggle-method]');if(stateToggle){e.preventDefault();const pendingPromise=new _pending.default("core_table/dynamic:togglestate");await this.setPluginState(stateToggle.dataset.toggleMethod,stateToggle.dataset.plugin,"1"===stateToggle.dataset.state?0:1);const[updatedRoot]=await Promise.all([(0,_dynamic.refreshTableContent)(tableRoot),(0,_notification.fetchNotifications)()]);updatedRoot.querySelector('[data-action="togglestate"][data-plugin="'.concat(stateToggle.dataset.plugin,'"]')).focus(),pendingPromise.resolve()}}async handleMoveUpDown(tableRoot,e){const actionLink=e.target.closest('[data-action="move"][data-method][data-direction]');if(!actionLink)return;e.preventDefault();const pendingPromise=new _pending.default("core_table/dynamic:processAction");await this.setPluginOrder(actionLink.dataset.method,actionLink.dataset.plugin,"up"===actionLink.dataset.direction?-1:1);const[updatedRoot]=await Promise.all([(0,_dynamic.refreshTableContent)(tableRoot),(0,_notification.fetchNotifications)()]),exactMatch=updatedRoot.querySelector('[data-action="move"][data-plugin="'.concat(actionLink.dataset.plugin,'"][data-direction="').concat(actionLink.dataset.direction,'"]'));var _updatedRoot$querySel;exactMatch?exactMatch.focus():null===(_updatedRoot$querySel=updatedRoot.querySelector('[data-action="move"][data-plugin="'.concat(actionLink.dataset.plugin,'"]')))||void 0===_updatedRoot$querySel||_updatedRoot$querySel.focus();pendingPromise.resolve()}},_exports.default}));
//# sourceMappingURL=plugin_management_table.min.js.map
File diff suppressed because one or more lines are too long
-72
View File
@@ -1,72 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
import PluginManagementTable from './plugin_management_table';
import {refreshTableContent} from 'core_table/dynamic';
import {call as fetchMany} from 'core/ajax';
import Pending from 'core/pending';
import {fetchNotifications} from 'core/notification';
export default class extends PluginManagementTable {
constructor() {
super();
this.addClickHandler(this.handleBlockProtectToggle);
}
/**
* Set the block protection state.
*
* @param {string} plugin
* @param {number} state
* @returns {Promise}
*/
setBlockProtectState(plugin, state) {
return fetchMany([{
methodname: 'core_admin_set_block_protection',
args: {
plugin,
state,
},
}])[0];
}
/**
* Handle toggling of block protection.
*
* @param {HTMLElement} tableRoot
* @param {Event} e
*/
async handleBlockProtectToggle(tableRoot, e) {
const stateToggle = e.target.closest('[data-action="toggleprotectstate"]');
if (stateToggle) {
e.preventDefault();
const pendingPromise = new Pending('core_table/dynamic:processAction');
await this.setBlockProtectState(
stateToggle.dataset.plugin,
stateToggle.dataset.targetState === '1' ? 1 : 0
);
const [updatedRoot] = await Promise.all([
refreshTableContent(tableRoot),
fetchNotifications(),
]);
// Refocus on the link that as pressed in the first place.
updatedRoot.querySelector(`[data-action="toggleprotectstate"][data-plugin="${stateToggle.dataset.plugin}"]`).focus();
pendingPromise.resolve();
}
}
}
-179
View File
@@ -1,179 +0,0 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
import {refreshTableContent} from 'core_table/dynamic';
import * as Selectors from 'core_table/local/dynamic/selectors';
import {call as fetchMany} from 'core/ajax';
import Pending from 'core/pending';
import {fetchNotifications} from 'core/notification';
let watching = false;
export default class {
/**
* @property {function[]} clickHandlers a list of handlers to call on click.
*/
clickHandlers = [];
constructor() {
this.addClickHandler(this.handleStateToggle);
this.addClickHandler(this.handleMoveUpDown);
this.registerEventListeners();
}
/**
* Initialise an instance of the class.
*
* This is just a way of making it easier to initialise an instance of the class from PHP.
*/
static init() {
if (watching) {
return;
}
watching = true;
new this();
}
/**
* Add a click handler to the list of handlers.
*
* @param {Function} handler A handler to call on a click event
*/
addClickHandler(handler) {
this.clickHandlers.push(handler.bind(this));
}
/**
* Register the event listeners for this instance.
*/
registerEventListeners() {
document.addEventListener('click', function(e) {
const tableRoot = this.getTableRoot(e);
if (!tableRoot) {
return;
}
this.clickHandlers.forEach((handler) => handler(tableRoot, e));
}.bind(this));
}
/**
* Get the table root from an event.
*
* @param {Event} e
* @returns {HTMLElement|bool}
*/
getTableRoot(e) {
const tableRoot = e.target.closest(Selectors.main.region);
if (!tableRoot) {
return false;
}
return tableRoot;
}
/**
* Set the plugin state (enabled or disabled)
*
* @param {string} methodname The web service to call
* @param {string} plugin The name of the plugin to set the state for
* @param {number} state The state to set
* @returns {Promise}
*/
setPluginState(methodname, plugin, state) {
return fetchMany([{
methodname,
args: {
plugin,
state,
},
}])[0];
}
setPluginOrder(methodname, plugin, direction) {
return fetchMany([{
methodname,
args: {
plugin,
direction,
},
}])[0];
}
/**
* Handle state toggling.
*
* @param {HTMLElement} tableRoot
* @param {Event} e
*/
async handleStateToggle(tableRoot, e) {
const stateToggle = e.target.closest('[data-action="togglestate"][data-toggle-method]');
if (stateToggle) {
e.preventDefault();
const pendingPromise = new Pending('core_table/dynamic:togglestate');
await this.setPluginState(
stateToggle.dataset.toggleMethod,
stateToggle.dataset.plugin,
stateToggle.dataset.state === '1' ? 0 : 1
);
const [updatedRoot] = await Promise.all([
refreshTableContent(tableRoot),
fetchNotifications(),
]);
// Refocus on the link that as pressed in the first place.
updatedRoot.querySelector(`[data-action="togglestate"][data-plugin="${stateToggle.dataset.plugin}"]`).focus();
pendingPromise.resolve();
}
}
async handleMoveUpDown(tableRoot, e) {
const actionLink = e.target.closest('[data-action="move"][data-method][data-direction]');
if (!actionLink) {
return;
}
e.preventDefault();
const pendingPromise = new Pending('core_table/dynamic:processAction');
await this.setPluginOrder(
actionLink.dataset.method,
actionLink.dataset.plugin,
actionLink.dataset.direction === 'up' ? -1 : 1,
);
const [updatedRoot] = await Promise.all([
refreshTableContent(tableRoot),
fetchNotifications(),
]);
// Refocus on the link that as pressed in the first place.
const exactMatch = updatedRoot.querySelector(
`[data-action="move"][data-plugin="${actionLink.dataset.plugin}"][data-direction="${actionLink.dataset.direction}"]`
);
if (exactMatch) {
exactMatch.focus();
} else {
// The move link is not present anymore, so we need to focus on the other one.
updatedRoot.querySelector(`[data-action="move"][data-plugin="${actionLink.dataset.plugin}"]`)?.focus();
}
pendingPromise.resolve();
}
}
-113
View File
@@ -1,113 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Allows admin to configure antiviruses.
*
* @package core_antivirus
* @copyright 2015 Ruslan Kabalin, Lancaster University.
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php');
$action = required_param('action', PARAM_ALPHANUMEXT);
$antivirus = required_param('antivirus', PARAM_PLUGIN);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$PAGE->set_url('/admin/antiviruses.php', array('action' => $action, 'antivirus' => $antivirus));
$PAGE->set_context(context_system::instance());
require_admin();
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=manageantiviruses";
// Get currently installed and enabled antivirus plugins.
$availableantiviruses = \core\antivirus\manager::get_available();
if (!empty($antivirus) and empty($availableantiviruses[$antivirus])) {
redirect ($returnurl);
}
$activeantiviruses = explode(',', $CFG->antiviruses);
foreach ($activeantiviruses as $key => $active) {
if (empty($availableantiviruses[$active])) {
unset($activeantiviruses[$key]);
}
}
if (!confirm_sesskey()) {
redirect($returnurl);
}
$needsupdate = false;
switch ($action) {
case 'disable':
// Remove from enabled list.
$class = \core_plugin_manager::resolve_plugininfo_class('antivirus');
$class::enable_plugin($antivirus, false);
break;
case 'enable':
// Add to enabled list.
if (!in_array($antivirus, $activeantiviruses)) {
$class = \core_plugin_manager::resolve_plugininfo_class('antivirus');
$class::enable_plugin($antivirus, true);
}
break;
case 'down':
$key = array_search($antivirus, $activeantiviruses);
// Check auth plugin is valid.
if ($key !== false) {
// Move down the list.
if ($key < (count($activeantiviruses) - 1)) {
$fsave = $activeantiviruses[$key];
$activeantiviruses[$key] = $activeantiviruses[$key + 1];
$activeantiviruses[$key + 1] = $fsave;
$needsupdate = true;
}
}
break;
case 'up':
$key = array_search($antivirus, $activeantiviruses);
// Check auth is valid.
if ($key !== false) {
// Move up the list.
if ($key >= 1) {
$fsave = $activeantiviruses[$key];
$activeantiviruses[$key] = $activeantiviruses[$key - 1];
$activeantiviruses[$key - 1] = $fsave;
$needsupdate = true;
}
}
break;
default:
break;
}
if ($needsupdate) {
$new = implode(',', $activeantiviruses);
add_to_config_log('antiviruses', $CFG->antiviruses, $new, 'core');
set_config('antiviruses', $new);
core_plugin_manager::reset_caches();
}
redirect ($returnurl);
+27 -16
View File
@@ -11,7 +11,8 @@ require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php');
require_admin();
require_login();
require_capability('moodle/site:config', context_system::instance());
$returnurl = new moodle_url('/admin/settings.php', array('section'=>'manageauths'));
@@ -28,7 +29,7 @@ if (empty($CFG->auth)) {
}
if (!empty($auth) and !exists_auth_plugin($auth)) {
throw new \moodle_exception('pluginnotinstalled', 'auth', $returnurl, $auth);
print_error('pluginnotinstalled', 'auth', $returnurl, $auth);
}
////////////////////////////////////////////////////////////////////////////////
@@ -40,31 +41,41 @@ if (!confirm_sesskey()) {
switch ($action) {
case 'disable':
// Remove from enabled list.
$class = \core_plugin_manager::resolve_plugininfo_class('auth');
$class::enable_plugin($auth, false);
// remove from enabled list
$key = array_search($auth, $authsenabled);
if ($key !== false) {
unset($authsenabled[$key]);
set_config('auth', implode(',', $authsenabled));
}
if ($auth == $CFG->registerauth) {
set_config('registerauth', '');
}
session_gc(); // remove stale sessions
break;
case 'enable':
// Add to enabled list.
$class = \core_plugin_manager::resolve_plugininfo_class('auth');
$class::enable_plugin($auth, true);
// add to enabled list
if (!in_array($auth, $authsenabled)) {
$authsenabled[] = $auth;
$authsenabled = array_unique($authsenabled);
set_config('auth', implode(',', $authsenabled));
}
session_gc(); // remove stale sessions
break;
case 'down':
$key = array_search($auth, $authsenabled);
// check auth plugin is valid
if ($key === false) {
throw new \moodle_exception('pluginnotenabled', 'auth', $returnurl, $auth);
print_error('pluginnotenabled', 'auth', $returnurl, $auth);
}
// move down the list
if ($key < (count($authsenabled) - 1)) {
$fsave = $authsenabled[$key];
$authsenabled[$key] = $authsenabled[$key + 1];
$authsenabled[$key + 1] = $fsave;
$value = implode(',', $authsenabled);
add_to_config_log('auth', $CFG->auth, $value, 'core');
set_config('auth', $value);
set_config('auth', implode(',', $authsenabled));
}
break;
@@ -72,16 +83,14 @@ switch ($action) {
$key = array_search($auth, $authsenabled);
// check auth is valid
if ($key === false) {
throw new \moodle_exception('pluginnotenabled', 'auth', $returnurl, $auth);
print_error('pluginnotenabled', 'auth', $returnurl, $auth);
}
// move up the list
if ($key >= 1) {
$fsave = $authsenabled[$key];
$authsenabled[$key] = $authsenabled[$key - 1];
$authsenabled[$key - 1] = $fsave;
$value = implode(',', $authsenabled);
add_to_config_log('auth', $CFG->auth, $value, 'core');
set_config('auth', $value);
set_config('auth', implode(',', $authsenabled));
}
break;
@@ -90,3 +99,5 @@ switch ($action) {
}
redirect($returnurl);
+179
View File
@@ -0,0 +1,179 @@
<?php
/**
* Edit configuration for an individual auth plugin
*/
require_once '../config.php';
require_once $CFG->libdir.'/adminlib.php';
$auth = required_param('auth', PARAM_PLUGIN);
$PAGE->set_pagetype('admin-auth-' . $auth);
admin_externalpage_setup('authsetting'.$auth);
$authplugin = get_auth_plugin($auth);
$err = array();
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=manageauths";
// save configuration changes
if ($frm = data_submitted() and confirm_sesskey()) {
$authplugin->validate_form($frm, $err);
if (count($err) == 0) {
// save plugin config
if ($authplugin->process_config($frm)) {
// save field lock configuration
foreach ($frm as $name => $value) {
if (preg_match('/^lockconfig_(.+?)$/', $name, $matches)) {
$plugin = "auth/$auth";
$name = $matches[1];
set_config($name, $value, $plugin);
}
}
redirect($returnurl);
exit;
}
} else {
foreach ($err as $key => $value) {
$focus = "form.$key";
}
}
} else {
$frmlegacystyle = get_config('auth/'.$auth);
$frmnewstyle = get_config('auth_'.$auth);
$frm = (object)array_merge((array)$frmlegacystyle, (array)$frmnewstyle);
}
$user_fields = $authplugin->userfields;
//$user_fields = array("firstname", "lastname", "email", "phone1", "phone2", "institution", "department", "address", "city", "country", "description", "idnumber", "lang");
/// Get the auth title (from core or own auth lang files)
$authtitle = $authplugin->get_title();
/// Get the auth descriptions (from core or own auth lang files)
$authdescription = $authplugin->get_description();
// output configuration form
echo $OUTPUT->header();
// choose an authentication method
echo "<form id=\"authmenu\" method=\"post\" action=\"auth_config.php\">\n";
echo "<div>\n";
echo "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />\n";
echo "<input type=\"hidden\" name=\"auth\" value=\"".$auth."\" />\n";
// auth plugin description
echo $OUTPUT->box_start();
echo $OUTPUT->heading($authtitle);
echo $OUTPUT->box_start('informationbox');
echo $authdescription;
echo $OUTPUT->box_end();
echo "<hr />\n";
$authplugin->config_form($frm, $err, $user_fields);
echo $OUTPUT->box_end();
echo '<p style="text-align: center"><input type="submit" value="' . get_string("savechanges") . "\" /></p>\n";
echo "</div>\n";
echo "</form>\n";
echo $OUTPUT->footer();
exit;
/// Functions /////////////////////////////////////////////////////////////////
// Good enough for most auth plugins
// but some may want a custom one if they are offering
// other options
// Note: lockconfig_ fields have special handling.
function print_auth_lock_options ($auth, $user_fields, $helptext, $retrieveopts, $updateopts) {
global $OUTPUT;
echo '<tr><td colspan="3">';
if ($retrieveopts) {
echo $OUTPUT->heading(get_string('auth_data_mapping', 'auth'));
} else {
echo $OUTPUT->heading(get_string('auth_fieldlocks', 'auth'));
}
echo '</td></tr>';
$lockoptions = array ('unlocked' => get_string('unlocked', 'auth'),
'unlockedifempty' => get_string('unlockedifempty', 'auth'),
'locked' => get_string('locked', 'auth'));
$updatelocaloptions = array('oncreate' => get_string('update_oncreate', 'auth'),
'onlogin' => get_string('update_onlogin', 'auth'));
$updateextoptions = array('0' => get_string('update_never', 'auth'),
'1' => get_string('update_onupdate', 'auth'));
$pluginconfig = get_config("auth/$auth");
// helptext is on a field with rowspan
if (empty($helptext)) {
$helptext = '&nbsp;';
}
foreach ($user_fields as $field) {
// Define some vars we'll work with
if (!isset($pluginconfig->{"field_map_$field"})) {
$pluginconfig->{"field_map_$field"} = '';
}
if (!isset($pluginconfig->{"field_updatelocal_$field"})) {
$pluginconfig->{"field_updatelocal_$field"} = '';
}
if (!isset($pluginconfig->{"field_updateremote_$field"})) {
$pluginconfig->{"field_updateremote_$field"} = '';
}
if (!isset($pluginconfig->{"field_lock_$field"})) {
$pluginconfig->{"field_lock_$field"} = '';
}
// define the fieldname we display to the user
$fieldname = $field;
if ($fieldname === 'lang') {
$fieldname = get_string('language');
} elseif (preg_match('/^(.+?)(\d+)$/', $fieldname, $matches)) {
$fieldname = get_string($matches[1]) . ' ' . $matches[2];
} elseif ($fieldname == 'url') {
$fieldname = get_string('webpage');
} else {
$fieldname = get_string($fieldname);
}
if ($retrieveopts) {
$varname = 'field_map_' . $field;
echo '<tr valign="top"><td align="right">';
echo '<label for="lockconfig_'.$varname.'">'.$fieldname.'</label>';
echo '</td><td>';
echo "<input id=\"lockconfig_{$varname}\" name=\"lockconfig_{$varname}\" type=\"text\" size=\"30\" value=\"{$pluginconfig->$varname}\" />";
echo '<div style="text-align: right">';
echo '<label for="menulockconfig_field_updatelocal_'.$field.'">'.get_string('auth_updatelocal', 'auth') . '</label>&nbsp;';
echo html_writer::select($updatelocaloptions, "lockconfig_field_updatelocal_{$field}", $pluginconfig->{"field_updatelocal_$field"}, false);
echo '<br />';
if ($updateopts) {
echo '<label for="menulockconfig_field_updateremote_'.$field.'">'.get_string('auth_updateremote', 'auth') . '</label>&nbsp;';
echo html_writer::select($updateextoptions, "lockconfig_field_updateremote_{$field}", $pluginconfig->{"field_updateremote_$field"}, false);
echo '<br />';
}
echo '<label for="menulockconfig_field_lock_'.$field.'">'.get_string('auth_fieldlock', 'auth') . '</label>&nbsp;';
echo html_writer::select($lockoptions, "lockconfig_field_lock_{$field}", $pluginconfig->{"field_lock_$field"}, false);
echo '</div>';
} else {
echo '<tr valign="top"><td align="right">';
echo '<label for="menulockconfig_field_lock_'.$field.'">'.$fieldname.'</label>';
echo '</td><td>';
echo html_writer::select($lockoptions, "lockconfig_field_lock_{$field}", $pluginconfig->{"field_lock_$field"}, false);
}
echo '</td>';
if (!empty($helptext)) {
echo '<td rowspan="' . count($user_fields) . '">' . $helptext . '</td>';
$helptext = '';
}
echo '</tr>';
}
}
+76
View File
@@ -0,0 +1,76 @@
<?php
// block.php - allows admin to edit all local configuration variables for a block
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
$blockid = required_param('block', PARAM_INT);
if(!$blockrecord = blocks_get_record($blockid)) {
print_error('blockdoesnotexist', 'error');
}
admin_externalpage_setup('blocksetting'.$blockrecord->name);
$block = block_instance($blockrecord->name);
if($block === false) {
print_error('blockcannotinistantiate', 'error');
}
// Define the data we're going to silently include in the instance config form here,
// so we can strip them from the submitted data BEFORE handling it.
$hiddendata = array(
'block' => $blockid,
'sesskey' => sesskey()
);
/// If data submitted, then process and store.
if ($config = data_submitted()) {
if (!confirm_sesskey()) {
print_error('confirmsesskeybad', 'error');
}
if(!$block->has_config()) {
print_error('blockcannotconfig', 'error');
}
$remove = array_keys($hiddendata);
foreach($remove as $item) {
unset($config->$item);
}
$block->config_save($config);
redirect("$CFG->wwwroot/$CFG->admin/blocks.php", get_string("changessaved"), 1);
exit;
}
/// Otherwise print the form.
$strmanageblocks = get_string('manageblocks');
$strblockname = $block->get_title();
echo $OUTPUT->header();
echo $OUTPUT->heading($strblockname);
echo $OUTPUT->notification('This block still uses an old-style config_global.html file. ' .
'It must be updated by a developer to use a settings.php file.');
echo $OUTPUT->box(get_string('configwarning', 'admin'), 'generalbox boxwidthnormal boxaligncenter');
echo '<br />';
echo '<form method="post" action="block.php">';
echo '<p>';
foreach($hiddendata as $name => $val) {
echo '<input type="hidden" name="'. $name .'" value="'. $val .'" />';
}
echo '</p>';
echo $OUTPUT->box_start();
include($CFG->dirroot.'/blocks/'. $block->name() .'/config_global.html');
echo $OUTPUT->box_end();
echo '</form>';
echo $OUTPUT->footer();
+251 -79
View File
@@ -1,94 +1,266 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Allows the admin to configure blocks (hide/show, uninstall and configure)
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// Allows the admin to configure blocks (hide/show, delete and configure)
require_once('../config.php');
require_once("{$CFG->libdir}/adminlib.php");
require_once("{$CFG->libdir}/blocklib.php");
require_once("{$CFG->libdir}/tablelib.php");
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php');
admin_externalpage_setup('manageblocks');
admin_externalpage_setup('manageblocks');
$plugin = optional_param('plugin', '', PARAM_PLUGIN);
$action = optional_param('action', '', PARAM_ALPHA);
$unprotect = optional_param('unprotect', 0, PARAM_PLUGIN);
$protect = optional_param('protect', 0, PARAM_PLUGIN);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$hide = optional_param('hide', 0, PARAM_INT);
$show = optional_param('show', 0, PARAM_INT);
$delete = optional_param('delete', 0, PARAM_INT);
$unprotect = optional_param('unprotect', 0, PARAM_INT);
$protect = optional_param('protect', 0, PARAM_INT);
$strmanageblocks = get_string('manageblocks');
/// Print headings
// If data submitted, then process and store.
if (!empty($plugin) && !empty($action) && confirm_sesskey()) {
$manager = \core_plugin_manager::resolve_plugininfo_class('block');
$pluginname = get_string('pluginname', "block_{$plugin}");
$strmanageblocks = get_string('manageblocks');
$strdelete = get_string('delete');
$strversion = get_string('version');
$strhide = get_string('hide');
$strshow = get_string('show');
$strsettings = get_string('settings');
$strcourses = get_string('blockinstances', 'admin');
$strname = get_string('name');
$strshowblockcourse = get_string('showblockcourse');
$strprotecthdr = get_string('blockprotect', 'admin'). $OUTPUT->help_icon('blockprotect','admin');
$strprotect = get_string('blockprotect', 'admin');
$strunprotect = get_string('blockunprotect', 'admin');
if ($action === 'disable' && $manager::enable_plugin($plugin, 0)) {
\core\notification::add(
get_string('plugin_disabled', 'core_admin', $pluginname),
\core\notification::SUCCESS
);
// Settings not required - only pages.
admin_get_root(true, false);
} else if ($action === 'enable' && $manager::enable_plugin($plugin, 1)) {
\core\notification::add(
get_string('plugin_enabled', 'core_admin', $pluginname),
\core\notification::SUCCESS
);
/// If data submitted, then process and store.
// Settings not required - only pages.
admin_get_root(true, false);
if (!empty($hide) && confirm_sesskey()) {
if (!$block = $DB->get_record('block', array('id'=>$hide))) {
print_error('blockdoesnotexist', 'error');
}
$DB->set_field('block', 'visible', '0', array('id'=>$block->id)); // Hide block
admin_get_root(true, false); // settings not required - only pages
}
// Redirect back to the page with out any params.
redirect(new moodle_url('/admin/blocks.php'));
}
if (!empty($show) && confirm_sesskey() ) {
if (!$block = $DB->get_record('block', array('id'=>$show))) {
print_error('blockdoesnotexist', 'error');
}
$DB->set_field('block', 'visible', '1', array('id'=>$block->id)); // Show block
admin_get_root(true, false); // settings not required - only pages
}
if (!empty($protect) && confirm_sesskey()) {
block_manager::protect_block($protect);
$pluginname = get_string('pluginname', "block_{$protect}");
\core\notification::add(
get_string('blockprotected', 'core_admin', $pluginname),
\core\notification::SUCCESS
);
// Settings not required - only pages.
admin_get_root(true, false);
}
if (!isset($CFG->undeletableblocktypes) || (!is_array($CFG->undeletableblocktypes) && !is_string($CFG->undeletableblocktypes))) {
$undeletableblocktypes = array('navigation', 'settings');
} else if (is_string($CFG->undeletableblocktypes)) {
$undeletableblocktypes = explode(',', $CFG->undeletableblocktypes);
} else {
$undeletableblocktypes = $CFG->undeletableblocktypes;
}
if (!empty($unprotect) && confirm_sesskey()) {
block_manager::unprotect_block($unprotect);
$pluginname = get_string('pluginname', "block_{$unprotect}");
\core\notification::add(
get_string('blockunprotected', 'core_admin', $pluginname),
\core\notification::SUCCESS
);
// Settings not required - only pages.
admin_get_root(true, false);
}
if (!empty($protect) && confirm_sesskey()) {
if (!$block = $DB->get_record('block', array('id'=>$protect))) {
print_error('blockdoesnotexist', 'error');
}
if (!in_array($block->name, $undeletableblocktypes)) {
$undeletableblocktypes[] = $block->name;
set_config('undeletableblocktypes', implode(',', $undeletableblocktypes));
}
admin_get_root(true, false); // settings not required - only pages
}
if (!empty($unprotect) && confirm_sesskey()) {
if (!$block = $DB->get_record('block', array('id'=>$unprotect))) {
print_error('blockdoesnotexist', 'error');
}
if (in_array($block->name, $undeletableblocktypes)) {
$undeletableblocktypes = array_diff($undeletableblocktypes, array($block->name));
set_config('undeletableblocktypes', implode(',', $undeletableblocktypes));
}
admin_get_root(true, false); // settings not required - only pages
}
if (!empty($delete) && confirm_sesskey()) {
echo $OUTPUT->header();
echo $OUTPUT->heading($strmanageblocks);
if (!$block = blocks_get_record($delete)) {
print_error('blockdoesnotexist', 'error');
}
if (get_string_manager()->string_exists('pluginname', "block_$block->name")) {
$strblockname = get_string('pluginname', "block_$block->name");
} else {
$strblockname = $block->name;
}
if (!$confirm) {
echo $OUTPUT->confirm(get_string('blockdeleteconfirm', '', $strblockname), 'blocks.php?delete='.$block->id.'&confirm=1', 'blocks.php');
echo $OUTPUT->footer();
exit;
} else {
uninstall_plugin('block', $block->name);
$a = new stdClass();
$a->block = $strblockname;
$a->directory = $CFG->dirroot.'/blocks/'.$block->name;
notice(get_string('blockdeletefiles', '', $a), 'blocks.php');
}
}
echo $OUTPUT->header();
echo $OUTPUT->heading($strmanageblocks);
/// Main display starts here
/// Get and sort the existing blocks
if (!$blocks = $DB->get_records('block', array(), 'name ASC')) {
print_error('noblocks', 'error'); // Should never happen
}
$incompatible = array();
/// Print the table of all blocks
$table = new flexible_table('admin-blocks-compatible');
$table->define_columns(array('name', 'instances', 'version', 'hideshow', 'undeletable', 'delete', 'settings'));
$table->define_headers(array($strname, $strcourses, $strversion, $strhide.'/'.$strshow, $strprotecthdr, $strdelete, $strsettings));
$table->define_baseurl($CFG->wwwroot.'/'.$CFG->admin.'/blocks.php');
$table->set_attribute('class', 'compatibleblockstable blockstable generaltable');
$table->setup();
$tablerows = array();
// Sort blocks using current locale.
$blocknames = array();
foreach ($blocks as $blockid=>$block) {
$blockname = $block->name;
if (file_exists("$CFG->dirroot/blocks/$blockname/block_$blockname.php")) {
$blocknames[$blockid] = get_string('pluginname', 'block_'.$blockname);
} else {
$blocknames[$blockid] = $blockname;
}
}
collatorlib::asort($blocknames);
foreach ($blocknames as $blockid=>$strblockname) {
$block = $blocks[$blockid];
$blockname = $block->name;
if (!file_exists("$CFG->dirroot/blocks/$blockname/block_$blockname.php")) {
$blockobject = false;
$strblockname = '<span class="notifyproblem">'.$strblockname.' ('.get_string('missingfromdisk').')</span>';
$plugin = new stdClass();
$plugin->version = $block->version;
} else {
$plugin = new stdClass();
$plugin->version = '???';
if (file_exists("$CFG->dirroot/blocks/$blockname/version.php")) {
include("$CFG->dirroot/blocks/$blockname/version.php");
}
if (!$blockobject = block_instance($block->name)) {
$incompatible[] = $block;
continue;
}
}
$delete = '<a href="blocks.php?delete='.$blockid.'&amp;sesskey='.sesskey().'">'.$strdelete.'</a>';
$settings = ''; // By default, no configuration
if ($blockobject and $blockobject->has_config()) {
$blocksettings = admin_get_root()->locate('blocksetting' . $block->name);
if ($blocksettings instanceof admin_externalpage) {
$settings = '<a href="' . $blocksettings->url . '">' . get_string('settings') . '</a>';
} else if ($blocksettings instanceof admin_settingpage) {
$settings = '<a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section=blocksetting'.$block->name.'">'.$strsettings.'</a>';
} else {
$settings = '<a href="block.php?block='.$blockid.'">'.$strsettings.'</a>';
}
}
// MDL-11167, blocks can be placed on mymoodle, or the blogs page
// and it should not show up on course search page
$totalcount = $DB->count_records('block_instances', array('blockname'=>$blockname));
$count = $DB->count_records('block_instances', array('blockname'=>$blockname, 'pagetypepattern'=>'course-view-*'));
if ($count>0) {
$blocklist = "<a href=\"{$CFG->wwwroot}/course/search.php?blocklist=$blockid&amp;sesskey=".sesskey()."\" ";
$blocklist .= "title=\"$strshowblockcourse\" >$totalcount</a>";
}
else {
$blocklist = "$totalcount";
}
$class = ''; // Nothing fancy, by default
if (!$blockobject) {
// ignore
$visible = '';
} else if ($blocks[$blockid]->visible) {
$visible = '<a href="blocks.php?hide='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strhide.'">'.
'<img src="'.$OUTPUT->pix_url('t/hide') . '" class="iconsmall" alt="'.$strhide.'" /></a>';
} else {
$visible = '<a href="blocks.php?show='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strshow.'">'.
'<img src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" alt="'.$strshow.'" /></a>';
$class = ' class="dimmed_text"'; // Leading space required!
}
if ($block->version == $plugin->version) {
$version = $block->version;
} else {
$version = "$block->version ($plugin->version)";
}
if (!$blockobject) {
// ignore
$undeletable = '';
} else if (in_array($blockname, $undeletableblocktypes)) {
$undeletable = '<a href="blocks.php?unprotect='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strunprotect.'">'.
'<img src="'.$OUTPUT->pix_url('t/unlock') . '" class="iconsmall" alt="'.$strunprotect.'" /></a>';
} else {
$undeletable = '<a href="blocks.php?protect='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strprotect.'">'.
'<img src="'.$OUTPUT->pix_url('t/lock') . '" class="iconsmall" alt="'.$strprotect.'" /></a>';
}
$row = array(
'<span'.$class.'>'.$strblockname.'</span>',
$blocklist,
'<span'.$class.'>'.$version.'</span>',
$visible,
$undeletable,
$delete,
$settings
);
$table->add_data($row);
}
$table->print_html();
if (!empty($incompatible)) {
echo $OUTPUT->heading(get_string('incompatibleblocks', 'blockstable', 'admin'));
$table = new flexible_table('admin-blocks-incompatible');
$table->define_columns(array('block', 'delete'));
$table->define_headers(array($strname, $strdelete));
$table->define_baseurl($CFG->wwwroot.'/'.$CFG->admin.'/blocks.php');
$table->set_attribute('class', 'incompatibleblockstable generaltable');
$table->setup();
foreach ($incompatible as $block) {
$table->add_data(array(
$block->name,
'<a href="blocks.php?delete='.$block->id.'&amp;sesskey='.sesskey().'">'.$strdelete.'</a>',
));
}
$table->print_html();
}
echo $OUTPUT->footer();
echo $OUTPUT->header();
echo $OUTPUT->heading($strmanageblocks);
echo $OUTPUT->notification(get_string('noteunneededblocks', 'admin'), 'info', false);
// Print the table of all blocks.
$table = new \core_admin\table\block_management_table();
$table->out();
echo $OUTPUT->footer();
+44 -48
View File
@@ -17,7 +17,7 @@
/**
* This file is used to display a categories sub categories, external pages, and settings.
*
* @since Moodle 2.3
* @since 2.3
* @package admin
* @copyright 2011 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -30,6 +30,7 @@ $category = required_param('category', PARAM_SAFEDIR);
$return = optional_param('return','', PARAM_ALPHA);
$adminediting = optional_param('adminedit', -1, PARAM_BOOL);
/// no guest autologin
require_login(0, false);
$PAGE->set_context(context_system::instance());
$PAGE->set_url('/admin/category.php', array('category' => $category));
@@ -41,47 +42,40 @@ $adminroot = admin_get_root(); // need all settings
$settingspage = $adminroot->locate($category, true);
if (empty($settingspage) or !($settingspage instanceof admin_category)) {
throw new \moodle_exception('categoryerror', 'error', "$CFG->wwwroot/$CFG->admin/");
print_error('categoryerror', 'admin', "$CFG->wwwroot/$CFG->admin/");
}
if (!($settingspage->check_access())) {
throw new \moodle_exception('accessdenied', 'admin');
print_error('accessdenied', 'admin');
}
$hassiteconfig = has_capability('moodle/site:config', $PAGE->context);
if ($hassiteconfig) {
$PAGE->add_header_action($OUTPUT->render_from_template('core_admin/header_search_input', [
'action' => new moodle_url('/admin/search.php'),
]));
}
$statusmsg = '';
$errormsg = '';
if ($data = data_submitted() and confirm_sesskey()) {
$count = admin_write_settings($data);
if (admin_write_settings($data)) {
$statusmsg = get_string('changessaved');
}
if (empty($adminroot->errors)) {
// No errors. Did we change any setting? If so, then indicate success.
if ($count) {
$statusmsg = get_string('changessaved');
} else {
switch ($return) {
case 'site': redirect("$CFG->wwwroot/");
case 'admin': redirect("$CFG->wwwroot/$CFG->admin/");
}
switch ($return) {
case 'site': redirect("$CFG->wwwroot/");
case 'admin': redirect("$CFG->wwwroot/$CFG->admin/");
}
} else {
$errormsg = get_string('errorwithsettings', 'admin');
$firsterror = reset($adminroot->errors);
}
$adminroot = admin_get_root(true); //reload tree
$settingspage = $adminroot->locate($category, true);
}
if ($PAGE->user_allowed_editing() && $adminediting != -1) {
$USER->editing = $adminediting;
}
$buttons = null;
if ($PAGE->user_allowed_editing() && !$PAGE->theme->haseditswitch) {
if ($PAGE->user_allowed_editing()) {
$url = clone($PAGE->url);
if ($PAGE->user_is_editing()) {
$caption = get_string('blockseditoff');
@@ -96,47 +90,46 @@ if ($PAGE->user_allowed_editing() && !$PAGE->theme->haseditswitch) {
$savebutton = false;
$outputhtml = '';
foreach ($settingspage->children as $childpage) {
if ($childpage->is_hidden() || !$childpage->check_access()) {
if ($childpage->is_hidden()) {
continue;
}
if ($childpage instanceof admin_externalpage) {
$outputhtml .= $OUTPUT->heading(html_writer::link($childpage->url, $childpage->visiblename), 3);
} else if ($childpage instanceof admin_settingpage) {
$outputhtml .= $OUTPUT->heading(html_writer::link(new moodle_url('/'.$CFG->admin.'/settings.php', array('section' => $childpage->name)), $childpage->visiblename), 3);
// If its a settings page and has settings lets display them.
if (!empty($childpage->settings)) {
$outputhtml .= html_writer::start_tag('fieldset', array('class' => 'adminsettings'));
foreach ($childpage->settings as $setting) {
if (empty($setting->nosave)) {
$savebutton = true;
}
$fullname = $setting->get_full_name();
if (array_key_exists($fullname, $adminroot->errors)) {
$data = $adminroot->errors[$fullname]->data;
} else {
$data = $setting->get_setting();
}
$outputhtml .= html_writer::tag('div', '<!-- -->', array('class' => 'clearer'));
$outputhtml .= $setting->output_html($data);
}
$outputhtml .= html_writer::end_tag('fieldset');
}
} else if ($childpage instanceof admin_category) {
$outputhtml .= $OUTPUT->heading(html_writer::link(new moodle_url('/'.$CFG->admin.'/category.php', array('category' => $childpage->name)), get_string('admincategory', 'admin', $childpage->visiblename)), 3);
} else {
continue;
}
if (!empty($childpage->settings)) {
$outputhtml .= html_writer::start_tag('fieldset', array('class' => 'adminsettings'));
foreach ($childpage->settings as $setting) {
if (empty($setting->nosave)) {
$savebutton = true;
}
$fullname = $setting->get_full_name();
if (array_key_exists($fullname, $adminroot->errors)) {
$data = $adminroot->errors[$fullname]->data;
} else {
$data = $setting->get_setting();
}
$outputhtml .= html_writer::tag('div', '<!-- -->', array('class' => 'clearer'));
$outputhtml .= $setting->output_html($data);
}
$outputhtml .= html_writer::end_tag('fieldset');
}
}
if ($savebutton) {
$outputhtml .= html_writer::start_tag('div', array('class' => 'form-buttons'));
$outputhtml .= html_writer::empty_tag('input', array('class' => 'btn btn-primary form-submit', 'type' => 'submit', 'value' => get_string('savechanges','admin')));
$outputhtml .= html_writer::empty_tag('input', array('class' => 'form-submit', 'type' => 'submit', 'value' => get_string('savechanges','admin')));
$outputhtml .= html_writer::end_tag('div');
}
$visiblepathtosection = array_reverse($settingspage->visiblepath);
$PAGE->set_title("$SITE->shortname: " . implode(": ",$visiblepathtosection));
$PAGE->set_heading($SITE->fullname);
if ($buttons) {
$PAGE->set_button($buttons);
}
$PAGE->set_button($buttons);
echo $OUTPUT->header();
@@ -146,7 +139,13 @@ if ($errormsg !== '') {
echo $OUTPUT->notification($statusmsg, 'notifysuccess');
}
echo $OUTPUT->heading(get_string('admincategory', 'admin', $settingspage->visiblename), 2);
$path = array_reverse($settingspage->visiblepath);
if (is_array($path)) {
$visiblename = join(' / ', $path);
} else {
$visiblename = $path;
}
echo $OUTPUT->heading(get_string('admincategory', 'admin', $visiblename), 2);
echo html_writer::start_tag('form', array('action' => '', 'method' => 'post', 'id' => 'adminsettings'));
echo html_writer::start_tag('div');
@@ -158,7 +157,4 @@ echo $outputhtml;
echo html_writer::end_tag('fieldset');
echo html_writer::end_tag('form');
// Add the form change checker.
$PAGE->requires->js_call_amd('core_form/changechecker', 'watchFormById', ['adminsettings']);
echo $OUTPUT->footer();
echo $OUTPUT->footer();
@@ -1,127 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\admin;
use admin_setting;
use core_plugin_manager;
use core_text;
/**
* Admin setting plugin manager.
*
* @package core_admin
* @subpackage admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class admin_setting_plugin_manager extends admin_setting {
/** @var core_plugin_manager The plugin manager instance */
protected core_plugin_manager $pluginmanager;
/** @var string The plugintype that this manager covers */
protected string $plugintype;
/** @var string The class of the management table to use */
protected string $tableclass;
public function __construct(
string $plugintype,
string $tableclass,
string $name,
string $visiblename,
string $description = '',
string $defaultsetting = '',
) {
$this->nosave = true;
$this->pluginmanager = core_plugin_manager::instance();
$this->plugintype = $plugintype;
$this->tableclass = $tableclass;
parent::__construct($name, $visiblename, $description, $defaultsetting);
}
/**
* Always returns true, does nothing
*
* @return true
*/
public function get_setting(): bool {
return true;
}
/**
* Always returns true, does nothing
*
* @return true
*/
public function get_defaultsetting(): bool {
return true;
}
/**
* Always returns '', does not write anything
*
* @return string Always returns ''
*/
// phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
public function write_setting($data): string {
// Do not write any setting.
return '';
}
/**
* Checks if $query is one of the available editors
*
* @param string $query The string to search for
* @return bool Returns true if found, false if not
*/
public function is_related($query) {
if (parent::is_related($query)) {
return true;
}
$plugins = $this->pluginmanager->get_installed_plugins($this->plugintype);
foreach (array_keys($plugins) as $plugin) {
$plugin = "{$this->plugintype}_{$plugin}";
if (str_contains($plugin, $query)) {
return true;
}
$pluginname = get_string('pluginname', $plugin);
if (strpos(core_text::strtolower($pluginname), $query) !== false) {
return true;
}
}
return false;
}
/**
* Builds the XHTML to display the control
*
* @param string $data Unused
* @param string $query
* @return string
*/
public function output_html($data, $query = ''): string {
$table = new $this->tableclass();
if (!($table instanceof \core_admin\table\plugin_management_table)) {
throw new \coding_exception("{$this->tableclass} must be an instance of \\core_admin\\table\\plugin_management_table");
}
return highlight($query, $table->get_content());
}
}
-97
View File
@@ -1,97 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\external;
use block_manager;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
/**
* Web Service to control the state of a plugin.
*
* @package core_admin
* @category external
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class set_block_protection extends external_api {
/**
* Returns description of method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'plugin' => new external_value(PARAM_PLUGIN, 'The name of the plugin', VALUE_REQUIRED),
'state' => new external_value(PARAM_INT, 'The target state', VALUE_REQUIRED),
]);
}
/**
* Set the block protection state.
*
* @param string $plugin The name of the plugin
* @param int $state The target state
* @return null
*/
public static function execute(
string $plugin,
int $state,
): array {
[
'plugin' => $plugin,
'state' => $state,
] = self::validate_parameters(self::execute_parameters(), [
'plugin' => $plugin,
'state' => $state,
]);
$context = \context_system::instance();
self::validate_context($context);
require_capability('moodle/site:config', $context);
[, $pluginname] = explode('_', \core_component::normalize_componentname($plugin), 2);
$displayname = get_string('pluginname', $plugin);
if ($state) {
block_manager::protect_block($pluginname);
\core\notification::add(
get_string('blockprotected', 'core_admin', $displayname),
\core\notification::SUCCESS
);
} else {
block_manager::unprotect_block($pluginname);
\core\notification::add(
get_string('blockunprotected', 'core_admin', $displayname),
\core\notification::SUCCESS
);
}
return [];
}
/**
* Describe the return structure of the external service.
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([]);
}
}
-84
View File
@@ -1,84 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
/**
* Web Service to control the order of a plugin.
*
* @package core_admin
* @category external
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class set_plugin_order extends external_api {
/**
* Returns description of method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'plugin' => new external_value(PARAM_PLUGIN, 'The name of the plugin', VALUE_REQUIRED),
'direction' => new external_value(PARAM_INT, 'The direction to move', VALUE_REQUIRED),
]);
}
/**
* Set the plugin state.
*
* @param string $plugin The name of the plugin
* @param int $direction The direction to move the plugin
* @return array
*/
public static function execute(
string $plugin,
int $direction,
): array {
[
'plugin' => $plugin,
'direction' => $direction,
] = self::validate_parameters(self::execute_parameters(), [
'plugin' => $plugin,
'direction' => $direction,
]);
$context = \context_system::instance();
self::validate_context($context);
require_capability('moodle/site:config', $context);
[$plugintype, $pluginname] = explode('_', \core_component::normalize_componentname($plugin), 2);
$manager = \core_plugin_manager::resolve_plugininfo_class($plugintype);
$manager::change_plugin_order($pluginname, $direction);
return [];
}
/**
* Describe the return structure of the external service.
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([]);
}
}
-98
View File
@@ -1,98 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\external;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_single_structure;
use core_external\external_value;
/**
* Web Service to control the state of a plugin.
*
* @package core_admin
* @category external
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class set_plugin_state extends external_api {
/**
* Returns description of method parameters
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'plugin' => new external_value(PARAM_PLUGIN, 'The name of the plugin', VALUE_REQUIRED),
'state' => new external_value(PARAM_INT, 'The target state', VALUE_REQUIRED),
]);
}
/**
* Set the plugin state.
*
* @param string $plugin The name of the plugin
* @param int $state The target state
* @return null
*/
public static function execute(
string $plugin,
int $state,
): array {
[
'plugin' => $plugin,
'state' => $state,
] = self::validate_parameters(self::execute_parameters(), [
'plugin' => $plugin,
'state' => $state,
]);
$context = \context_system::instance();
self::validate_context($context);
require_capability('moodle/site:config', $context);
[$plugintype, $pluginname] = explode('_', \core_component::normalize_componentname($plugin), 2);
$manager = \core_plugin_manager::resolve_plugininfo_class($plugintype);
$displayname = get_string('pluginname', $plugin);
if ($manager::enable_plugin($pluginname, $state)) {
if (!empty($state)) {
\core\notification::add(
get_string('plugin_enabled', 'core_admin', $displayname),
\core\notification::SUCCESS
);
} else {
\core\notification::add(
get_string('plugin_disabled', 'core_admin', $displayname),
\core\notification::SUCCESS
);
}
}
return [];
}
/**
* Describe the return structure of the external service.
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([]);
}
}
-76
View File
@@ -1,76 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Form for selective purging of caches.
*
* @package core
* @copyright 2018 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_admin\form;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
/**
* Form for selecting which caches to purge on admin/purgecaches.php
*
* @package core
* @copyright 2018 The Open University
* @author Mark Johnson <mark.johnson@open.ac.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class purge_caches extends \moodleform {
/**
* Define a "Purge all caches" button, and a fieldset with checkboxes for selectively purging separate caches.
*/
public function definition() {
$mform = $this->_form;
$mform->addElement('hidden', 'returnurl', $this->_customdata['returnurl']);
$mform->setType('returnurl', PARAM_LOCALURL);
$mform->addElement('submit', 'all', get_string('purgecaches', 'admin'));
$mform->addElement('header', 'purgecacheheader', get_string('purgeselectedcaches', 'admin'));
$checkboxes = [
$mform->createElement('advcheckbox', 'theme', '', get_string('purgethemecache', 'admin')),
$mform->createElement('advcheckbox', 'lang', '', get_string('purgelangcache', 'admin')),
$mform->createElement('advcheckbox', 'js', '', get_string('purgejscache', 'admin')),
$mform->createElement('advcheckbox', 'template', '', get_string('purgetemplates', 'admin')),
$mform->createElement('advcheckbox', 'filter', '', get_string('purgefiltercache', 'admin')),
$mform->createElement('advcheckbox', 'muc', '', get_string('purgemuc', 'admin')),
$mform->createElement('advcheckbox', 'other', '', get_string('purgeothercaches', 'admin'))
];
$mform->addGroup($checkboxes, 'purgeselectedoptions');
$mform->addElement('submit', 'purgeselectedcaches', get_string('purgeselectedcaches', 'admin'));
}
/**
* If the "Purge selected caches" button was pressed, ensure at least one cache was selected.
*
* @param array $data
* @param array $files
* @return array Error messages
*/
public function validation($data, $files) {
$errors = [];
if (isset($data['purgeselectedcaches']) && empty(array_filter($data['purgeselectedoptions']))) {
$errors['purgeselectedoptions'] = get_string('purgecachesnoneselected', 'admin');
}
return $errors;
}
}
@@ -1,92 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Testing outgoing mail configuration form
*
* @package core
* @copyright 2019 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_admin\form;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
/**
* Test mail form
*
* @package core
* @copyright 2019 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class testoutgoingmailconf_form extends \moodleform {
/**
* Add elements to form
*/
public function definition() {
$mform = $this->_form;
// Recipient.
$options = ['maxlength' => '100', 'size' => '25', 'autocomplete' => 'email'];
$mform->addElement('text', 'recipient', get_string('testoutgoingmailconf_toemail', 'admin'), $options);
$mform->setType('recipient', PARAM_EMAIL);
$mform->addRule('recipient', get_string('required'), 'required');
// From user.
$options = ['maxlength' => '100', 'size' => '25'];
$mform->addElement('text', 'from', get_string('testoutgoingmailconf_fromemail', 'admin'), $options);
$mform->setType('from', PARAM_TEXT);
$mform->addHelpButton('from', 'testoutgoingmailconf_fromemail', 'admin');
// Additional subject text.
$options = ['size' => '25'];
$mform->addElement('text', 'additionalsubject', get_string('testoutgoingmailconf_subjectadditional', 'admin'), $options);
$mform->setType('additionalsubject', PARAM_TEXT);
$buttonarray = array();
$buttonarray[] = $mform->createElement('submit', 'send', get_string('testoutgoingmailconf_sendtest', 'admin'));
$buttonarray[] = $mform->createElement('cancel');
$mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
$mform->closeHeaderBefore('buttonar');
}
/**
* Validate Form field, should be a valid email format or a username that matches with a Moodle user.
*
* @param array $data
* @param array $files
* @return array
* @throws \dml_exception|\coding_exception
*/
public function validation($data, $files): array {
$errors = parent::validation($data, $files);
if (isset($data['from']) && $data['from']) {
$userfrom = \core_user::get_user_by_username($data['from']);
if (!$userfrom && !validate_email($data['from'])) {
$errors['from'] = get_string('testoutgoingmailconf_fromemail_invalid', 'admin');
}
}
return $errors;
}
}
@@ -1,71 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* External admin page class that allows a callback to be provided to determine whether page can be accessed
*
* @package core_admin
* @copyright 2019 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_admin\local\externalpage;
use admin_externalpage;
defined('MOODLE_INTERNAL') || die();
require_once("{$CFG->libdir}/adminlib.php");
/**
* Admin externalpage class
*
* @package core_admin
* @copyright 2019 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class accesscallback extends admin_externalpage {
/** @var callable $accesscheckcallback */
protected $accesscheckcallback;
/**
* Class constructor
*
* @param string $name
* @param string $visiblename
* @param string $url
* @param callable $accesscheckcallback The callback method that will be executed to check whether user has access to
* this page. The setting instance ($this) is passed as an argument to the callback. Should return boolean value
* @param bool $hidden
*/
public function __construct(string $name, string $visiblename, string $url, callable $accesscheckcallback,
bool $hidden = false) {
$this->accesscheckcallback = $accesscheckcallback;
parent::__construct($name, $visiblename, $url, [], $hidden);
}
/**
* Determines if the current user has access to this external page based on access callback
*
* @return bool
*/
public function check_access() {
return ($this->accesscheckcallback)($this);
}
}
@@ -1,206 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Auto complete admin setting.
*
* @package core_admin
* @copyright 2020 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_admin\local\settings;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/adminlib.php');
/**
* Auto complete setting class.
*
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @copyright 2020 The Open University
*/
class autocomplete extends \admin_setting_configmultiselect {
/** @var boolean Should we allow typing new entries to the field? */
protected $tags = false;
/** @var string Name of an AMD module to send/process ajax requests. */
protected $ajax = '';
/** @var string Placeholder text for an empty list. */
protected $placeholder = '';
/** @var bool Whether the search has to be case-sensitive. */
protected $casesensitive = false;
/** @var bool Show suggestions by default - but this can be turned off. */
protected $showsuggestions = true;
/** @var string String that is shown when there are no selections. */
protected $noselectionstring = '';
/** @var string Delimiter to store values in database. */
protected $delimiter = ',';
/** @var string Should be multiple choices? */
protected $multiple = true;
/** @var string The link to manage choices. */
protected $manageurl = true;
/** @var string The text to display in manage link. */
protected $managetext = true;
/**
* Constructor
*
* @param string $name unique ascii name, either 'mysetting' for settings that in config, or 'myplugin/mysetting'
* for ones in config_plugins.
* @param string $visiblename localised
* @param string $description long localised info
* @param array $defaultsetting array of selected items
* @param array $choices options for autocomplete field
* @param array $attributes settings for autocomplete field
*/
public function __construct($name, $visiblename, $description, $defaultsetting, $choices, $attributes = null) {
if ($attributes === null) {
$attributes = [];
}
$this->placeholder = get_string('search');
$this->noselectionstring = get_string('noselection', 'form');
$defaultattributes = [
'tags',
'showsuggestions',
'placeholder',
'noselectionstring',
'ajax',
'casesensitive',
'delimiter',
'multiple',
'manageurl',
'managetext'
];
foreach ($defaultattributes as $attributename) {
if (isset($attributes[$attributename])) {
$this->$attributename = $attributes[$attributename];
}
}
parent::__construct($name, $visiblename, $description, $defaultsetting, $choices);
}
/**
* Returns the select setting(s)
*
* @return mixed null or array. Null if no settings else array of setting(s)
*/
public function get_setting() {
$result = $this->config_read($this->name);
if (is_null($result)) {
return null;
}
if ($result === '') {
return [];
}
return explode($this->delimiter, $result);
}
/**
* Saves setting(s) provided through $data
*
* @param array $data
*/
public function write_setting($data) {
if (!is_array($data)) {
return ''; // Ignore it.
}
if (!$this->load_choices() || empty($this->choices)) {
return '';
}
unset($data['xxxxx']);
$save = [];
foreach ($data as $value) {
if (!array_key_exists($value, $this->choices)) {
continue; // Ignore it.
}
$save[] = $value;
}
return ($this->config_write($this->name, implode($this->delimiter, $save)) ? '' : get_string('errorsetting', 'admin'));
}
/**
* Returns XHTML autocomplete field
*
* @param array $data Array of values to select by default
* @param string $query
* @return string XHTML autocomplete field
*/
public function output_html($data, $query = '') {
global $OUTPUT;
if (!$this->load_choices() or empty($this->choices)) {
return '';
}
$default = $this->get_defaultsetting();
if (empty($default)) {
$default = [];
}
if (is_null($data)) {
$data = [];
}
$context = [
'id' => $this->get_id(),
'name' => $this->get_full_name()
];
$defaults = [];
$options = [];
$template = 'core_admin/local/settings/autocomplete';
foreach ($this->choices as $value => $name) {
if (in_array($value, $default)) {
$defaults[] = $name;
}
$options[] = [
'value' => $value,
'text' => $name,
'selected' => in_array($value, $data),
'disabled' => false
];
}
$context['options'] = $options;
$context['tags'] = $this->tags;
$context['placeholder'] = $this->placeholder;
$context['casesensitive'] = $this->casesensitive;
$context['multiple'] = $this->multiple;
$context['showsuggestions'] = $this->showsuggestions;
$context['manageurl'] = $this->manageurl;
$context['managetext'] = $this->managetext;
if (is_null($default)) {
$defaultinfo = null;
} if (!empty($defaults)) {
$defaultinfo = implode(', ', $defaults);
} else {
$defaultinfo = get_string('none');
}
$element = $OUTPUT->render_from_template($template, $context);
return format_admin_setting($this, $this->visiblename, $element, $this->description, true, '', $defaultinfo, $query);
}
}
-197
View File
@@ -1,197 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* File size admin setting.
*
* @package core_admin
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_admin\local\settings;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/adminlib.php');
/**
* An admin setting to support entering and displaying of file sizes in Bytes, KB, MB or GB.
*
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class filesize extends \admin_setting {
/** @var int The byte unit. Number of bytes in a byte */
const UNIT_B = 1;
/** @var int The kilobyte unit (number of bytes in a kilobyte) */
const UNIT_KB = 1024;
/** @var int The megabyte unit (number of bytes in a megabyte) */
const UNIT_MB = 1048576;
/** @var int The gigabyte unit (number of bytes in a gigabyte) */
const UNIT_GB = 1073741824;
/** @var int default size unit */
protected $defaultunit;
/**
* Constructor
*
* @param string $name unique ascii name, either 'mysetting' for settings that in config,
* or 'myplugin/mysetting' for ones in config_plugins.
* @param string $visiblename localised name
* @param string $description localised long description
* @param int|null $defaultvalue Value of the settings in bytes
* @param int|null $defaultunit GB, MB, etc. (in bytes)
*/
public function __construct(string $name, string $visiblename, string $description,
int $defaultvalue = null, int $defaultunit = null) {
$defaultsetting = self::parse_bytes($defaultvalue);
if ($defaultunit && array_key_exists($defaultunit, self::get_units())) {
$this->defaultunit = $defaultunit;
} else {
$this->defaultunit = self::UNIT_MB;
}
parent::__construct($name, $visiblename, $description, $defaultsetting);
}
/**
* Returns selectable units.
*
* @return array
*/
protected static function get_units(): array {
return [
self::UNIT_GB => get_string('sizegb'),
self::UNIT_MB => get_string('sizemb'),
self::UNIT_KB => get_string('sizekb'),
self::UNIT_B => get_string('sizeb'),
];
}
/**
* Converts bytes to some more user friendly string.
*
* @param int $bytes The number of bytes we want to convert from
* @return string
*/
protected static function get_size_text(int $bytes): string {
if (empty($bytes)) {
return get_string('none');
}
return display_size($bytes, 0);
}
/**
* Finds suitable units for given file size.
*
* @param int $bytes The number of bytes
* @return array Parsed file size in the format of ['v' => value, 'u' => unit]
*/
protected static function parse_bytes(int $bytes): array {
foreach (self::get_units() as $unit => $unused) {
if ($bytes % $unit === 0) {
return ['v' => (int)($bytes / $unit), 'u' => $unit];
}
}
return ['v' => (int)$bytes, 'u' => self::UNIT_B];
}
/**
* Get the selected file size as array.
*
* @return array|null An array containing 'v' => xx, 'u' => xx, or null if not set
*/
public function get_setting(): ?array {
$bytes = $this->config_read($this->name);
if (is_null($bytes)) {
return null;
}
$bytes = intval($bytes);
return self::parse_bytes($bytes);
}
/**
* Store the file size as bytes.
*
* @param array $data Must be form 'h' => xx, 'm' => xx
* @return string The error string if any
*/
public function write_setting($data): string {
if (!is_array($data)) {
return '';
}
if (!is_numeric($data['v']) || $data['v'] < 0) {
return get_string('errorsetting', 'admin');
}
// Calculate size in bytes, ensuring we don't overflow PHP_INT_MAX.
$bytes = $data['v'] * $data['u'];
$result = (is_int($bytes) && $this->config_write($this->name, $bytes));
return ($result ? '' : get_string('errorsetting', 'admin'));
}
/**
* Returns file size text+select fields.
*
* @param array $data The current setting value. Must be form 'v' => xx, 'u' => xx.
* @param string $query Admin search query to be highlighted.
* @return string File size text+select fields and wrapping div(s).
*/
public function output_html($data, $query = ''): string {
global $OUTPUT;
$default = $this->get_defaultsetting();
if (is_number($default)) {
$defaultinfo = self::get_size_text($default);
} else if (is_array($default)) {
$defaultinfo = self::get_size_text($default['v'] * $default['u']);
} else {
$defaultinfo = null;
}
$inputid = $this->get_id() . 'v';
$units = self::get_units();
$defaultunit = $this->defaultunit;
$context = (object) [
'id' => $this->get_id(),
'name' => $this->get_full_name(),
'value' => $data['v'],
'readonly' => $this->is_readonly(),
'options' => array_map(function($unit, $title) use ($data, $defaultunit) {
return [
'value' => $unit,
'name' => $title,
'selected' => ($data['v'] == 0 && $unit == $defaultunit) || $unit == $data['u']
];
}, array_keys($units), $units)
];
$element = $OUTPUT->render_from_template('core_admin/setting_configfilesize', $context);
return format_admin_setting($this, $this->visiblename, $element, $this->description, $inputid, '', $defaultinfo, $query);
}
}
@@ -1,37 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A settings page which can be viewed with a link directly.
*
* @package core_admin
* @copyright 2021 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_admin\local\settings;
use moodle_url;
interface linkable_settings_page {
/**
* Get the URL to view this settings page.
*
* @return moodle_url
*/
public function get_settings_page_url(): moodle_url;
}
@@ -1,74 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Payment gateway admin setting.
*
* @package core_admin
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_admin\local\settings;
/**
* Generic class for managing plugins in a table that allows re-ordering and enable/disable of each plugin.
*/
class manage_payment_gateway_plugins extends \admin_setting_manage_plugins {
/**
* Get the admin settings section title (use get_string).
*
* @return string
*/
public function get_section_title() {
return get_string('type_paygw_plural', 'plugin');
}
/**
* Get the type of plugin to manage.
*
* @return string
*/
public function get_plugin_type() {
return 'paygw';
}
/**
* Get the name of the second column.
*
* @return string
*/
public function get_info_column_name() {
return get_string('supportedcurrencies', 'core_payment');
}
/**
* Get the type of plugin to manage.
*
* @param plugininfo The plugin info class.
* @return string
*/
public function get_info_column($plugininfo) {
$codes = $plugininfo->get_supported_currencies();
$currencies = [];
foreach ($codes as $c) {
$currencies[$c] = new \lang_string($c, 'core_currencies');
}
return implode(get_string('listsep', 'langconfig') . ' ', $currencies);
}
}
@@ -1,121 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Admin setting to show current scheduled task's status.
*
* @package core
* @copyright 2021 Universitat Rovira i Virgili
* @author Jordi Pujol-Ahulló <jpahullo@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_admin\local\settings;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/moodlelib.php');
use admin_setting_description;
use core\task\manager;
use core\task\scheduled_task;
use html_writer;
use lang_string;
use moodle_url;
use stdClass;
/**
* This admin setting tells whether a given scheduled task is enabled, providing a link to its configuration page.
*
* The goal of this setting is to help contextualizing the configuration settings with related scheduled task status,
* providing the big picture of that part of the system.
*
* @package core
* @copyright 2021 Universitat Rovira i Virgili
* @author Jordi Pujol-Ahulló <jpahullo@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class setting_scheduled_task_status extends admin_setting_description {
/**
* @var string fully qualified class name of a scheduled task.
*/
private $classname;
/**
* @var string additional text to append to the description.
*/
private $extradescription;
/**
* setting_scheduled_task_status constructor.
* @param string $name unique setting name.
* @param string $scheduledtaskclassname full classpath class name of the scheduled task.
* @param string $extradescription extra detail to append to the scheduled task status to add context in the setting
* page.
*/
public function __construct(string $name, string $scheduledtaskclassname, string $extradescription = '') {
$visiblename = new lang_string('task_status', 'admin');
$this->classname = $scheduledtaskclassname;
$this->extradescription = $extradescription;
parent::__construct($name, $visiblename, '');
}
/**
* Calculates lazily the content of the description.
* @param mixed $data nothing expected in this case.
* @param string $query nothing expected in this case.
* @return string the HTML content to print for this setting.
*/
public function output_html($data, $query = ''): string {
if (empty($this->description)) {
$this->description = $this->get_task_description();
}
return parent::output_html($data, $query);
}
/**
* Returns the HTML to print as the description.
* @return string description to be printed.
*/
private function get_task_description(): string {
$task = manager::get_scheduled_task($this->classname);
if ($task->is_enabled()) {
$taskenabled = get_string('enabled', 'admin');
} else {
$taskenabled = get_string('disabled', 'admin');
}
$taskenabled = strtolower($taskenabled);
$gotourl = new moodle_url(
'/admin/tool/task/scheduledtasks.php',
[],
scheduled_task::get_html_id($this->classname)
);
if (!empty($this->extradescription)) {
$this->extradescription = '<br />' . $this->extradescription;
}
$taskdetail = new stdClass();
$taskdetail->class = $this->classname;
$taskdetail->name = $task->get_name();
$taskdetail->status = $taskenabled;
$taskdetail->gotourl = $gotourl->out(false);
$taskdetail->extradescription = $this->extradescription;
return html_writer::tag('p', get_string('task_status_desc', 'admin', $taskdetail));
}
}
-41
View File
@@ -1,41 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy Subsystem implementation for core_admin.
*
* @package core_admin
* @copyright 2018 Carlos Escobedo <carlos@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_admin\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for core_admin implementing null_provider.
*
* @copyright 2018 Carlos Escobedo <carlos@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}
@@ -1,117 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
declare(strict_types=1);
namespace core_admin\reportbuilder\datasource;
use core_admin\reportbuilder\local\entities\task_log;
use core_reportbuilder\datasource;
use core_reportbuilder\local\entities\user;
use core_reportbuilder\local\filters\select;
/**
* Task logs datasource
*
* @package core_admin
* @copyright 2022 Paul Holden <paulh@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class task_logs extends datasource {
/**
* Return user friendly name of the report source
*
* @return string
*/
public static function get_name(): string {
return get_string('tasklogs', 'core_admin');
}
/**
* Initialise report
*/
protected function initialise(): void {
$tasklogentity = new task_log();
$tasklogalias = $tasklogentity->get_table_alias('task_log');
$this->set_main_table('task_log', $tasklogalias);
$this->add_entity($tasklogentity);
// Join the user entity to represent the associated user.
$userentity = new user();
$useralias = $userentity->get_table_alias('user');
$this->add_entity($userentity->add_join("
LEFT JOIN {user} {$useralias}
ON {$useralias}.id = {$tasklogalias}.userid")
);
// Add report elements from each of the entities we added to the report.
$this->add_all_from_entities();
}
/**
* Return the columns that will be added to the report upon creation
*
* @return string[]
*/
public function get_default_columns(): array {
return [
'task_log:name',
'task_log:starttime',
'task_log:duration',
'task_log:result',
];
}
/**
* Return the filters that will be added to the report upon creation
*
* @return string[]
*/
public function get_default_filters(): array {
return [
'task_log:timestart',
'task_log:result',
];
}
/**
* Return the conditions that will be added to the report upon creation
*
* @return string[]
*/
public function get_default_conditions(): array {
return [
'task_log:type',
'task_log:timestart',
'task_log:result',
];
}
/**
* Return the condition values that will be set for the report upon creation
*
* @return array
*/
public function get_default_condition_values(): array {
return [
'task_log:type_operator' => select::EQUAL_TO,
'task_log:type_value' => \core\task\database_logger::TYPE_SCHEDULED,
];
}
}
@@ -1,427 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\reportbuilder\local\entities;
use core_reportbuilder\local\filters\date;
use core_reportbuilder\local\filters\duration;
use core_reportbuilder\local\filters\number;
use core_reportbuilder\local\filters\select;
use core_reportbuilder\local\filters\text;
use core_reportbuilder\local\filters\autocomplete;
use core_reportbuilder\local\helpers\format;
use lang_string;
use core_reportbuilder\local\entities\base;
use core_reportbuilder\local\report\column;
use core_reportbuilder\local\report\filter;
use stdClass;
use core_collator;
/**
* Task log entity class implementation
*
* @package core_admin
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class task_log extends base {
/** @var int Result success */
protected const SUCCESS = 0;
/** @var int Result failed */
protected const FAILED = 1;
/**
* Database tables that this entity uses and their default aliases
*
* @return array
*/
protected function get_default_table_aliases(): array {
return ['task_log' => 'tl'];
}
/**
* The default title for this entity in the list of columns/conditions/filters in the report builder
*
* @return lang_string
*/
protected function get_default_entity_title(): lang_string {
return new lang_string('entitytasklog', 'admin');
}
/**
* Initialise the entity
*
* @return base
*/
public function initialise(): base {
$columns = $this->get_all_columns();
foreach ($columns as $column) {
$this->add_column($column);
}
// All the filters defined by the entity can also be used as conditions.
$filters = $this->get_all_filters();
foreach ($filters as $filter) {
$this
->add_filter($filter)
->add_condition($filter);
}
return $this;
}
/**
* Returns list of all available columns
*
* @return column[]
*/
protected function get_all_columns(): array {
global $DB;
$tablealias = $this->get_table_alias('task_log');
// Name column.
$columns[] = (new column(
'name',
new lang_string('name'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("$tablealias.classname")
->set_is_sortable(true)
->add_callback(static function(string $classname): string {
$output = '';
if (class_exists($classname)) {
$task = new $classname;
if ($task instanceof \core\task\task_base) {
$output = $task->get_name();
}
}
$output .= \html_writer::tag('div', "\\{$classname}", [
'class' => 'small text-muted',
]);
return $output;
});
// Component column.
$columns[] = (new column(
'component',
new lang_string('plugin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$tablealias}.component")
->set_is_sortable(true);
// Type column.
$columns[] = (new column(
'type',
new lang_string('tasktype', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("{$tablealias}.type")
->set_is_sortable(true)
->add_callback(static function($value): string {
if (\core\task\database_logger::TYPE_SCHEDULED === (int) $value) {
return get_string('task_type:scheduled', 'admin');
}
return get_string('task_type:adhoc', 'admin');
});
// Start time column.
$columns[] = (new column(
'starttime',
new lang_string('task_starttime', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TIMESTAMP)
->add_field("{$tablealias}.timestart")
->set_is_sortable(true)
->add_callback([format::class, 'userdate'], get_string('strftimedatetimeshortaccurate', 'core_langconfig'));
// End time column.
$columns[] = (new column(
'endtime',
new lang_string('task_endtime', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TIMESTAMP)
->add_field("{$tablealias}.timeend")
->set_is_sortable(true)
->add_callback([format::class, 'userdate'], get_string('strftimedatetimeshortaccurate', 'core_langconfig'));
// Duration column.
$columns[] = (new column(
'duration',
new lang_string('task_duration', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_FLOAT)
->add_field("{$tablealias}.timeend - {$tablealias}.timestart", 'duration')
->set_is_sortable(true)
->add_callback(static function(float $value): string {
$duration = round($value, 2);
if (empty($duration)) {
// The format_time function returns 'now' when the difference is exactly 0.
// Note: format_time performs concatenation in exactly this fashion so we should do this for consistency.
return '0 ' . get_string('secs', 'moodle');
}
return format_time($duration);
});
// Hostname column.
$columns[] = (new column(
'hostname',
new lang_string('hostname', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_TEXT)
->add_field("$tablealias.hostname")
->set_is_sortable(true);
// PID column.
$columns[] = (new column(
'pid',
new lang_string('pid', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_field("{$tablealias}.pid")
->set_is_sortable(true)
// Although this is an integer column, it doesn't make sense to perform numeric aggregation on it.
->set_disabled_aggregation(['avg', 'count', 'countdistinct', 'max', 'min', 'sum']);
// Database column.
$columns[] = (new column(
'database',
new lang_string('task_dbstats', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_fields("{$tablealias}.dbreads, {$tablealias}.dbwrites")
->set_is_sortable(true, ["{$tablealias}.dbreads", "{$tablealias}.dbwrites"])
->add_callback(static function(int $value, stdClass $row): string {
$output = '';
$output .= \html_writer::div(get_string('task_stats:dbreads', 'admin', $row->dbreads));
$output .= \html_writer::div(get_string('task_stats:dbwrites', 'admin', $row->dbwrites));
return $output;
})
// Although this is an integer column, it doesn't make sense to perform numeric aggregation on it.
->set_disabled_aggregation(['avg', 'count', 'countdistinct', 'max', 'min', 'sum']);
// Database reads column.
$columns[] = (new column(
'dbreads',
new lang_string('task_dbreads', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_fields("{$tablealias}.dbreads")
->set_is_sortable(true);
// Database writes column.
$columns[] = (new column(
'dbwrites',
new lang_string('task_dbwrites', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_INTEGER)
->add_fields("{$tablealias}.dbwrites")
->set_is_sortable(true);
// Result column.
$columns[] = (new column(
'result',
new lang_string('task_result', 'admin'),
$this->get_entity_name()
))
->add_joins($this->get_joins())
->set_type(column::TYPE_BOOLEAN)
// For accurate aggregation, we need to return boolean success = true by xor'ing the field value.
->add_field($DB->sql_bitxor("{$tablealias}.result", 1), 'success')
->set_is_sortable(true)
->add_callback(static function(bool $success): string {
if (!$success) {
return get_string('task_result:failed', 'admin');
}
return get_string('success');
});
return $columns;
}
/**
* Return list of all available filters
*
* @return filter[]
*/
protected function get_all_filters(): array {
global $DB;
$tablealias = $this->get_table_alias('task_log');
// Name filter (Filter by classname).
$filters[] = (new filter(
autocomplete::class,
'name',
new lang_string('classname', 'tool_task'),
$this->get_entity_name(),
"{$tablealias}.classname"
))
->add_joins($this->get_joins())
->set_options_callback(static function(): array {
global $DB;
$classnames = $DB->get_fieldset_sql('SELECT DISTINCT classname FROM {task_log} ORDER BY classname ASC');
$options = [];
foreach ($classnames as $classname) {
if (class_exists($classname)) {
$task = new $classname;
$options[$classname] = $task->get_name();
}
}
core_collator::asort($options);
return $options;
});
// Component filter.
$filters[] = (new filter(
text::class,
'component',
new lang_string('plugin'),
$this->get_entity_name(),
"{$tablealias}.component"
))
->add_joins($this->get_joins());
// Type filter.
$filters[] = (new filter(
select::class,
'type',
new lang_string('tasktype', 'admin'),
$this->get_entity_name(),
"{$tablealias}.type"
))
->add_joins($this->get_joins())
->set_options([
\core\task\database_logger::TYPE_ADHOC => new lang_string('task_type:adhoc', 'admin'),
\core\task\database_logger::TYPE_SCHEDULED => new lang_string('task_type:scheduled', 'admin'),
]);
// Output filter (Filter by task output).
$filters[] = (new filter(
text::class,
'output',
new lang_string('task_logoutput', 'admin'),
$this->get_entity_name(),
$DB->sql_cast_to_char("{$tablealias}.output")
))
->add_joins($this->get_joins());
// Start time filter.
$filters[] = (new filter(
date::class,
'timestart',
new lang_string('task_starttime', 'admin'),
$this->get_entity_name(),
"{$tablealias}.timestart"
))
->add_joins($this->get_joins())
->set_limited_operators([
date::DATE_ANY,
date::DATE_RANGE,
date::DATE_PREVIOUS,
date::DATE_CURRENT,
]);
// End time.
$filters[] = (new filter(
date::class,
'timeend',
new lang_string('task_endtime', 'admin'),
$this->get_entity_name(),
"{$tablealias}.timeend"
))
->add_joins($this->get_joins())
->set_limited_operators([
date::DATE_ANY,
date::DATE_RANGE,
date::DATE_PREVIOUS,
date::DATE_CURRENT,
]);
// Duration filter.
$filters[] = (new filter(
duration::class,
'duration',
new lang_string('task_duration', 'admin'),
$this->get_entity_name(),
"{$tablealias}.timeend - {$tablealias}.timestart"
))
->add_joins($this->get_joins());
// Database reads.
$filters[] = (new filter(
number::class,
'dbreads',
new lang_string('task_dbreads', 'admin'),
$this->get_entity_name(),
"{$tablealias}.dbreads"
))
->add_joins($this->get_joins());
// Database writes.
$filters[] = (new filter(
number::class,
'dbwrites',
new lang_string('task_dbwrites', 'admin'),
$this->get_entity_name(),
"{$tablealias}.dbwrites"
))
->add_joins($this->get_joins());
// Result filter.
$filters[] = (new filter(
select::class,
'result',
new lang_string('task_result', 'admin'),
$this->get_entity_name(),
"{$tablealias}.result"
))
->add_joins($this->get_joins())
->set_options([
self::SUCCESS => get_string('success'),
self::FAILED => get_string('task_result:failed', 'admin'),
]);
return $filters;
}
}
@@ -1,159 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\reportbuilder\local\systemreports;
use context_system;
use core_admin\reportbuilder\local\entities\task_log;
use core_reportbuilder\local\entities\user;
use core_reportbuilder\local\report\action;
use lang_string;
use moodle_url;
use pix_icon;
use core_reportbuilder\system_report;
/**
* Task logs system report class implementation
*
* @package core_admin
* @copyright 2021 David Matamoros <davidmc@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class task_logs extends system_report {
/**
* Initialise report, we need to set the main table, load our entities and set columns/filters
*/
protected function initialise(): void {
// Our main entity, it contains all of the column definitions that we need.
$entitymain = new task_log();
$entitymainalias = $entitymain->get_table_alias('task_log');
$this->set_main_table('task_log', $entitymainalias);
$this->add_entity($entitymain);
// Any columns required by actions should be defined here to ensure they're always available.
$this->add_base_fields("{$entitymainalias}.id");
// We can join the "user" entity to our "main" entity and use the fullname column from the user entity.
$entityuser = new user();
$entituseralias = $entityuser->get_table_alias('user');
$this->add_entity($entityuser->add_join(
"LEFT JOIN {user} {$entituseralias} ON {$entituseralias}.id = {$entitymainalias}.userid"
));
// Now we can call our helper methods to add the content we want to include in the report.
$this->add_columns();
$this->add_filters();
$this->add_actions();
// Set if report can be downloaded.
$this->set_downloadable(true, get_string('tasklogs', 'admin'));
}
/**
* Validates access to view this report
*
* @return bool
*/
protected function can_view(): bool {
return has_capability('moodle/site:config', context_system::instance());
}
/**
* Get the visible name of the report
*
* @return string
*/
public static function get_name(): string {
return get_string('entitytasklog', 'admin');
}
/**
* Adds the columns we want to display in the report
*
* They are all provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier
*/
public function add_columns(): void {
$columns = [
'task_log:name',
'task_log:type',
'user:fullname',
'task_log:starttime',
'task_log:duration',
'task_log:hostname',
'task_log:pid',
'task_log:database',
'task_log:result',
];
$this->add_columns_from_entities($columns);
// It's possible to override the display name of a column, if you don't want to use the value provided by the entity.
if ($column = $this->get_column('user:fullname')) {
$column->set_title(new lang_string('user', 'admin'));
}
// It's possible to set a default initial sort direction for one column.
$this->set_initial_sort_column('task_log:starttime', SORT_DESC);
}
/**
* Adds the filters we want to display in the report
*
* They are all provided by the entities we previously added in the {@see initialise} method, referencing each by their
* unique identifier
*/
protected function add_filters(): void {
$filters = [
'task_log:name',
'task_log:type',
'task_log:output',
'task_log:result',
'task_log:timestart',
'task_log:duration',
];
$this->add_filters_from_entities($filters);
}
/**
* Add the system report actions. An extra column will be appended to each row, containing all actions added here
*
* Note the use of ":id" placeholder which will be substituted according to actual values in the row
*/
protected function add_actions(): void {
// Action to view individual task log on a popup window.
$this->add_action((new action(
new moodle_url('/admin/tasklogs.php', ['logid' => ':id']),
new pix_icon('e/search', ''),
[],
true,
new lang_string('view'),
)));
// Action to download individual task log.
$this->add_action((new action(
new moodle_url('/admin/tasklogs.php', ['logid' => ':id', 'download' => true]),
new pix_icon('t/download', ''),
[],
false,
new lang_string('download'),
)));
}
}
@@ -1,118 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\table;
use core_plugin_manager;
use dml_exception;
use html_writer;
use moodle_url;
use stdClass;
/**
* Activity Module admin settings.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class activity_management_table extends plugin_management_table {
public function setup() {
$this->set_attribute('id', 'modules');
$this->set_attribute('class', 'admintable generaltable');
parent::setup();
}
protected function get_table_id(): string {
return 'module-administration-table';
}
protected function get_plugintype(): string {
return 'mod';
}
public function guess_base_url(): void {
$this->define_baseurl(
new moodle_url('/admin/modules.php')
);
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/modules.php', $params);
}
protected function get_column_list(): array {
$columns = parent::get_column_list();
return array_merge(
array_slice($columns, 0, 1, true),
['activities' => get_string('activities')],
array_slice($columns, 1, null, true),
);
}
protected function col_name(stdClass $row): string {
global $OUTPUT;
$status = $row->plugininfo->get_status();
if ($status === core_plugin_manager::PLUGIN_STATUS_MISSING) {
return html_writer::span(
get_string('pluginmissingfromdisk', 'core', $row->plugininfo),
'notifyproblem'
);
}
return html_writer::span(
html_writer::img(
$OUTPUT->image_url('monologo', $row->plugininfo->name),
'',
[
'class' => 'icon',
],
) . get_string('modulename', $row->plugininfo->name)
);
}
/**
* Show the number of activities present, with a link to courses containing activity if relevant.
*
* @param mixed $row
* @return string
*/
protected function col_activities(stdClass $row): string {
global $DB, $OUTPUT;
try {
$count = $DB->count_records_select($row->plugininfo->name, "course <> 0");
} catch (dml_exception $e) {
$count = -1;
}
if ($count > 0) {
return $OUTPUT->action_link(
new moodle_url('/course/search.php', [
'modulelist' => $row->plugininfo->name,
]),
$count,
null,
['title' => get_string('showmodulecourse')]
);
} else if ($count < 0) {
return get_string('error');
} else {
return $count;
}
}
}
@@ -1,153 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\table;
use html_writer;
use moodle_url;
use stdClass;
/**
* Tiny admin settings.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class block_management_table extends \core_admin\table\plugin_management_table {
/** @var plugininfo[] A list of blocks which cannot be deleted */
protected array $undeletableblocktypes;
/** @var stdClass[] A list of basic block data */
protected array $blockdata;
public function __construct() {
global $DB;
parent::__construct();
$this->undeletableblocktypes = \block_manager::get_undeletable_block_types();
$sql = <<<EOF
SELECT
b.name,
b.id,
b.name,
COUNT(DISTINCT binst.id) as totalcount,
COUNT(DISTINCT bcinst.id) as courseviewcount
FROM {block} b
LEFT JOIN {block_instances} binst ON binst.blockname = b.name
LEFT JOIN {block_instances} bcinst ON
bcinst.blockname = b.name AND
bcinst.pagetypepattern = 'course-view-*'
GROUP BY b.id, b.name, b.visible, binst.blockname, bcinst.blockname
ORDER BY b.name ASC
EOF;
$this->blockdata = $DB->get_records_sql($sql);
}
protected function get_plugintype(): string {
return 'block';
}
public function guess_base_url(): void {
$this->define_baseurl(
new moodle_url('/admin/blocks.php')
);
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/blocks.php', $params);
}
protected function get_table_js_module(): string {
return 'core_admin/block_management_table';
}
protected function get_column_list(): array {
$columns = parent::get_column_list();
return array_merge(
array_slice($columns, 0, 1, true),
['instances' => get_string('blockinstances', 'admin')],
array_slice($columns, 1, 2, true),
['protect' => get_string('blockprotect', 'admin')],
array_slice($columns, 3, null, true),
);
}
protected function get_columns_with_help(): array {
return [
'protect' => new \help_icon('blockprotect', 'admin'),
];
}
/**
* Render the instances column
* @param stdClass $row
* @return string
*/
protected function col_instances(stdClass $row): string {
$blockdata = $this->blockdata[$row->plugininfo->name];
if ($blockdata->courseviewcount > 0) {
return html_writer::link(
new moodle_url('/course/search.php', [
'blocklist' => $row->plugininfo->name,
'sesskey' => sesskey(),
]),
$blockdata->totalcount,
);
}
return $blockdata->totalcount;
}
/**
* Render the protect column.
*
* @param stdClass $row
* @return string
*/
protected function col_protect(stdClass $row): string {
global $OUTPUT;
$params = [
'sesskey' => sesskey(),
];
$protected = in_array($row->plugininfo->name, $this->undeletableblocktypes);
$pluginname = $row->plugininfo->displayname;
if ($protected) {
$params['unprotect'] = $row->plugininfo->name;
$icon = $OUTPUT->pix_icon('t/unlock', get_string('blockunprotectblock', 'admin', $pluginname));
} else {
$params['protect'] = $row->plugininfo->name;
$icon = $OUTPUT->pix_icon('t/lock', get_string('blockprotectblock', 'admin', $pluginname));
}
return html_writer::link(
$this->get_action_url($params),
$icon,
[
'data-action' => 'toggleprotectstate',
'data-plugin' => $row->plugin,
'data-target-state' => $protected ? 0 : 1,
],
);
return '';
}
}
@@ -1,63 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\table;
use moodle_url;
/**
* Tiny admin settings.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class editor_management_table extends \core_admin\table\plugin_management_table {
protected function get_plugintype(): string {
return 'editor';
}
public function guess_base_url(): void {
$this->define_baseurl(
new moodle_url('/admin/settings.php', ['section' => 'manageeditors'])
);
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/editors.php', $params);
}
protected function order_plugins(array $plugins): array {
global $CFG;
// The Editor list is stored in an ordered string.
$activeeditors = explode(',', $CFG->texteditors);
$sortedplugins = [];
foreach ($activeeditors as $editor) {
if (isset($plugins[$editor])) {
$sortedplugins[$editor] = $plugins[$editor];
unset($plugins[$editor]);
}
}
$otherplugins = parent::order_plugins($plugins);
return array_merge(
$sortedplugins,
$otherplugins
);
}
}
@@ -1,71 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\table;
use moodle_url;
use stdClass;
/**
* Media plugin admin settings.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class media_management_table extends \core_admin\table\plugin_management_table {
/** @var array The list of used extensions */
protected array $usedextensions = [];
protected function get_plugintype(): string {
return 'media';
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/media.php', $params);
}
protected function get_column_list(): array {
$columns = parent::get_column_list();
return array_merge(
array_slice($columns, 0, 1, true),
['supports' => get_string('supports', 'core_media')],
array_slice($columns, 1, null, true),
);
}
protected function col_name(stdClass $row): string {
global $OUTPUT, $PAGE;
$name = $row->plugininfo->name;
if ($PAGE->theme->resolve_image_location('icon', 'media_' . $name, false)) {
$icon = $OUTPUT->pix_icon('icon', '', "media_{$name}", ['class' => 'icon pluginicon']);
} else {
$icon = $OUTPUT->pix_icon('spacer', '', 'moodle', ['class' => 'icon pluginicon noicon']);
}
$help = '';
if (get_string_manager()->string_exists('pluginname_help', 'media_' . $name)) {
$help = '&nbsp;' . $OUTPUT->help_icon('pluginname', 'media_' . $name);
}
return $icon . $row->plugininfo->displayname . $help;
}
protected function col_supports(stdClass $row): string {
return $row->plugininfo->supports($this->usedextensions);
}
}
@@ -1,503 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\table;
use context_system;
use core_plugin_manager;
use core_table\dynamic as dynamic_table;
use flexible_table;
use html_writer;
use moodle_url;
use stdClass;
defined('MOODLE_INTERNAL') || die();
require_once("{$CFG->libdir}/tablelib.php");
/**
* Plugin Management table.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class plugin_management_table extends flexible_table implements dynamic_table {
/** @var \core\plugininfo\base[] The plugin list */
protected array $plugins = [];
/** @var int The number of enabled plugins of this type */
protected int $enabledplugincount = 0;
/** @var core_plugin_manager */
protected core_plugin_manager $pluginmanager;
/** @var string The plugininfo class for this plugintype */
protected string $plugininfoclass;
public function __construct() {
global $CFG;
parent::__construct($this->get_table_id());
require_once($CFG->libdir . '/adminlib.php');
// Fetch the plugininfo class.
$this->pluginmanager = core_plugin_manager::instance();
$this->plugininfoclass = $this->pluginmanager::resolve_plugininfo_class($this->get_plugintype());
$this->guess_base_url();
$this->plugins = $this->get_sorted_plugins();
$this->enabledplugincount = count(array_filter($this->plugins, function ($plugin) {
return $plugin->is_enabled();
}));
$this->setup_column_configuration();
$this->set_filterset(new plugin_management_table_filterset());
$this->setup();
}
/**
* Get the list of sorted plugins.
*
* @return \core\plugininfo\base[]
*/
protected function get_sorted_plugins(): array {
if ($this->plugininfoclass::plugintype_supports_ordering()) {
return $this->plugininfoclass::get_sorted_plugins();
} else {
$plugins = $this->pluginmanager->get_plugins_of_type($this->get_plugintype());
return self::sort_plugins($plugins);
}
}
/**
* Sort the plugins list.
*
* Note: This only applies to plugins which do not support ordering.
*
* @param \core\plugininfo\base[] $plugins
* @return \core\plugininfo\base[]
*/
protected function sort_plugins(array $plugins): array {
// The asort functions work by reference.
\core_collator::asort_objects_by_property($plugins, 'displayname');
return $plugins;
}
/**
* Set up the column configuration for this table.
*/
protected function setup_column_configuration(): void {
$columnlist = $this->get_column_list();
$this->define_columns(array_keys($columnlist));
$this->define_headers(array_values($columnlist));
$columnswithhelp = $this->get_columns_with_help();
$columnhelp = array_map(function (string $column) use ($columnswithhelp): ?\renderable {
if (array_key_exists($column, $columnswithhelp)) {
return $columnswithhelp[$column];
}
return null;
}, array_keys($columnlist));
$this->define_help_for_headers($columnhelp);
}
/**
* Set the standard order of the plugins.
*
* @param array $plugins
* @return array
*/
protected function order_plugins(array $plugins): array {
uasort($plugins, function ($a, $b) {
if ($a->is_enabled() && !$b->is_enabled()) {
return -1;
} else if (!$a->is_enabled() && $b->is_enabled()) {
return 1;
}
return strnatcasecmp($a->name, $b->name);
});
return $plugins;
}
/**
* Get the plugintype for this table.
*
* @return string
*/
abstract protected function get_plugintype(): string;
/**
* Get the action URL for this table.
*
* The action URL is used to perform all actions when JS is not available.
*
* @param array $params
* @return moodle_url
*/
abstract protected function get_action_url(array $params = []): moodle_url;
/**
* Provide a default implementation for guessing the base URL from the action URL.
*/
public function guess_base_url(): void {
$this->define_baseurl($this->get_action_url());
}
/**
* Get the web service method used to toggle state.
*
* @return null|string
*/
protected function get_toggle_service(): ?string {
return 'core_admin_set_plugin_state';
}
/**
* Get the web service method used to order plugins.
*
* @return null|string
*/
protected function get_sortorder_service(): ?string {
return 'core_admin_set_plugin_order';
}
/**
* Get the ID of the table.
*
* @return string
*/
protected function get_table_id(): string {
return 'plugin_management_table-' . $this->get_plugintype();
}
/**
* Get a list of the column titles
* @return string[]
*/
protected function get_column_list(): array {
$columns = [
'name' => get_string('name', 'core'),
'version' => get_string('version', 'core'),
];
if ($this->supports_disabling()) {
$columns['enabled'] = get_string('pluginenabled', 'core_plugin');
}
if ($this->supports_ordering()) {
$columns['order'] = get_string('order', 'core');
}
$columns['settings'] = get_string('settings', 'core');
$columns['uninstall'] = get_string('uninstallplugin', 'core_admin');
return $columns;
}
protected function get_columns_with_help(): array {
return [];
}
/**
* Get the context for this table.
*
* @return context_system
*/
public function get_context(): context_system {
return context_system::instance();
}
/**
* Get the table content.
*/
public function get_content(): string {
ob_start();
$this->out();
$content = ob_get_contents();
ob_end_clean();
return $content;
}
/**
* Print the table.
*/
public function out(): void {
$plugintype = $this->get_plugintype();
foreach ($this->plugins as $plugininfo) {
$plugin = "{$plugintype}_{$plugininfo->name}";
$rowdata = (object) [
'plugin' => $plugin,
'plugininfo' => $plugininfo,
'name' => $plugininfo->displayname,
'version' => $plugininfo->versiondb,
];
$this->add_data_keyed(
$this->format_row($rowdata),
$this->get_row_class($rowdata)
);
}
$this->finish_output(false);
}
/**
* This table is not downloadable.
* @param bool $downloadable
* @return bool
*/
// phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
public function is_downloadable($downloadable = null): bool {
return false;
}
/**
* Show the name column content.
*
* @param stdClass $row
* @return string
*/
protected function col_name(stdClass $row): string {
$status = $row->plugininfo->get_status();
if ($status === core_plugin_manager::PLUGIN_STATUS_MISSING) {
return html_writer::span(
get_string('pluginmissingfromdisk', 'core', $row->plugininfo),
'notifyproblem'
);
}
if ($row->plugininfo->is_installed_and_upgraded()) {
return $row->plugininfo->displayname;
}
return html_writer::span(
$row->plugininfo->displayname,
'notifyproblem'
);
}
/**
* Show the enable/disable column content.
*
* @param stdClass $row
* @return string
*/
protected function col_enabled(stdClass $row): string {
global $OUTPUT;
$enabled = $row->plugininfo->is_enabled();
$params = [
'sesskey' => sesskey(),
'plugin' => $row->plugininfo->name,
'action' => $enabled ? 'disable' : 'enable',
];
if ($enabled) {
$icon = $OUTPUT->pix_icon('t/hide', get_string('disableplugin', 'core_admin', $row->plugininfo->displayname));
} else {
$icon = $OUTPUT->pix_icon('t/show', get_string('enableplugin', 'core_admin', $row->plugininfo->displayname));
}
return html_writer::link(
$this->get_action_url($params),
$icon,
[
'data-toggle-method' => $this->get_toggle_service(),
'data-action' => 'togglestate',
'data-plugin' => $row->plugin,
'data-state' => $enabled ? 1 : 0,
],
);
}
protected function col_order(stdClass $row): string {
global $OUTPUT;
if (!$this->supports_ordering()) {
return '';
}
if (!$row->plugininfo->is_enabled()) {
return '';
}
if ($this->enabledplugincount <= 1) {
// There is only one row.
return '';
}
$hasup = true;
$hasdown = true;
if (empty($this->currentrow)) {
// This is the top row.
$hasup = false;
}
if ($this->currentrow === ($this->enabledplugincount - 1)) {
// This is the last row.
$hasdown = false;
}
if ($this->supports_ordering()) {
$dataattributes = [
'data-method' => $this->get_sortorder_service(),
'data-action' => 'move',
'data-plugin' => $row->plugin,
];
} else {
$dataattributes = [];
}
if ($hasup) {
$upicon = html_writer::link(
$this->get_action_url([
'sesskey' => sesskey(),
'action' => 'up',
'plugin' => $row->plugininfo->name,
]),
$OUTPUT->pix_icon('t/up', get_string('moveup')),
array_merge($dataattributes, ['data-direction' => 'up']),
);
} else {
$upicon = $OUTPUT->spacer();
}
if ($hasdown) {
$downicon = html_writer::link(
$this->get_action_url([
'sesskey' => sesskey(),
'action' => 'down',
'plugin' => $row->plugininfo->name,
]),
$OUTPUT->pix_icon('t/down', get_string('movedown')),
array_merge($dataattributes, ['data-direction' => 'down']),
);
} else {
$downicon = $OUTPUT->spacer();
}
// For now just add the up/down icons.
return html_writer::span($upicon . $downicon);
}
/**
* Show the settings column content.
*
* @param stdClass $row
* @return string
*/
protected function col_settings(stdClass $row): string {
if ($settingsurl = $row->plugininfo->get_settings_url()) {
return html_writer::link($settingsurl, get_string('settings'));
}
return '';
}
/**
* Show the Uninstall column content.
*
* @param stdClass $row
* @return string
*/
protected function col_uninstall(stdClass $row): string {
$status = $row->plugininfo->get_status();
if ($status === core_plugin_manager::PLUGIN_STATUS_NEW) {
return get_string('status_new', 'core_plugin');
}
if ($status === core_plugin_manager::PLUGIN_STATUS_MISSING) {
$uninstall = get_string('status_missing', 'core_plugin') . '<br/>';
} else {
$uninstall = '';
}
if ($uninstallurl = $this->pluginmanager->get_uninstall_url($row->plugin)) {
$uninstall .= html_writer::link($uninstallurl, get_string('uninstallplugin', 'core_admin'));
}
return $uninstall;
}
/**
* Get the JS module used to manage this table.
*
* This should be a class which extends 'core_admin/plugin_management_table'.
*
* @return string
*/
protected function get_table_js_module(): string {
return 'core_admin/plugin_management_table';
}
/**
* Add JS specific to this implementation.
*
* @return string
*/
protected function get_dynamic_table_html_end(): string {
global $PAGE;
$PAGE->requires->js_call_amd($this->get_table_js_module(), 'init');
return parent::get_dynamic_table_html_end();
}
/**
* Get any class to add to the row.
*
* @param mixed $row
* @return string
*/
protected function get_row_class($row): string {
$plugininfo = $row->plugininfo;
if ($plugininfo->get_status() === core_plugin_manager::PLUGIN_STATUS_MISSING) {
return '';
}
if (!$plugininfo->is_enabled()) {
return 'dimmed_text';
}
return '';
}
public static function get_filterset_class(): string {
return self::class . '_filterset';
}
/**
* Whether this plugin type supports the disabling of plugins.
*
* @return bool
*/
protected function supports_disabling(): bool {
return $this->plugininfoclass::plugintype_supports_disabling();
}
/**
* Whether this table should show ordering fields.
*
* @return bool
*/
protected function supports_ordering(): bool {
return $this->plugininfoclass::plugintype_supports_ordering();
}
}
@@ -1,27 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\table;
/**
* This file contains the dynamic interface.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class plugin_management_table_filterset extends \core_table\local\filter\filterset {
}
@@ -1,50 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace core_admin\table;
use moodle_url;
/**
* Tiny admin settings.
*
* @package core_admin
* @copyright 2023 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_plugin_management_table extends \core_admin\table\plugin_management_table {
protected function get_plugintype(): string {
return 'tool';
}
public function guess_base_url(): void {
$this->define_baseurl(
new moodle_url('/admin/tools.php')
);
}
protected function get_column_list(): array {
$columns = parent::get_column_list();
unset($columns['settings']);
return $columns;
}
protected function get_action_url(array $params = []): moodle_url {
return new moodle_url('/admin/tool.php', $params);
}
}
-174
View File
@@ -1,174 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Task executor for adhoc tasks.
*
* @package core
* @subpackage cli
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once("{$CFG->libdir}/clilib.php");
list($options, $unrecognized) = cli_get_params(
[
'help' => false,
'showsql' => false,
'showdebugging' => false,
'execute' => false,
'keep-alive' => 0,
'ignorelimits' => false,
'force' => false,
'id' => null,
'classname' => null,
'taskslimit' => null,
'failed' => false,
], [
'h' => 'help',
'e' => 'execute',
'k' => 'keep-alive',
'i' => 'ignorelimits',
'f' => 'force',
'c' => 'classname',
'l' => 'taskslimit',
]
);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
$help = <<<EOT
Ad hoc cron tasks.
Options:
-h, --help Print out this help
--showsql Show sql queries before they are executed
--showdebugging Show developer level debugging information
-e, --execute Run all queued adhoc tasks
-k, --keep-alive=N Keep this script alive for N seconds and poll for new adhoc tasks
-i --ignorelimits Ignore task_adhoc_concurrency_limit and task_adhoc_max_runtime limits
-f, --force Run even if cron is disabled
--id Run (failed) task with id
-c, --classname Run tasks with a certain classname (FQN)
-l, --taskslimit=N Run at most N tasks
--failed Run only tasks that failed, ie those with a fail delay
Run all queued tasks:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --execute
Run all queued tasks of specific class:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --classname=\\\\core_course\\\\task\\\\course_delete_modules
Double backslash for the shell escape reasons.
Run a specific task:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --id=123456
Run a specific task with debugging:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --id=123456 --showsql --showdebugging
To profile a long running task:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --taskslimit=1 --classname='\\some\\class\\name' --ignorelimits
EOT;
if ($options['help']) {
echo $help;
exit(0);
}
if (CLI_MAINTENANCE) {
echo "CLI maintenance mode active, cron execution suspended.\n";
exit(1);
}
if (moodle_needs_upgrading()) {
echo "Moodle upgrade pending, cron execution suspended.\n";
exit(1);
}
if (!get_config('core', 'cron_enabled') && !$options['force']) {
mtrace('Cron is disabled. Use --force to override.');
exit(1);
}
// Common debugging options.
if ($options['showdebugging']) {
set_debugging(DEBUG_DEVELOPER, true);
}
if ($options['showsql']) {
$DB->set_debug(true);
}
if (!empty($CFG->showcronsql)) {
$DB->set_debug(true);
}
if (!empty($CFG->showcrondebugging)) {
set_debugging(DEBUG_DEVELOPER, true);
}
// Process params.
core_php_time_limit::raise();
// Increase memory limit.
raise_memory_limit(MEMORY_EXTRA);
// Emulate normal session - we use admin account by default.
\core\cron::setup_user();
\core\local\cli\shutdown::script_supports_graceful_exit();
$humantimenow = date('r', time());
mtrace("Server Time: {$humantimenow}\n");
$classname = $options['classname'];
// Run a single adhoc task only, if requested.
if (!empty($options['id'])) {
$taskid = (int) $options['id'];
\core\cron::run_adhoc_task($taskid);
exit(0);
}
// Run all failed tasks.
if (!empty($options['failed'])) {
\core\cron::run_failed_adhoc_tasks($classname);
exit(0);
}
// Examine params and determine if we should run.
$execute = (bool) $options['execute'];
$keepalive = empty($options['keep-alive']) ? 0 : (int) $options['keep-alive'];
$taskslimit = empty($options['taskslimit']) ? null : (int) $options['taskslimit'];
$checklimits = empty($options['ignorelimits']);
if ($classname || $keepalive || $taskslimit) {
$execute = true;
}
// Output the help text if no criteria for running the adhoc tasks are given.
if (!$execute) {
echo $help;
exit(0);
}
\core\cron::run_adhoc_tasks(time(), $keepalive, $checklimits, null, $taskslimit, $classname);
-111
View File
@@ -1,111 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This hack is intended for clustered sites that do not want
* to use shared cachedir for component cache.
*
* This file needs to be called after any change in PHP files in dataroot,
* that is before upgrade and install.
*
* @package core
* @copyright 2013 Petr Skoda (skodak) {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
define('ABORT_AFTER_CONFIG', true); // We need just the values from config.php.
define('CACHE_DISABLE_ALL', true); // This prevents reading of existing caches.
define('IGNORE_COMPONENT_CACHE', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
// Now get cli options.
list($options, $unrecognized) = cli_get_params(
array(
'file' => false,
'rebuild' => false,
'print' => false,
'help' => false
),
array(
'h' => 'help'
)
);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized), 2);
}
if (!$options['rebuild'] and !$options['file'] and !$options['print']) {
$help =
"Create alternative component cache file
Options:
-h, --help Print out this help
--rebuild Rebuild \$CFG->alternative_component_cache file
--file=filepath Save component cache to file
--print Print component cache file content
Example:
\$ php admin/cli/rebuild_alternative_component_cache.php --rebuild
";
echo $help;
exit(0);
}
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
$content = core_component::get_cache_content();
if ($options['print']) {
echo $content;
exit(0);
}
if ($options['rebuild']) {
if (empty($CFG->alternative_component_cache)) {
fwrite(STDERR, 'config.php does not contain $CFG->alternative_component_cache setting');
fwrite(STDERR, "\n");
exit(2);
}
$target = $CFG->alternative_component_cache;
} else {
$target = $options['file'];
}
if (!$target) {
fwrite(STDERR, "Invalid target file $target");
fwrite(STDERR, "\n");
exit(1);
}
$bytes = file_put_contents($target, $content);
if (!$bytes) {
fwrite(STDERR, "Error writing to $target");
fwrite(STDERR, "\n");
exit(1);
}
// Success.
echo "File $target was updated\n";
exit(0);
+8 -6
View File
@@ -28,8 +28,9 @@
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/clilib.php'); // cli only functions
require_once($CFG->libdir.'/cronlib.php');
// now get cli options
list($options, $unrecognized) = cli_get_params(array('help'=>false),
@@ -74,15 +75,16 @@ if (!empty($CFG->showcronsql)) {
$DB->set_debug(true);
}
if (!empty($CFG->showcrondebugging)) {
set_debugging(DEBUG_DEVELOPER, true);
$CFG->debug = DEBUG_DEVELOPER;
$CFG->debugdisplay = true;
}
$starttime = microtime();
// Emulate normal session.
\core\cron::setup_user();
/// emulate normal session
cron_setup_user();
// Start output log.
/// Start output log
$timenow = time();
mtrace("Server Time: ".date('r',$timenow)."\n\n");
@@ -95,4 +97,4 @@ backup_cron_automated_helper::run_automated_backup(backup_cron_automated_helper:
mtrace("Automated cron backups completed correctly");
$difftime = microtime_diff($starttime, microtime());
mtrace("Execution took ".$difftime." seconds");
mtrace("Execution took ".$difftime." seconds");
-119
View File
@@ -1,119 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This script allows to do backup.
*
* @package core
* @subpackage cli
* @copyright 2013 Lancaster University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', 1);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
// Now get cli options.
list($options, $unrecognized) = cli_get_params(array(
'courseid' => false,
'courseshortname' => '',
'destination' => '',
'help' => false,
), array('h' => 'help'));
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help'] || !($options['courseid'] || $options['courseshortname'])) {
$help = <<<EOL
Perform backup of the given course.
Options:
--courseid=INTEGER Course ID for backup.
--courseshortname=STRING Course shortname for backup.
--destination=STRING Path where to store backup file. If not set the backup
will be stored within the course backup file area.
-h, --help Print out this help.
Example:
\$sudo -u www-data /usr/bin/php admin/cli/backup.php --courseid=2 --destination=/moodle/backup/\n
EOL;
echo $help;
die;
}
$admin = get_admin();
if (!$admin) {
mtrace("Error: No admin account was found");
die;
}
// Do we need to store backup somewhere else?
$dir = rtrim($options['destination'], '/');
if (!empty($dir)) {
if (!file_exists($dir) || !is_dir($dir) || !is_writable($dir)) {
mtrace("Destination directory does not exists or not writable.");
die;
}
}
// Check that the course exists.
if ($options['courseid']) {
$course = $DB->get_record('course', array('id' => $options['courseid']), '*', MUST_EXIST);
} else if ($options['courseshortname']) {
$course = $DB->get_record('course', array('shortname' => $options['courseshortname']), '*', MUST_EXIST);
}
cli_heading('Performing backup...');
$bc = new backup_controller(backup::TYPE_1COURSE, $course->id, backup::FORMAT_MOODLE,
backup::INTERACTIVE_YES, backup::MODE_GENERAL, $admin->id);
// Set the default filename.
$format = $bc->get_format();
$type = $bc->get_type();
$id = $bc->get_id();
$users = $bc->get_plan()->get_setting('users')->get_value();
$anonymised = $bc->get_plan()->get_setting('anonymize')->get_value();
$filename = backup_plan_dbops::get_default_backup_filename($format, $type, $id, $users, $anonymised);
$bc->get_plan()->get_setting('filename')->set_value($filename);
// Execution.
$bc->finish_ui();
$bc->execute_plan();
$results = $bc->get_results();
$file = $results['backup_destination']; // May be empty if file already moved to target location.
// Do we need to store backup somewhere else?
if (!empty($dir)) {
if ($file) {
mtrace("Writing " . $dir.'/'.$filename);
if ($file->copy_content_to($dir.'/'.$filename)) {
$file->delete();
mtrace("Backup completed.");
} else {
mtrace("Destination directory does not exist or is not writable. Leaving the backup in the course backup file area.");
}
}
} else {
mtrace("Backup completed, the new file is listed in the backup area of the given course");
}
$bc->destroy();
exit(0);
-119
View File
@@ -1,119 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Build and store theme CSS.
*
* @package core
* @subpackage cli
* @copyright 2017 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once("$CFG->libdir/clilib.php");
require_once("$CFG->libdir/csslib.php");
require_once("$CFG->libdir/outputlib.php");
$longparams = [
'themes' => null,
'direction' => null,
'help' => false,
'verbose' => false
];
$shortmappings = [
't' => 'themes',
'd' => 'direction',
'h' => 'help',
'v' => 'verbose'
];
// Get CLI params.
list($options, $unrecognized) = cli_get_params($longparams, $shortmappings);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help']) {
echo
"Compile the CSS for one or more installed themes.
Existing CSS caches will replaced.
By default all themes will be recompiled unless otherwise specified.
Options:
-t, --themes A comma separated list of themes to be compiled
-d, --direction Only compile a single direction (either ltr or rtl)
-v, --verbose Print info comments to stdout
-h, --help Print out this help
Example:
\$ sudo -u www-data /usr/bin/php admin/cli/build_theme_css.php --themes=boost --direction=ltr
";
die;
}
if (empty($options['verbose'])) {
$trace = new null_progress_trace();
} else {
$trace = new text_progress_trace();
}
cli_heading('Build theme css');
// Determine which themes we need to build.
$themenames = [];
if (is_null($options['themes'])) {
$trace->output('No themes specified. Finding all installed themes.');
$themenames = array_keys(core_component::get_plugin_list('theme'));
} else {
if (is_string($options['themes'])) {
$themenames = explode(',', $options['themes']);
} else {
cli_error('--themes must be a comma separated list of theme names');
}
}
$trace->output('Checking that each theme is correctly installed...');
$themeconfigs = [];
foreach ($themenames as $themename) {
if (is_null(theme_get_config_file_path($themename))) {
cli_error("Unable to find theme config for {$themename}");
}
// Load the config for the theme.
$themeconfigs[] = theme_config::load($themename);
}
$directions = ['ltr', 'rtl'];
if (!is_null($options['direction'])) {
if (!in_array($options['direction'], $directions)) {
cli_error("--direction must be either ltr or rtl");
}
$directions = [$options['direction']];
}
$trace->output('Building CSS for themes: ' . implode(', ', $themenames));
theme_build_css_for_themes($themeconfigs, $directions);
exit(0);
-185
View File
@@ -1,185 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* CLI script allowing to get and set config values.
*
* This is technically just a thin wrapper for {@link get_config()} and
* {@link set_config()} functions.
*
* @package core
* @subpackage cli
* @copyright 2017 David Mudrák <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
$usage = "Displays the current value of the given site setting. Allows to set it to the given value, too.
Usage:
# php cfg.php [--component=<componentname>] [--json] [--shell-arg]
# php cfg.php --name=<configname> [--component=<componentname>] [--shell-arg] [--no-eol]
# php cfg.php --name=<configname> [--component=<componentname>] --set=<value>
# php cfg.php --name=<configname> [--component=<componentname>] --unset
# php cfg.php [--help|-h]
Options:
-h --help Print this help.
--component=<frankenstyle> Name of the component the variable is part of. Defaults to core.
--name=<configname> Name of the configuration variable to get/set. If missing, print all
configuration variables of the given component.
--set=<value> Set the given variable to this value.
--unset Unset the given variable.
--shell-arg Escape output values so that they can be directly used as shell script arguments.
--json Encode output list of values using JSON notation.
--no-eol Do not include the trailing new line character when printing the value.
The list of all variables of the given component can be printed as
tab-separated list (default) or JSON object (--json). Particular values are
printed as raw text values, optionally escaped so that they can be directly
used as shell script arguments (--shell-arg). Single values are displayed with
trailing new line by default, unless explicitly disabled (--no-eol).
In the read mode, the script exits with success status 0 if the requested value
is found. If the requested variable is not set, the script exits with status 3.
When listing all variables of the component, the exit status is always 0 even
if no variables for the given component are found. When setting/unsetting a
value, the exit status is 0. When attempting to set/unset a value that has
already been hard-set in config.php, the script exits with error status 4. In
case of unexpected error, the script exits with error status 1.
Examples:
# php cfg.php
Prints tab-separated list of all core configuration variables and their values.
# php cfg.php --json
Prints list of all core configuration variables and their values as a JSON object.
# php cfg.php --name=release
Prints the given configuration variable - e.g. \$CFG->release in this case.
# php cfg.php --component=tool_recyclebin
# Prints tab-separated list of the plugin's configuration variables.
# export DATAROOT=\$(php cfg.php --name=dataroot --shell-arg --no-eol)
Stores the given configuration variable in the shell variable, escaped
so that it can be safely used as a shell argument.
# php cfg.php --name=theme --set=classic
Sets the given configuration variable to the given value.
# php cfg.php --name=noemailever --unset
Unsets the previously configured variable.
";
list($options, $unrecognised) = cli_get_params([
'help' => false,
'component' => null,
'name' => null,
'set' => null,
'unset' => false,
'shell-arg' => false,
'json' => false,
'no-eol' => false,
], [
'h' => 'help'
]);
if ($unrecognised) {
$unrecognised = implode(PHP_EOL.' ', $unrecognised);
cli_error(get_string('cliunknowoption', 'core_admin', $unrecognised));
}
if ($options['help']) {
cli_writeln($usage);
exit(2);
}
if ($options['unset'] || $options['set'] !== null) {
// Unset the variable or set it to the given value.
if (empty($options['name'])) {
cli_error('Missing configuration variable name', 2);
}
// Check that the variable is not hard-set in the main config.php already.
$component = $options['component'];
if (!empty($component)) {
$componentsettings = $CFG->forced_plugin_settings[$component] ?? [];
$settinginconfig = array_key_exists($options['name'], $componentsettings);
} else {
$settinginconfig = array_key_exists($options['name'], $CFG->config_php_settings);
}
if ($settinginconfig) {
cli_error('The configuration variable is hard-set in the config.php, unable to change.', 4);
}
$new = $options['set'];
$old = get_config($options['component'], $options['name']);
if ($new !== $old) {
set_config($options['name'], $options['set'], $options['component']);
add_to_config_log($options['name'], $old, $new, $options['component']);
}
exit(0);
}
if ($options['name'] === null) {
// List all variables provided by the component (defaults to core).
$got = get_config($options['component']);
if ($options['json']) {
cli_writeln(json_encode($got));
} else {
foreach ($got as $name => $value) {
if ($options['shell-arg']) {
$value = escapeshellarg($value);
}
cli_writeln($name."\t".$value);
}
}
exit(0);
} else {
// Display the value of a single variable.
$got = get_config($options['component'], $options['name']);
if ($got === false) {
cli_error('No such configuration variable found.', 3);
}
if ($options['shell-arg']) {
$got = escapeshellarg($got);
}
if ($options['json']) {
$got = json_encode($got);
}
if ($options['no-eol']) {
cli_write($got);
} else {
cli_writeln($got);
}
exit(0);
}
-76
View File
@@ -1,76 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Validate that the current db structure matches the install.xml files.
*
* @package core
* @copyright 2014 Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Petr Skoda <petr.skoda@totaralms.com>
*/
define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once($CFG->libdir.'/clilib.php');
$help = "Validate database structure
Options:
-h, --help Print out this help.
Example:
\$ sudo -u www-data /usr/bin/php admin/cli/check_database_schema.php
";
list($options, $unrecognized) = cli_get_params(
array(
'help' => false,
),
array(
'h' => 'help',
)
);
if ($options['help']) {
echo $help;
exit(0);
}
if (empty($CFG->version)) {
echo "Database is not yet installed.\n";
exit(2);
}
$dbmanager = $DB->get_manager();
$schema = $dbmanager->get_install_xml_schema();
if (!$errors = $dbmanager->check_database_schema($schema)) {
echo "Database structure is ok.\n";
exit(0);
}
foreach ($errors as $table => $items) {
cli_separator();
echo "$table\n";
foreach ($items as $item) {
echo " * $item\n";
}
}
cli_separator();
exit(1);
-171
View File
@@ -1,171 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* CLI tool for system checks
*
* @package core
* @category check
* @copyright 2020 Brendan Heywood (brendan@catalyst-au.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once($CFG->libdir.'/clilib.php');
use core\check\result;
list($options, $unrecognized) = cli_get_params([
'help' => false,
'filter' => '',
'type' => 'status',
'verbose' => false,
], [
'h' => 'help',
'f' => 'filter',
'v' => 'verbose',
't' => 'type',
]);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
$checks = \core\check\manager::get_checks($options['type']);
$types = join(', ', \core\check\manager::TYPES);
$help = "Run Moodle system checks
Options:
-h, --help Print out this help
-f, --filter Filter to a subset of checks
-t, --type Which set of checks? Defaults to 'status'
One of $types
-v, --verbose Show details of all checks, not just failed checks
Example:
sudo -u www-data php admin/cli/checks.php
sudo -u www-data php admin/cli/checks.php -v
sudo -u www-data php admin/cli/checks.php -v --filter=environment
";
if ($options['help']) {
echo $help;
die();
}
$filter = $options['filter'];
if ($filter) {
$checks = array_filter($checks, function($check, $key) use ($filter) {
$ref = $check->get_ref();
return (strpos($ref, $filter) !== false);
}, 1);
}
// These shell exit codes and labels align with the NRPE standard.
$exitcodes = [
result::NA => 0,
result::OK => 0,
result::INFO => 0,
result::UNKNOWN => 3,
result::WARNING => 1,
result::ERROR => 2,
result::CRITICAL => 2,
];
$exitlabel = [
result::NA => 'OK',
result::OK => 'OK',
result::INFO => 'OK',
result::UNKNOWN => 'UNKNOWN',
result::WARNING => 'WARNING',
result::ERROR => 'CRITICAL',
result::CRITICAL => 'CRITICAL',
];
$format = "% 10s| % -60s\n";
$spacer = "----------+--------------------------------------------------------------------\n";
$prefix = ' |';
$output = '';
$header = $exitlabel[result::OK] . ': ' . get_string('checksok', '', $options['type']) . "\n";
$exitcode = $exitcodes[result::OK];
foreach ($checks as $check) {
$ref = $check->get_ref();
$result = $check->get_result();
$status = $result->get_status();
$checkexitcode = $exitcodes[$status];
// Summary is treated as html.
$summary = $result->get_summary();
$summary = html_to_text($summary, 60, false);
if ($checkexitcode > $exitcode) {
$exitcode = $checkexitcode;
$header = $exitlabel[$status] . ': ' . $check->get_name() . " (" . $check->get_ref() . ")\n";
}
if (empty($messages[$status])) {
$messages[$status] = $result;
}
$len = strlen(get_string('status' . $status));
if ($options['verbose'] ||
$status == result::WARNING ||
$status == result::CRITICAL ||
$status == result::ERROR) {
$output .= sprintf(
$format,
$OUTPUT->check_result($result),
sprintf('%s (%s)', $check->get_name(), $ref)
);
$summary = str_replace("\n", "\n" . $prefix . ' ', $summary);
$output .= sprintf( $format, '', ' ' . $summary);
if ($options['verbose']) {
$actionlink = $check->get_action_link();
if ($actionlink) {
$output .= sprintf( $format, '', ' ' . $actionlink->url);
}
$output .= sprintf( $format, '', '');
}
}
}
// Print NRPE header.
print $header;
// Only show the table header if there is anything to show.
if ($output) {
print sprintf($format,
get_string('status'). ' ',
get_string('check')
) . $spacer;
print $output;
}
// NRPE shell exit code.
exit($exitcode);
+10 -135
View File
@@ -1,4 +1,5 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -29,32 +30,13 @@
define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/clilib.php');
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/clilib.php'); // cli only functions
require_once($CFG->libdir.'/cronlib.php');
// Now get cli option.
[$options, $unrecognized] = cli_get_params(
[
'help' => false,
'stop' => false,
'list' => false,
'force' => false,
'enable' => false,
'disable' => false,
'disable-wait' => false,
'keep-alive' => null,
],
[
'h' => 'help',
's' => 'stop',
'l' => 'list',
'f' => 'force',
'e' => 'enable',
'd' => 'disable',
'w' => 'disable-wait',
'k' => 'keep-alive',
]
);
// now get cli options
list($options, $unrecognized) = cli_get_params(array('help'=>false),
array('h'=>'help'));
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
@@ -63,19 +45,10 @@ if ($unrecognized) {
if ($options['help']) {
$help =
"Execute periodic cron actions.
"Execute periodic cron actions.
Options:
-h, --help Print out this help
-s, --stop Notify all other running cron processes to stop after the current task
-l, --list Show the list of currently running tasks and how long they have been running
-f, --force Execute task even if cron is disabled
-e, --enable Enable cron
-d, --disable Disable cron
-w, --disable-wait=600 Disable cron and wait until all tasks finished or fail after N seconds (optional param)
-k, --keep-alive=N Keep this script alive for N seconds and poll for new tasks
The default value can be set by administrators in:
Site administration > Server > Tasks > Task processing > Keep alive time
-h, --help Print out this help
Example:
\$sudo -u www-data /usr/bin/php admin/cli/cron.php
@@ -85,102 +58,4 @@ Example:
die;
}
if ($options['stop']) {
// By clearing the caches this signals to other running processes
// to exit after finishing the current task.
\core\task\manager::clear_static_caches();
die;
}
if ($options['enable']) {
set_config('cron_enabled', 1);
mtrace('Cron has been enabled for the site.');
exit(0);
}
if ($options['disable']) {
set_config('cron_enabled', 0);
\core\task\manager::clear_static_caches();
mtrace('Cron has been disabled for the site.');
exit(0);
}
if ($options['list']) {
$tasks = \core\task\manager::get_running_tasks();
mtrace('The list of currently running tasks:');
$format = "%7s %-12s %-9s %-20s %-52s\n";
printf(
$format,
'PID',
'HOST',
'TYPE',
'TIME',
'CLASSNAME'
);
foreach ($tasks as $task) {
printf(
$format,
$task->pid,
substr($task->hostname, 0, 12),
$task->type,
format_time(time() - $task->timestarted),
substr($task->classname, 0, 52)
);
}
exit(0);
}
if ($wait = $options['disable-wait']) {
$started = time();
if (true === $wait) {
// Default waiting time.
$waitsec = 600;
} else {
$waitsec = $wait;
$wait = true;
}
set_config('cron_enabled', 0);
\core\task\manager::clear_static_caches();
mtrace('Cron has been disabled for the site.');
mtrace('Allocating ' . format_time($waitsec) . ' for the tasks to finish.');
$lastcount = 0;
while ($wait) {
$tasks = \core\task\manager::get_running_tasks();
if (count($tasks) == 0) {
mtrace('');
mtrace('All scheduled and adhoc tasks finished.');
exit(0);
}
if (time() - $started >= $waitsec) {
mtrace('');
mtrace('Wait time (' . format_time($waitsec) . ') elapsed, but ' . count($tasks) . ' task(s) still running.');
mtrace('Exiting with code 1.');
exit(1);
}
if (count($tasks) !== $lastcount) {
mtrace('');
mtrace(count($tasks) . " tasks currently running.", '');
$lastcount = count($tasks);
} else {
mtrace('.', '');
}
sleep(1);
}
}
if (!get_config('core', 'cron_enabled') && !$options['force']) {
mtrace('Cron is disabled. Use --force to override.');
exit(1);
}
\core\local\cli\shutdown::script_supports_graceful_exit();
$keepalive = $options['keep-alive'];
\core\cron::run_main_process($keepalive);
cron_run();
-65
View File
@@ -1,65 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* CLI script to reset dashboards.
*
* @package core
* @subpackage cli
* @copyright 2021 Brendan Heywood (brendan@catalyst-au.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
require_once($CFG->dirroot.'/my/lib.php');
list($options, $unrecognized) = cli_get_params([
'help' => false,
'execute' => false,
], [
'h' => 'help',
'e' => 'execute',
]);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized), 2);
}
if (!$options['execute']) {
$help = <<<EOF
Resets Moodle dashboards for all users
Options:
-h, --help Print out this help
-e, --execute Actually run the reset
Example:
\$ sudo -u www-data /usr/bin/php admin/cli/dashboard_reset.php -e
EOF;
echo $help;
exit(0);
}
$progressbar = new progress_bar();
$progressbar->create();
my_reset_page_for_all_users(MY_PAGE_PRIVATE, 'my-index', $progressbar);
-123
View File
@@ -1,123 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* CLI script to delete a course.
*
* @package core
* @subpackage cli
* @author Mikhail Golenkov <mikhailgolenkov@catalyst-au.net>
* @copyright 2022 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/clilib.php');
list($options, $unrecognized) = cli_get_params(
[
'courseid' => false,
'help' => false,
'showsql' => false,
'showdebugging' => false,
'disablerecyclebin' => false,
'non-interactive' => false,
], [
'c' => 'courseid',
'h' => 'help',
]
);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help'] || empty($options['courseid'])) {
$help = <<<EOT
CLI script to delete a course.
Options:
-h, --help Print out this help
--showsql Show sql queries before they are executed
--showdebugging Show developer level debugging information
--disablerecyclebin Skip backing up the course
--non-interactive No interactive questions or confirmations
-c, --courseid Course id to be deleted
Example:
\$sudo -u www-data /usr/bin/php admin/cli/delete_course.php --courseid=123456
\$sudo -u www-data /usr/bin/php admin/cli/delete_course.php --courseid=123456 --showdebugging
\$sudo -u www-data /usr/bin/php admin/cli/delete_course.php --courseid=123456 --disablerecyclebin
EOT;
echo $help;
die;
}
$interactive = empty($options['non-interactive']);
if ($options['showdebugging']) {
mtrace('Enabling debugging...');
set_debugging(DEBUG_DEVELOPER, true);
}
if ($options['showsql']) {
mtrace('Enabling SQL debugging...');
$DB->set_debug(true);
}
if (CLI_MAINTENANCE) {
cli_error('CLI maintenance mode active, CLI execution suspended');
}
if (moodle_needs_upgrading()) {
cli_error('Moodle upgrade pending, CLI execution suspended');
}
$course = $DB->get_record('course', array('id' => $options['courseid']));
if (empty($course)) {
cli_error('Course not found');
}
mtrace('Deleting course id ' . $course->id);
mtrace('Course name: ' . $course->fullname);
mtrace('Short name: ' . $course->shortname);
if ($interactive) {
mtrace('');
$input = cli_input('Are you sure you wish to delete this course? (y/N)', 'N', ['y', 'Y', 'n', 'N']);
if (strtolower($input) != 'y') {
exit(0);
}
}
if ($options['disablerecyclebin']) {
mtrace('Disabling recycle bin...');
$overrideconfig = ['tool_recyclebin' => ['coursebinenable' => false, 'categorybinenable' => false]];
$CFG->forced_plugin_settings = array_merge($CFG->forced_plugin_settings, $overrideconfig);
}
core_php_time_limit::raise();
delete_course($course);
mtrace('Updating course count in categories...');
fix_course_sortorder();
mtrace('Done!');
-209
View File
@@ -1,209 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This script allows you to view and change the emailstop flag of any user.
*
* @package core
* @subpackage cli
* @copyright 2023 Stephan Robotta (stephan.robotta@bfh.ch)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
// Define the input options.
$longparams = [
'email' => '',
'help' => false,
'id' => '',
'quiet' => false,
'stop' => '',
'username' => '',
];
$shortparams = [
'e' => 'email',
'h' => 'help',
'i' => 'id',
'q' => 'quiet',
's' => 'stop',
'u' => 'username',
];
// Define exit codes.
$exitsuccess = 0;
$exitunknownoption = 1;
$exitmissinguserarg = 2;
$exittoomanyuserarg = 3;
$exitnosearchargs = 4;
$exitnousersfound = 5;
$exitinvalidstopflag = 6;
$exiterrordb = 7;
// Now get cli options that are set by the caller.
list($options, $unrecognized) = cli_get_params($longparams, $shortparams);
$verbose = empty($options['quiet']);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
if ($verbose) {
cli_error(get_string('cliunknowoption', 'admin', $unrecognized), $exitunknownoption);
}
exit($exitunknownoption);
}
if ($options['help']) {
$help =
"Set/unset or show status of emailstop flag for a user, identified by username or email.
There are no security checks here because anybody who is able to
execute this file may execute any PHP too.
Options:
-h, --help Print out this help
-e, --email=email Specify user by email, separate many users by comma
-i, --id=id Specify user by id, separate many users by comma
-q, --quiet No output to stdout
-s, --stop=0|1|off|on Set new value for emailstop flag
-u, --username=username Specify user by username, separate many users by comma
Example:
\$sudo -u www-data /usr/bin/php admin/cli/emailstop.php --email=student1@example.com --stop=1
\$sudo -u www-data /usr/bin/php admin/cli/emailstop.php --email=student1@example.com,student2@example.com
\$sudo -u www-data /usr/bin/php admin/cli/emailstop.php --u=student1,student2 -s=on
";
echo $help;
exit($exitsuccess);
}
$cntempty = 0;
$cntfilled = 0;
$searchargs = [];
// Try to find out which option is used to fetch the users from. Also do sanitize etc.
foreach (['email', 'username', 'id'] as $option) {
if (empty($options[$option])) {
$cntempty++;
} else {
$cntfilled++;
$argname = $option;
// The search args must be: split by the comma, trimmed, and empty elements filtered out.
$searchargs = array_flip(array_filter(
array_map(
function ($item) {
return trim($item);
},
explode(',', $options[$option])
),
function ($item) {
return $item !== '';
}
));
}
}
if ($cntempty === 3) {
if ($verbose) {
cli_error('One of username, email, or id must be set.', $exitmissinguserarg);
}
exit($exitmissinguserarg);
}
if ($cntfilled > 1) {
if ($verbose) {
cli_error('Only one of email, username, or id can be set to identify a user.', $exittoomanyuserarg);
}
exit($exittoomanyuserarg);
}
if (empty($searchargs)) {
if ($verbose) {
cli_error('No values are provided for users.', $exitnosearchargs);
}
exit($exitnosearchargs);
}
try {
$users = $DB->get_records_list('user', $argname, array_keys($searchargs));
} catch (Exception $e) {
if ($verbose) {
cli_error("Could not fetch data from db by {$argname}: '{$options[$argname]}'.", $exiterrordb);
}
exit($exiterrordb);
}
if (empty($users)) {
if ($verbose) {
cli_error("Can not find any user by {$argname}: '{$options[$argname]}'.", $exitnousersfound);
}
exit($exitnousersfound);
}
// No stop flag set, then just print the user and the current emailstop flag state.
if ($options['stop'] === '') {
foreach ($users as $user) {
if ($verbose) {
echo 'user=' . $user->{$argname} . ' - emailstop=' . (int)$user->emailstop . PHP_EOL;
unset($searchargs[$user->{$argname}]);
}
}
if ($verbose) {
foreach (array_keys($searchargs) as $arg) {
echo 'user=' . $arg . ' - not found' . PHP_EOL;
}
}
exit($exitsuccess);
}
// Allowed values for the stop flag enabled are 1 and on, for disabled are 0 and off.
$validvalues = ['0', '1', 'off', 'on'];
$stopflag = strtolower($options['stop']);
if (!in_array($stopflag, $validvalues)) {
if ($verbose) {
cli_error('Value for the emailstop flag must be one of: ' . implode(', ', $validvalues) . '.', $exitinvalidstopflag);
}
exit($exitinvalidstopflag);
}
foreach ($validvalues as $value) {
if ($value === $stopflag) {
$stopflag = ($value === '1' || $value === 'on') ? 1 : 0;
break;
}
}
// Update each user with the stop flag to be set if it is necessary.
foreach ($users as $user) {
$line = 'Update user ' . $user->{$argname} . ($argname !== 'id' ? ' (' . $user->id . ')' : '') . ' - ';
if ((int)$user->emailstop !== $stopflag) {
$DB->set_field('user', 'emailstop', $stopflag, ['id' => $user->id]);
$line .= 'ok';
} else {
$line .= 'already done';
}
if ($verbose) {
echo $line . PHP_EOL;
unset($searchargs[$user->{$argname}]);
}
}
if ($verbose) {
foreach (array_keys($searchargs) as $arg) {
echo 'user=' . $arg . ' - not found' . PHP_EOL;
}
}
exit($exitsuccess);
-125
View File
@@ -1,125 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This script fixed incorrectly deleted users.
*
* @package core
* @subpackage cli
* @copyright 2013 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
// Get cli options.
list($options, $unrecognized) = cli_get_params(
array(
'courses' => false,
'fix' => false,
'help' => false
),
array(
'h' => 'help',
'c' => 'courses',
'f' => 'fix'
)
);
if ($options['help'] || empty($options['courses'])) {
$help =
"Checks and fixes that course modules and sections reference each other correctly.
Compares DB fields course_sections.sequence and course_modules.section
checking that:
- course_sections.sequence contains each module id not more than once in the course
- for each moduleid from course_sections.sequence the field course_modules.section
refers to the same section id (this means course_sections.sequence is more
important if they are different)
- each module in the course is present in one of course_sections.sequence
- section sequences do not contain non-existing course modules
If there are any mismatches, the message is displayed. If --fix is specified,
the records in DB are corrected.
This script may run for a long time on big systems if called for all courses.
Avoid executing the script when another user may simultaneously edit any of the
courses being checked (recommended to run in mainenance mode).
Options:
-c, --courses List courses that need to be checked (comma-separated
values or * for all). Required
-f, --fix Fix the mismatches in DB. If not specified check only and
report problems to STDERR
-h, --help Print out this help
Example:
\$sudo -u www-data /usr/bin/php admin/cli/fix_course_sequence.php --courses=*
\$sudo -u www-data /usr/bin/php admin/cli/fix_course_sequence.php --courses=2,3,4 --fix
";
echo $help;
die;
}
$courseslist = preg_split('/\s*,\s*/', $options['courses'], -1, PREG_SPLIT_NO_EMPTY);
if (in_array('*', $courseslist)) {
$where = '';
$params = array();
} else {
list($sql, $params) = $DB->get_in_or_equal($courseslist, SQL_PARAMS_NAMED, 'id');
$where = 'WHERE id '. $sql;
}
$coursescount = $DB->get_field_sql('SELECT count(id) FROM {course} '. $where, $params);
if (!$coursescount) {
cli_error('No courses found');
}
echo "Checking $coursescount courses...\n\n";
require_once($CFG->dirroot. '/course/lib.php');
$problems = array();
$courses = $DB->get_fieldset_sql('SELECT id FROM {course} '. $where, $params);
foreach ($courses as $courseid) {
$errors = course_integrity_check($courseid, null, null, true, empty($options['fix']));
if ($errors) {
if (!empty($options['fix'])) {
// Reset the course cache to make sure cache is recalculated next time the course is viewed.
rebuild_course_cache($courseid, true);
}
foreach ($errors as $error) {
cli_problem($error);
}
$problems[] = $courseid;
} else {
echo "Course [$courseid] is OK\n";
}
}
if (!count($problems)) {
echo "\n...All courses are OK\n";
} else {
if (!empty($options['fix'])) {
echo "\n...Found and fixed ".count($problems)." courses with problems". "\n";
} else {
echo "\n...Found ".count($problems)." courses with problems. To fix run:\n";
echo "\$sudo -u www-data /usr/bin/php admin/cli/fix_course_sequence.php --courses=".join(',', $problems)." --fix". "\n";
}
}
-92
View File
@@ -1,92 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This script fixed incorrectly deleted users.
*
* @package core
* @subpackage cli
* @copyright 2013 Petr Skoda (http://skodak.org)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
// Now get cli options.
list($options, $unrecognized) = cli_get_params(array('help'=>false),
array('h'=>'help'));
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help']) {
$help =
"Fix incorrectly deleted users.
This scripts detects users that are marked as deleted instead
of calling delete_user().
Deleted users do not have original username, idnumber or email,
we must also delete all roles, enrolments, group memberships, etc.
Please note this script does not delete any public information
such as forum posts.
Options:
-h, --help Print out this help
Example:
\$sudo -u www-data /usr/bin/php admin/cli/fix_deleted_users.php
";
echo $help;
die;
}
cli_heading('Looking for sloppy user deletes');
// Look for sloppy deleted users where somebody only flipped the deleted flag.
$sql = "SELECT *
FROM {user}
WHERE deleted = 1 AND email LIKE '%@%' AND username NOT LIKE '%@%'";
$rs = $DB->get_recordset_sql($sql);
foreach ($rs as $user) {
echo "Redeleting user $user->id: $user->username ($user->email)\n";
delete_user($user);
}
$rs->close();
cli_heading('Deleting all leftovers');
$DB->set_field('user', 'idnumber', '', array('deleted'=>1));
$DB->delete_records_select('role_assignments', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
$DB->delete_records_select('cohort_members', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
$DB->delete_records_select('groups_members', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
$DB->delete_records_select('user_enrolments', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
$DB->delete_records_select('user_preferences', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
$DB->delete_records_select('user_info_data', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
$DB->delete_records_select('user_lastaccess', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
$DB->delete_records_select('external_tokens', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
$DB->delete_records_select('external_services_users', "userid IN (SELECT id FROM {user} WHERE deleted = 1)");
exit(0);
-138
View File
@@ -1,138 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Fix orphaned calendar events that were broken by MDL-67494.
*
* This script will look for all the calendar events which userids
* where broken by a wrong upgrade step, affecting to Moodle 3.9.5
* and up.
*
* It performs checks to both:
* a) Detect if the site was affected (ran the wrong upgrade step).
* b) Look for orphaned calendar events, categorising them as:
* - standard: site / category / course / group / user events
* - subscription: events created via subscriptions.
* - action: normal action events, created to show common important dates.
* - override: user and group override events, particular, that some activities support.
* - custom: other events, not being any of the above, common or particular.
* By specifying it (--fix) try to recover as many broken events (missing userid) as
* possible. Standard, subscription, action, override events in core are fully supported but
* override or custom events should be fixed by each plugin as far as there isn't any standard
* API (plugin-wise) to launch a rebuild of the calendar events.
*
* @package core
* @copyright 2021 onwards Simey Lameze <simey@moodle.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require_once(__DIR__ . '/../../config.php');
require_once($CFG->libdir . "/clilib.php");
require_once($CFG->libdir . '/db/upgradelib.php');
// Supported options.
$long = ['fix' => false, 'help' => false];
$short = ['f' => 'fix', 'h' => 'help'];
// CLI options.
[$options, $unrecognized] = cli_get_params($long, $short);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help']) {
$help = <<<EOT
Fix orphaned calendar events.
This script detects calendar events that have had their
userid lost. By default it will perform various checks
and report them, showing the site status in an easy way.
Also, optionally (--fix), it wil try to recover as many
lost userids as possible from different sources. Note that
this script aims to process well-know events in core,
leaving custom events in 3rd part plugins mostly unmodified
because there isn't any consistent way to regenerate them.
For more details: https://tracker.moodle.org/browse/MDL-71156
Options:
-h, --help Print out this help.
-f, --fix Fix the orphaned calendar events in the DB.
If not specified only check and report problems to STDERR.
Usage:
- Only report: \$ sudo -u www-data /usr/bin/php admin/cli/fix_orphaned_calendar_events.php
- Report and fix: \$ sudo -u www-data /usr/bin/php admin/cli/fix_orphaned_calendar_events.php -f
EOT;
cli_writeln($help);
die;
}
// Check various usual pre-requisites.
if (empty($CFG->version)) {
cli_error('Database is not yet installed.');
}
$admin = get_admin();
if (!$admin) {
cli_error('Error: No admin account was found.');
}
if (moodle_needs_upgrading()) {
cli_error('Moodle upgrade pending, script execution suspended.');
}
// Do everything as admin by default.
\core\session\manager::set_user($admin);
// Report current site status.
cli_heading('Checking the site status');
$needsfix = upgrade_calendar_site_status();
// Report current calendar events status.
cli_heading('Checking the calendar events status');
$info = upgrade_calendar_events_status();
$hasbadevents = $info['total']->bad > 0 || $info['total']->bad != $info['other']->bad;
$needsfix = $needsfix || $hasbadevents;
// If, selected, fix as many calendar events as possible.
if ($options['fix']) {
// If the report has told us that the fix was not needed... ask for confirmation!
if (!$needsfix) {
cli_writeln("This site DOES NOT NEED to run the calendar events fix.");
$input = cli_input('Are you completely sure that you want to run the fix? (y/N)', 'N', ['y', 'Y', 'n', 'N']);
if (strtolower($input) != 'y') {
exit(0);
}
cli_writeln("");
}
cli_heading('Fixing as many as possible calendar events');
upgrade_calendar_events_fix_remaining($info);
// Report current (after fix) calendar events status.
cli_heading('Checking the calendar events status (after fix)');
upgrade_calendar_events_status();
} else if ($needsfix) {
// Fix option was not provided but problem events have been found. Notify the user and provide info how to fix these events.
cli_writeln("This site NEEDS to run the calendar events fix!");
cli_writeln("To fix the calendar events, re-run this script with the --fix option.");
}
@@ -1,103 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This script fixes orphaned question categories.
*
* Orphaned question categories have had their associated context deleted
* but the category itself remains in the database with an invalid context.
*
* @package core
* @subpackage cli
* @copyright 2013 Tyler Bannister (tyler.bannister@remote-learner.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
require_once($CFG->libdir.'/questionlib.php');
$long = array('fix' => false, 'help' => false);
$short = array('f' => 'fix', 'h' => 'help');
// Now get cli options.
list($options, $unrecognized) = cli_get_params($long, $short);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help']) {
$help =
"Fix orphaned question categories.
This scripts detects question categories that have had their
context deleted, thus severing them from their original purpose.
This script will find the orphaned categories and delete the unused
questions in each category found. Used questions will not be
deleted, instead they will be moved to a rescue question category.
Options:
-h, --help Print out this help
-f, --fix Fix the orphaned question categories in the DB.
If not specified only check and report problems to STDERR.
Example:
\$sudo -u www-data /usr/bin/php admin/cli/fix_orphaned_question_categories.php
\$sudo -u www-data /usr/bin/php admin/cli/fix_orphaned_question_categories.php -f
";
echo $help;
die;
}
cli_heading('Checking for orphaned categories');
$sql = 'SELECT qc.id, qc.contextid, qc.name
FROM {question_categories} qc
LEFT JOIN {context} c ON qc.contextid = c.id
WHERE c.id IS NULL';
$categories = $DB->get_recordset_sql($sql);
$i = 0;
foreach ($categories as $category) {
$i += 1;
echo "Found orphaned category: {$category->name}\n";
if (!empty($options['fix'])) {
echo "Cleaning...";
// One transaction per category.
$transaction = $DB->start_delegated_transaction();
question_category_delete_safe($category);
$transaction->allow_commit();
echo " Done!\n";
}
}
if (($i > 0) && !empty($options['fix'])) {
echo "Found and removed {$i} orphaned question categories\n";
} else if ($i > 0) {
echo "Found {$i} orphaned question categories. To fix, run:\n";
echo "\$sudo -u www-data /usr/bin/php admin/cli/fix_orphaned_question_categories.php --fix\n";
} else {
echo "No orphaned question categories found.\n";
}
$categories->close();
-79
View File
@@ -1,79 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Generates a secure key for the current server (presuming it does not already exist).
*
* @package core_admin
* @copyright 2020 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
use \core\encryption;
define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/clilib.php');
// Get cli options.
[$options, $unrecognized] = cli_get_params(
['help' => false, 'method' => null],
['h' => 'help']);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
// TODO: MDL-71421 - Remove the openssl alternative once sodium becomes a requirement in Moodle 4.2.
if ($options['help']) {
echo "Generate secure key
This script manually creates a secure key within the secret data root folder (configured in
config.php as \$CFG->secretdataroot). You must run it using an account with access to write
to that folder.
In normal use Moodle automatically creates the key; this script is intended when setting up
a new Moodle system, for cases where the secure folder is not on shared storage and the key
may be manually installed on multiple servers.
Options:
-h, --help Print out this help
--method <method> Generate key for specified encryption method instead of default.
* sodium
* openssl-aes-256-ctr
Example:
php admin/cli/generate_key.php
";
exit;
}
$method = $options['method'];
if (encryption::key_exists($method)) {
echo 'Key already exists: ' . encryption::get_key_file($method) . "\n";
exit;
}
// Creates key with default permissions (no chmod).
echo "Generating key...\n";
encryption::create_key($method, false);
echo "\nKey created: " . encryption::get_key_file($method) . "\n\n";
echo "If the key folder is not shared storage, then key files should be copied to all servers.\n";
+176 -351
View File
@@ -36,12 +36,6 @@ if (isset($_SERVER['REMOTE_ADDR'])) {
exit(1);
}
// Force OPcache reset if used, we do not want any stale caches
// when preparing test environment.
if (function_exists('opcache_reset')) {
opcache_reset();
}
$help =
"Command line Moodle installer, creates config.php and initializes database.
Please note you must execute this script with the same uid as apache
@@ -64,26 +58,19 @@ Options:
--dbname=NAME Database name. Default is moodle
--dbuser=USERNAME Database user. Default is root
--dbpass=PASSWORD Database password. Default is blank
--dbport=NUMBER Use database port.
--dbsocket=PATH Use database socket, 1 means default. Available for some databases only.
--dbsocket Use database sockets. Available for some databases only.
--prefix=STRING Table prefix for above database tables. Default is mdl_
--fullname=STRING The fullname of the site
--shortname=STRING The shortname of the site
--summary=STRING The summary to be displayed on the front page
--adminuser=USERNAME Username for the moodle admin account. Default is admin
--adminpass=PASSWORD Password for the moodle admin account,
required in non-interactive mode.
--adminemail=STRING Email address for the moodle admin account.
--sitepreset=STRING Admin site preset to be applied during the installation process.
--supportemail=STRING Email address for support and help.
--upgradekey=STRING The upgrade key to be set in the config.php, leave empty to not set it.
--non-interactive No interactive questions, installation fails if any
problem encountered.
--agree-license Indicates agreement with software license,
required in non-interactive mode.
--allow-unstable Install even if the version is not marked as stable yet,
required in non-interactive mode.
--skip-database Stop the installation before installing the database.
-h, --help Print out this help
Example:
@@ -92,7 +79,7 @@ Example:
// distro specific customisation
$distrolibfile = __DIR__.'/../../install/distrolib.php';
$distrolibfile = dirname(dirname(dirname(__FILE__))).'/install/distrolib.php';
$distro = null;
if (file_exists($distrolibfile)) {
require_once($distrolibfile);
@@ -102,7 +89,7 @@ if (file_exists($distrolibfile)) {
}
// Nothing to do if config.php exists
$configfile = __DIR__.'/../../config.php';
$configfile = dirname(dirname(dirname(__FILE__))).'/config.php';
if (file_exists($configfile)) {
require($configfile);
require_once($CFG->libdir.'/clilib.php');
@@ -126,11 +113,10 @@ $olddir = getcwd();
chdir(dirname($_SERVER['argv'][0]));
// Servers should define a default timezone in php.ini, but if they don't then make sure something is defined.
if (!function_exists('date_default_timezone_set') or !function_exists('date_default_timezone_get')) {
fwrite(STDERR, "Timezone functions are not available.\n");
exit(1);
// This is a quick hack. Ideally we should ask the admin for a value. See MDL-22625 for more on this.
if (function_exists('date_default_timezone_set') and function_exists('date_default_timezone_get')) {
@date_default_timezone_set(@date_default_timezone_get());
}
date_default_timezone_set(@date_default_timezone_get());
// make sure PHP errors are displayed - helps with diagnosing of problems
@error_reporting(E_ALL);
@@ -141,49 +127,40 @@ date_default_timezone_set(@date_default_timezone_get());
/** Used by library scripts to check they are being called by Moodle */
define('MOODLE_INTERNAL', true);
// Disables all caching.
// Disables caching.. just in case.
define('CACHE_DISABLE_ALL', true);
define('PHPUNIT_TEST', false);
define('IGNORE_COMPONENT_CACHE', true);
// Check that PHP is of a sufficient version as soon as possible.
require_once(__DIR__.'/../../lib/phpminimumversionlib.php');
moodle_require_minimum_php_version();
// Check that PHP is of a sufficient version
if (version_compare(phpversion(), "5.3.2") < 0) {
$phpversion = phpversion();
// do NOT localise - lang strings would not work here and we CAN NOT move it after installib
fwrite(STDERR, "Moodle 2.1 or later requires at least PHP 5.3.2 (currently using version $phpversion).\n");
fwrite(STDERR, "Please upgrade your server software or install older Moodle version.\n");
exit(1);
}
// set up configuration
global $CFG;
$CFG = new stdClass();
$CFG->lang = 'en';
$CFG->dirroot = dirname(dirname(__DIR__));
$CFG->dirroot = dirname(dirname(dirname(__FILE__)));
$CFG->libdir = "$CFG->dirroot/lib";
$CFG->wwwroot = "http://localhost";
$CFG->httpswwwroot = $CFG->wwwroot;
$CFG->docroot = 'http://docs.moodle.org';
$CFG->running_installer = true;
$CFG->early_install_lang = true;
$CFG->ostype = (stristr(PHP_OS, 'win') && !stristr(PHP_OS, 'darwin')) ? 'WINDOWS' : 'UNIX';
$CFG->dboptions = array();
$CFG->debug = (E_ALL | E_STRICT);
$CFG->debugdisplay = true;
$CFG->debugdeveloper = true;
$parts = explode('/', str_replace('\\', '/', dirname(__DIR__)));
$parts = explode('/', str_replace('\\', '/', dirname(dirname(__FILE__))));
$CFG->admin = array_pop($parts);
//point pear include path to moodles lib/pear so that includes and requires will search there for files before anywhere else
//the problem is that we need specific version of quickforms and hacked excel files :-(
ini_set('include_path', $CFG->libdir.'/pear' . PATH_SEPARATOR . ini_get('include_path'));
require_once($CFG->libdir.'/classes/component.php');
require_once($CFG->libdir.'/classes/text.php');
require_once($CFG->libdir.'/classes/string_manager.php');
require_once($CFG->libdir.'/classes/string_manager_install.php');
require_once($CFG->libdir.'/classes/string_manager_standard.php');
require_once($CFG->libdir.'/installlib.php');
require_once($CFG->libdir.'/clilib.php');
require_once($CFG->libdir.'/setuplib.php');
require_once($CFG->libdir.'/textlib.class.php');
require_once($CFG->libdir.'/weblib.php');
require_once($CFG->libdir.'/dmllib.php');
require_once($CFG->libdir.'/moodlelib.php');
@@ -192,36 +169,15 @@ require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/componentlib.class.php');
require_once($CFG->dirroot.'/cache/lib.php');
// Register our classloader, in theory somebody might want to replace it to load other hacked core classes.
// Required because the database checks below lead to session interaction which is going to lead us to requiring autoloaded classes.
if (defined('COMPONENT_CLASSLOADER')) {
spl_autoload_register(COMPONENT_CLASSLOADER);
} else {
spl_autoload_register('core_component::classloader');
}
require($CFG->dirroot.'/version.php');
$CFG->target_release = $release;
\core\session\manager::init_empty_session();
global $SESSION;
global $USER;
global $COURSE;
$COURSE = new stdClass();
$COURSE->id = 1;
global $SITE;
$SITE = $COURSE;
define('SITEID', 1);
//Database types
$databases = array('mysqli' => moodle_database::get_driver_instance('mysqli', 'native'),
'auroramysql' => moodle_database::get_driver_instance('auroramysql', 'native'),
'mariadb'=> moodle_database::get_driver_instance('mariadb', 'native'),
'pgsql' => moodle_database::get_driver_instance('pgsql', 'native'),
'oci' => moodle_database::get_driver_instance('oci', 'native'),
'sqlsrv' => moodle_database::get_driver_instance('sqlsrv', 'native'), // MS SQL*Server PHP driver
'mssql' => moodle_database::get_driver_instance('mssql', 'native'), // FreeTDS driver
);
foreach ($databases as $type=>$database) {
if ($database->driver_installed() !== true) {
@@ -241,28 +197,21 @@ list($options, $unrecognized) = cli_get_params(
'chmod' => isset($distro->directorypermissions) ? sprintf('%04o',$distro->directorypermissions) : '2777', // let distros set dir permissions
'lang' => $CFG->lang,
'wwwroot' => '',
'dataroot' => empty($distro->dataroot) ? str_replace('\\', '/', dirname(dirname(dirname(__DIR__))).'/moodledata'): $distro->dataroot, // initialised later after including libs or by distro
'dataroot' => empty($distro->dataroot) ? str_replace('\\', '/', dirname(dirname(dirname(dirname(__FILE__)))).'/moodledata'): $distro->dataroot, // initialised later after including libs or by distro
'dbtype' => empty($distro->dbtype) ? $defaultdb : $distro->dbtype, // let distro skip dbtype selection
'dbhost' => empty($distro->dbhost) ? 'localhost' : $distro->dbhost, // let distros set dbhost
'dbname' => 'moodle',
'dbuser' => empty($distro->dbuser) ? 'root' : $distro->dbuser, // let distros set dbuser
'dbpass' => '',
'dbport' => '',
'dbsocket' => '',
'dbsocket' => false,
'prefix' => 'mdl_',
'fullname' => '',
'shortname' => '',
'summary' => '',
'adminuser' => 'admin',
'adminpass' => '',
'adminemail' => '',
'sitepreset' => '',
'supportemail' => '',
'upgradekey' => '',
'non-interactive' => false,
'agree-license' => false,
'allow-unstable' => false,
'skip-database' => false,
'help' => false
),
array(
@@ -271,21 +220,13 @@ list($options, $unrecognized) = cli_get_params(
);
$interactive = empty($options['non-interactive']);
$skipdatabase = $options['skip-database'];
// set up language
$lang = clean_param($options['lang'], PARAM_SAFEDIR);
$languages = get_string_manager()->get_list_of_translations();
if (array_key_exists($lang, $languages)) {
if (file_exists($CFG->dirroot.'/install/lang/'.$lang)) {
$CFG->lang = $lang;
}
// Set up site admin preset.
$sitepreset = clean_param($options['sitepreset'], PARAM_RAW);
if (!empty($sitepreset)) {
$CFG->setsitepresetduringinstall = $sitepreset;
}
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
@@ -297,41 +238,28 @@ if ($options['help']) {
}
//Print header
cli_logo();
echo PHP_EOL;
echo get_string('cliinstallheader', 'install', $CFG->target_release)."\n";
//Fist select language
if ($interactive) {
cli_separator();
$languages = get_string_manager()->get_list_of_translations();
// Do not put the langs into columns because it is not compatible with RTL.
$langlist = implode("\n", $languages);
$default = $CFG->lang;
cli_heading(get_string('chooselanguagehead', 'install'));
if (array_key_exists($default, $languages)) {
echo $default.' - '.$languages[$default]."\n";
}
if ($default !== 'en') {
echo 'en - English (en)'."\n";
}
echo '? - '.get_string('availablelangs', 'install')."\n";
cli_heading(get_string('availablelangs', 'install'));
echo $langlist."\n";
$prompt = get_string('clitypevaluedefault', 'admin', $CFG->lang);
$error = '';
do {
echo $error;
$input = cli_input($prompt, $default);
$input = clean_param($input, PARAM_SAFEDIR);
if ($input === '?') {
echo implode("\n", $languages)."\n";
$error = "\n";
if (!file_exists($CFG->dirroot.'/install/lang/'.$input)) {
$error = get_string('cliincorrectvalueretry', 'admin')."\n";
} else {
$input = clean_param($input, PARAM_SAFEDIR);
if (!array_key_exists($input, $languages)) {
$error = get_string('cliincorrectvalueretry', 'admin')."\n";
} else {
$error = '';
}
$error = '';
}
} while ($error !== '');
$CFG->lang = $input;
@@ -365,8 +293,6 @@ if ($interactive) {
}
}
$CFG->directorypermissions = $chmod;
$CFG->filepermissions = ($CFG->directorypermissions & 0666);
$CFG->umaskpermissions = (($CFG->directorypermissions & 0777) ^ 0777);
//We need wwwroot before we test dataroot
$wwwroot = clean_param($options['wwwroot'], PARAM_URL);
@@ -403,6 +329,7 @@ if ($interactive) {
$CFG->wwwroot = $wwwroot;
$CFG->httpswwwroot = $CFG->wwwroot;
//We need dataroot before lang download
$CFG->dataroot = $options['dataroot'];
if ($interactive) {
@@ -452,10 +379,8 @@ if ($interactive) {
cli_error(get_string('pathserrcreatedataroot', 'install', $a));
}
}
$CFG->tempdir = $CFG->dataroot.'/temp';
$CFG->backuptempdir = $CFG->tempdir.'/backup';
$CFG->cachedir = $CFG->dataroot.'/cache';
$CFG->localcachedir = $CFG->dataroot.'/localcache';
$CFG->tempdir = $CFG->dataroot.'/temp';
$CFG->cachedir = $CFG->dataroot.'/cache';
// download required lang packs
if ($CFG->lang !== 'en') {
@@ -525,105 +450,72 @@ if ($interactive) {
$database = $databases[$CFG->dbtype];
// We cannot do any validation until all DB connection data is provided.
$hintdatabase = '';
do {
echo $hintdatabase;
// Ask for db host.
if ($interactive) {
cli_separator();
cli_heading(get_string('databasehost', 'install'));
if ($options['dbhost'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['dbhost']);
} else {
$prompt = get_string('clitypevalue', 'admin');
}
$CFG->dbhost = cli_input($prompt, $options['dbhost']);
// ask for db host
if ($interactive) {
cli_separator();
cli_heading(get_string('databasehost', 'install'));
if ($options['dbhost'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['dbhost']);
} else {
$CFG->dbhost = $options['dbhost'];
$prompt = get_string('clitypevalue', 'admin');
}
$CFG->dbhost = cli_input($prompt, $options['dbhost']);
// Ask for db name.
if ($interactive) {
cli_separator();
cli_heading(get_string('databasename', 'install'));
if ($options['dbname'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['dbname']);
} else {
$prompt = get_string('clitypevalue', 'admin');
}
$CFG->dbname = cli_input($prompt, $options['dbname']);
} else {
$CFG->dbhost = $options['dbhost'];
}
// ask for db name
if ($interactive) {
cli_separator();
cli_heading(get_string('databasename', 'install'));
if ($options['dbname'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['dbname']);
} else {
$CFG->dbname = $options['dbname'];
$prompt = get_string('clitypevalue', 'admin');
}
$CFG->dbname = cli_input($prompt, $options['dbname']);
// Ask for db prefix.
if ($interactive) {
cli_separator();
cli_heading(get_string('dbprefix', 'install'));
//TODO: solve somehow the prefix trouble for oci.
if ($options['prefix'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['prefix']);
} else {
$prompt = get_string('clitypevalue', 'admin');
}
$CFG->prefix = cli_input($prompt, $options['prefix']);
} else {
$CFG->dbname = $options['dbname'];
}
// ask for db prefix
if ($interactive) {
cli_separator();
cli_heading(get_string('dbprefix', 'install'));
//TODO: solve somehow the prefix trouble for oci
if ($options['prefix'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['prefix']);
} else {
$CFG->prefix = $options['prefix'];
$prompt = get_string('clitypevalue', 'admin');
}
$CFG->prefix = cli_input($prompt, $options['prefix']);
// Ask for db port.
if ($interactive) {
cli_separator();
cli_heading(get_string('databaseport', 'install'));
$prompt = get_string('clitypevaluedefault', 'admin', $options['dbport']);
$CFG->dboptions['dbport'] = (int) cli_input($prompt, $options['dbport']);
} else {
$CFG->prefix = $options['prefix'];
}
// ask for db user
if ($interactive) {
cli_separator();
cli_heading(get_string('databaseuser', 'install'));
if ($options['dbuser'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['dbuser']);
} else {
$CFG->dboptions['dbport'] = (int) $options['dbport'];
}
if ($CFG->dboptions['dbport'] <= 0) {
$CFG->dboptions['dbport'] = '';
$prompt = get_string('clitypevalue', 'admin');
}
$CFG->dbuser = cli_input($prompt, $options['dbuser']);
// Ask for db socket.
if ($CFG->ostype === 'WINDOWS') {
$CFG->dboptions['dbsocket'] = '';
} else if ($interactive and empty($CFG->dboptions['dbport'])) {
cli_separator();
cli_heading(get_string('databasesocket', 'install'));
$prompt = get_string('clitypevaluedefault', 'admin', $options['dbsocket']);
$CFG->dboptions['dbsocket'] = cli_input($prompt, $options['dbsocket']);
} else {
$CFG->dboptions['dbsocket'] = $options['dbsocket'];
}
// Ask for db user.
if ($interactive) {
cli_separator();
cli_heading(get_string('databaseuser', 'install'));
if ($options['dbuser'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['dbuser']);
} else {
$prompt = get_string('clitypevalue', 'admin');
}
$CFG->dbuser = cli_input($prompt, $options['dbuser']);
} else {
$CFG->dbuser = $options['dbuser'];
}
// Ask for db password.
if ($interactive) {
cli_separator();
cli_heading(get_string('databasepass', 'install'));
} else {
$CFG->dbuser = $options['dbuser'];
}
// ask for db password
if ($interactive) {
cli_separator();
cli_heading(get_string('databasepass', 'install'));
do {
if ($options['dbpass'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['dbpass']);
} else {
@@ -631,171 +523,113 @@ do {
}
$CFG->dbpass = cli_input($prompt, $options['dbpass']);
if (function_exists('distro_pre_create_db')) { // Hook for distros needing to do something before DB creation.
$distro = distro_pre_create_db($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix,
array('dbpersist' => 0, 'dbport' => $CFG->dboptions['dbport'], 'dbsocket' => $CFG->dboptions['dbsocket']),
$distro);
if (function_exists('distro_pre_create_db')) { // Hook for distros needing to do something before DB creation
$distro = distro_pre_create_db($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbsocket'=>$options['dbsocket']), $distro);
}
$hintdatabase = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix,
array('dbpersist' => 0, 'dbport' => $CFG->dboptions['dbport'], 'dbsocket' => $CFG->dboptions['dbsocket']));
$hint_database = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbsocket'=>$options['dbsocket']));
} while ($hint_database !== '');
} else {
$CFG->dbpass = $options['dbpass'];
$hintdatabase = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix,
array('dbpersist' => 0, 'dbport' => $CFG->dboptions['dbport'], 'dbsocket' => $CFG->dboptions['dbsocket']));
if ($hintdatabase !== '') {
cli_error(get_string('dbconnectionerror', 'install'));
}
}
} while ($hintdatabase !== '');
// If --skip-database option is provided, we do not need to ask for site fullname, shortname, adminuser, adminpass, adminemail.
// These fields will be requested during the database install part.
if (!$skipdatabase) {
// Ask for fullname.
if ($interactive) {
cli_separator();
cli_heading(get_string('fullsitename', 'moodle'));
if ($options['fullname'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['fullname']);
} else {
$prompt = get_string('clitypevalue', 'admin');
}
do {
$options['fullname'] = cli_input($prompt, $options['fullname']);
} while (empty($options['fullname']));
} else {
if (empty($options['fullname'])) {
$a = (object)['option' => 'fullname', 'value' => $options['fullname']];
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
}
// Ask for shortname.
if ($interactive) {
cli_separator();
cli_heading(get_string('shortsitename', 'moodle'));
if ($options['shortname'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
} else {
$prompt = get_string('clitypevalue', 'admin');
}
do {
$options['shortname'] = cli_input($prompt, $options['shortname']);
} while (empty($options['shortname']));
} else {
if (empty($options['shortname'])) {
$a = (object)['option' => 'shortname', 'value' => $options['shortname']];
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
}
// Ask for admin user name.
if ($interactive) {
cli_separator();
cli_heading(get_string('cliadminusername', 'install'));
if (!empty($options['adminuser'])) {
$prompt = get_string('clitypevaluedefault', 'admin', $options['adminuser']);
} else {
$prompt = get_string('clitypevalue', 'admin');
}
do {
$options['adminuser'] = cli_input($prompt, $options['adminuser']);
} while (empty($options['adminuser']) or $options['adminuser'] === 'guest');
} else {
if ((empty($options['adminuser']) || $options['adminuser'] === 'guest')) {
$a = (object)['option' => 'adminuser', 'value' => $options['adminuser']];
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
}
// Ask for admin user password.
if ($interactive) {
cli_separator();
cli_heading(get_string('cliadminpassword', 'install'));
$prompt = get_string('clitypevalue', 'admin');
do {
$options['adminpass'] = cli_input($prompt);
} while (empty($options['adminpass']) or $options['adminpass'] === 'admin');
} else {
if ((empty($options['adminpass']) or $options['adminpass'] === 'admin')) {
$a = (object)['option' => 'adminpass', 'value' => $options['adminpass']];
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
}
// Ask for the admin email address.
if ($interactive) {
cli_separator();
cli_heading(get_string('cliadminemail', 'install'));
$prompt = get_string('clitypevaluedefault', 'admin', $options['adminemail']);
$options['adminemail'] = cli_input($prompt, $options['adminemail']);
}
// Validate that the address provided was an e-mail address.
if (!empty($options['adminemail']) && !validate_email($options['adminemail'])) {
$a = (object)['option' => 'adminemail', 'value' => $options['adminemail']];
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
// Ask for the support email address.
if ($interactive) {
cli_separator();
cli_heading(get_string('clisupportemail', 'install'));
$prompt = get_string('clitypevaluedefault', 'admin', $options['supportemail']);
$options['supportemail'] = cli_input($prompt, $options['supportemail']);
}
// Validate that the support email address provided is valid.
if (!empty($options['supportemail']) && !validate_email($options['supportemail'])) {
$a = (object)['option' => 'supportemail', 'value' => $options['supportemail']];
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
} else {
$CFG->dbpass = $options['dbpass'];
$hint_database = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbsocket'=>$options['dbsocket']));
if ($hint_database !== '') {
cli_error(get_string('dbconnectionerror', 'install'));
}
}
// Ask for the upgrade key.
// ask for fullname
if ($interactive) {
cli_separator();
cli_heading(get_string('upgradekeyset', 'admin'));
if ($options['upgradekey'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['upgradekey']);
$options['upgradekey'] = cli_input($prompt, $options['upgradekey']);
cli_heading(get_string('fullsitename', 'moodle'));
if ($options['fullname'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['fullname']);
} else {
$prompt = get_string('clitypevalue', 'admin');
$options['upgradekey'] = cli_input($prompt);
}
do {
$options['fullname'] = cli_input($prompt, $options['fullname']);
} while (empty($options['fullname']));
} else {
if (empty($options['fullname'])) {
$a = (object)array('option'=>'fullname', 'value'=>$options['fullname']);
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
}
// Set the upgrade key if it was provided.
if ($options['upgradekey'] !== '') {
$CFG->upgradekey = $options['upgradekey'];
// ask for shortname
if ($interactive) {
cli_separator();
cli_heading(get_string('shortsitename', 'moodle'));
if ($options['shortname'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
} else {
$prompt = get_string('clitypevalue', 'admin');
}
do {
$options['shortname'] = cli_input($prompt, $options['shortname']);
} while (empty($options['shortname']));
} else {
if (empty($options['shortname'])) {
$a = (object)array('option'=>'shortname', 'value'=>$options['shortname']);
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
}
// The user does not also need to pass agree-license when --skip-database is provided as the user will need to accept
// the license again in the database install part.
if (!$skipdatabase) {
if ($interactive) {
if (!$options['agree-license']) {
cli_separator();
cli_heading(get_string('copyrightnotice'));
echo "Moodle - Modular Object-Oriented Dynamic Learning Environment\n";
echo get_string('gpl3')."\n\n";
echo get_string('doyouagree')."\n";
$prompt = get_string('cliyesnoprompt', 'admin');
$input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
if ($input == get_string('clianswerno', 'admin')) {
exit(1);
}
}
// ask for admin user name
if ($interactive) {
cli_separator();
cli_heading(get_string('cliadminusername', 'install'));
if (!empty($options['adminuser'])) {
$prompt = get_string('clitypevaluedefault', 'admin', $options['adminuser']);
} else {
if (!$options['agree-license'] && !$skipdatabase) {
cli_error(get_string('climustagreelicense', 'install'));
$prompt = get_string('clitypevalue', 'admin');
}
do {
$options['adminuser'] = cli_input($prompt, $options['adminuser']);
} while (empty($options['adminuser']) or $options['adminuser'] === 'guest');
} else {
if (empty($options['adminuser']) or $options['adminuser'] === 'guest') {
$a = (object)array('option'=>'adminuser', 'value'=>$options['adminuser']);
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
}
// ask for admin user password
if ($interactive) {
cli_separator();
cli_heading(get_string('cliadminpassword', 'install'));
$prompt = get_string('clitypevalue', 'admin');
do {
$options['adminpass'] = cli_input($prompt);
} while (empty($options['adminpass']) or $options['adminpass'] === 'admin');
} else {
if (empty($options['adminpass']) or $options['adminpass'] === 'admin') {
$a = (object)array('option'=>'adminpass', 'value'=>$options['adminpass']);
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
}
if ($interactive) {
if (!$options['agree-license']) {
cli_separator();
cli_heading(get_string('copyrightnotice'));
echo "Moodle - Modular Object-Oriented Dynamic Learning Environment\n";
echo get_string('gpl3')."\n\n";
echo get_string('doyouagree')."\n";
$prompt = get_string('cliyesnoprompt', 'admin');
$input = cli_input($prompt, '', array(get_string('clianswerno', 'admin'), get_string('cliansweryes', 'admin')));
if ($input == get_string('clianswerno', 'admin')) {
exit(1);
}
}
} else {
if (!$options['agree-license']) {
cli_error(get_string('climustagreelicense', 'install'));
}
}
// Finally we have all info needed for config.php
@@ -837,23 +671,14 @@ if (!$envstatus) {
}
// Test plugin dependencies.
require_once($CFG->libdir . '/pluginlib.php');
$failed = array();
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
if (!plugin_manager::instance()->all_plugins_ok($version, $failed)) {
cli_problem(get_string('pluginscheckfailed', 'admin', array('pluginslist' => implode(', ', array_unique($failed)))));
cli_error(get_string('pluginschecktodo', 'admin'));
}
if (!$skipdatabase) {
install_cli_database($options, $interactive);
// This needs to happen at the end to ensure it occurs after all caches
// have been purged for the last time.
// This will build a cached version of the current theme for the user
// to immediately start browsing the site.
require_once($CFG->libdir.'/upgradelib.php');
upgrade_themes();
} else {
echo get_string('cliskipdatabase', 'install')."\n";
}
install_cli_database($options, $interactive);
echo get_string('cliinstallfinished', 'install')."\n";
exit(0); // 0 means success
+16 -39
View File
@@ -29,19 +29,12 @@
*/
define('CLI_SCRIPT', true);
define('CACHE_DISABLE_ALL', true);
// extra execution prevention - we can not just require config.php here
if (isset($_SERVER['REMOTE_ADDR'])) {
exit(1);
}
// Force OPcache reset if used, we do not want any stale caches
// when preparing test environment.
if (function_exists('opcache_reset')) {
opcache_reset();
}
$help =
"Advanced command line Moodle database installer.
Please note you must execute this script with the same uid as apache.
@@ -52,23 +45,26 @@ Options:
--lang=CODE Installation and default site language. Default is en.
--adminuser=USERNAME Username for the moodle admin account. Default is admin.
--adminpass=PASSWORD Password for the moodle admin account.
--adminemail=STRING Email address for the moodle admin account.
--agree-license Indicates agreement with software license.
--fullname=STRING Name of the site
--shortname=STRING Name of the site
--summary=STRING The summary to be displayed on the front page
-h, --help Print out this help
Example:
\$sudo -u www-data /usr/bin/php admin/cli/install_database.php --lang=cs --adminpass=soMePass123 --agree-license
";
// Check that PHP is of a sufficient version as soon as possible.
require_once(__DIR__.'/../../lib/phpminimumversionlib.php');
moodle_require_minimum_php_version();
// Check that PHP is of a sufficient version
if (version_compare(phpversion(), "5.3.2") < 0) {
$phpversion = phpversion();
// do NOT localise - lang strings would not work here and we CAN NOT move it after installib
fwrite(STDERR, "Moodle 2.1 or later requires at least PHP 5.3.2 (currently using version $phpversion).\n");
fwrite(STDERR, "Please upgrade your server software or install older Moodle version.\n");
exit(1);
}
// Nothing to do if config.php does not exist
$configfile = __DIR__.'/../../config.php';
$configfile = dirname(dirname(dirname(__FILE__))).'/config.php';
if (!file_exists($configfile)) {
fwrite(STDERR, 'config.php does not exist, can not continue'); // do not localize
fwrite(STDERR, "\n");
@@ -83,6 +79,11 @@ require_once($CFG->libdir.'/installlib.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/componentlib.class.php');
// make sure no tables are installed yet
if ($DB->get_tables() ) {
cli_error(get_string('clitablesexist', 'install'));
}
$CFG->early_install_lang = true;
get_string_manager(true);
@@ -94,10 +95,8 @@ list($options, $unrecognized) = cli_get_params(
'lang' => 'en',
'adminuser' => 'admin',
'adminpass' => '',
'adminemail' => '',
'fullname' => '',
'shortname' => '',
'summary' => '',
'agree-license' => false,
'help' => false
),
@@ -106,22 +105,12 @@ list($options, $unrecognized) = cli_get_params(
)
);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
// We show help text even if tables are installed.
if ($options['help']) {
echo $help;
die;
}
// Make sure no tables are installed yet.
if ($DB->get_tables() ) {
cli_error(get_string('clitablesexist', 'install'));
}
if (!$options['agree-license']) {
cli_error('You have to agree to the license. --help prints out the help'); // TODO: localize
}
@@ -130,12 +119,6 @@ if ($options['adminpass'] === true or $options['adminpass'] === '') {
cli_error('You have to specify admin password. --help prints out the help'); // TODO: localize
}
// Validate that the address provided was an e-mail address.
if (!empty($options['adminemail']) && !validate_email($options['adminemail'])) {
$a = (object) array('option' => 'adminemail', 'value' => $options['adminemail']);
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
}
$options['lang'] = clean_param($options['lang'], PARAM_SAFEDIR);
if (!file_exists($CFG->dirroot.'/install/lang/'.$options['lang'])) {
$options['lang'] = 'en';
@@ -177,20 +160,14 @@ if (!$envstatus) {
}
// Test plugin dependencies.
require_once($CFG->libdir . '/pluginlib.php');
$failed = array();
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
if (!plugin_manager::instance()->all_plugins_ok($version, $failed)) {
cli_problem(get_string('pluginscheckfailed', 'admin', array('pluginslist' => implode(', ', array_unique($failed)))));
cli_error(get_string('pluginschecktodo', 'admin'));
}
install_cli_database($options, true);
// This needs to happen at the end to ensure it occurs after all caches
// have been purged for the last time.
// This will build a cached version of the current theme for the user
// to immediately start browsing the site.
require_once($CFG->libdir.'/upgradelib.php');
upgrade_themes();
echo get_string('cliinstallfinished', 'install')."\n";
exit(0); // 0 means success
-55
View File
@@ -1,55 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* CLI script to kill all user sessions without asking for confirmation.
*
* @package core
* @subpackage cli
* @copyright 2017 Alexander Bias <alexander.bias@uni-ulm.de>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir.'/clilib.php');
list($options, $unrecognized) = cli_get_params(array('help' => false), array('h' => 'help'));
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized), 2);
}
if ($options['help']) {
$help =
"Kill all Moodle sessions
Options:
-h, --help Print out this help
Example:
\$sudo -u www-data /usr/bin/php admin/cli/kill_all_sessions.php
";
echo $help;
exit(0);
}
\core\session\manager::kill_all_sessions();
exit(0);
+10 -46
View File
@@ -1,4 +1,5 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -15,7 +16,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Enable or disable maintenance mode.
* Enable or disable maintenance mode
*
* @package core
* @subpackage cli
@@ -25,13 +26,12 @@
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once("$CFG->libdir/clilib.php");
require_once("$CFG->libdir/adminlib.php");
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/clilib.php'); // cli only functions
// Now get cli options.
list($options, $unrecognized) = cli_get_params(array('enable'=>false, 'enablelater'=>0, 'enableold'=>false, 'disable'=>false, 'help'=>false),
// now get cli options
list($options, $unrecognized) = cli_get_params(array('enable'=>false, 'disable'=>false, 'help'=>false),
array('h'=>'help'));
if ($unrecognized) {
@@ -45,14 +45,12 @@ if ($options['help']) {
Current status displayed if not option specified.
Options:
--enable Enable CLI maintenance mode
--enablelater=MINUTES Number of minutes before entering CLI maintenance mode
--enableold Enable legacy half-maintenance mode
--enable Enable maintenance mode
--disable Disable maintenance mode
-h, --help Print out this help
Example:
\$ sudo -u www-data /usr/bin/php admin/cli/maintenance.php
\$sudo -u www-data /usr/bin/php admin/cli/maintenance.php
"; //TODO: localize - to be translated later when everything is finished
echo $help;
@@ -61,52 +59,18 @@ Example:
cli_heading(get_string('sitemaintenancemode', 'admin')." ($CFG->wwwroot)");
if ($options['enablelater']) {
if (file_exists("$CFG->dataroot/climaintenance.html")) {
// Already enabled, sorry.
echo get_string('clistatusenabled', 'admin')."\n";
return 1;
}
$time = time() + ($options['enablelater']*60);
set_config('maintenance_later', $time);
echo get_string('clistatusenabledlater', 'admin', userdate($time))."\n";
return 0;
} else if ($options['enable']) {
if (file_exists("$CFG->dataroot/climaintenance.html")) {
// The maintenance is already enabled, nothing to do.
} else {
enable_cli_maintenance_mode();
}
set_config('maintenance_enabled', 0);
unset_config('maintenance_later');
echo get_string('sitemaintenanceoncli', 'admin')."\n";
exit(0);
} else if ($options['enableold']) {
if ($options['enable']) {
set_config('maintenance_enabled', 1);
unset_config('maintenance_later');
echo get_string('sitemaintenanceon', 'admin')."\n";
exit(0);
} else if ($options['disable']) {
set_config('maintenance_enabled', 0);
unset_config('maintenance_later');
if (file_exists("$CFG->dataroot/climaintenance.html")) {
unlink("$CFG->dataroot/climaintenance.html");
}
echo get_string('sitemaintenanceoff', 'admin')."\n";
exit(0);
}
if (!empty($CFG->maintenance_enabled) or file_exists("$CFG->dataroot/climaintenance.html")) {
if (!empty($CFG->maintenance_enabled)) {
echo get_string('clistatusenabled', 'admin')."\n";
} else if (isset($CFG->maintenance_later)) {
echo get_string('clistatusenabledlater', 'admin', userdate($CFG->maintenance_later))."\n";
} else {
echo get_string('clistatusdisabled', 'admin')."\n";
}
+11 -128
View File
@@ -24,7 +24,7 @@
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/clilib.php'); // cli only functions
if ($DB->get_dbfamily() !== 'mysql') {
@@ -53,7 +53,7 @@ Options:
-h, --help Print out this help
Example:
\$ sudo -u www-data /usr/bin/php admin/cli/mysql_collation.php --collation=utf8mb4_unicode_ci
\$ sudo -u www-data /usr/bin/php admin/cli/mysql_collation.php --collation=utf8_general_ci
";
if (!empty($options['collation'])) {
@@ -64,71 +64,6 @@ if (!empty($options['collation'])) {
cli_error("Error: collation '$collation' is not available on this server!");
}
$collationinfo = explode('_', $collation);
$charset = reset($collationinfo);
$engine = strtolower($DB->get_dbengine());
// Do checks for utf8mb4.
if (strpos($collation, 'utf8mb4') === 0) {
// Do we have the right engine?
if ($engine !== 'innodb' && $engine !== 'xtradb') {
cli_error("Error: '$collation' requires InnoDB or XtraDB set as the engine.");
}
// Are we using Barracuda?
if ($DB->get_row_format() != 'Barracuda') {
// Try setting it here.
try {
$DB->execute("SET GLOBAL innodb_file_format=Barracuda");
} catch (dml_exception $e) {
cli_error("Error: '$collation' requires the file format to be set to Barracuda.
An attempt was made to change the format, but it failed. Please try doing this manually.");
}
echo "GLOBAL SETTING: innodb_file_format changed to Barracuda\n";
}
// Is one file per table being used?
if (!$DB->is_file_per_table_enabled()) {
try {
$DB->execute("SET GLOBAL innodb_file_per_table=1");
} catch (dml_exception $e) {
cli_error("Error: '$collation' requires the setting 'innodb_file_per_table' be set to 'ON'.
An attempt was made to change the format, but it failed. Please try doing this manually.");
}
echo "GLOBAL SETTING: innodb_file_per_table changed to 1\n";
}
// Is large prefix set?
if (!$DB->is_large_prefix_enabled()) {
try {
$DB->execute("SET GLOBAL innodb_large_prefix=1");
} catch (dml_exception $e) {
cli_error("Error: '$collation' requires the setting 'innodb_large_prefix' be set to 'ON'.
An attempt was made to change the format, but it failed. Please try doing this manually.");
}
echo "GLOBAL SETTING: innodb_large_prefix changed to 1\n";
}
}
$sql = "SHOW VARIABLES LIKE 'collation_database'";
if (!$dbcollation = $DB->get_record_sql($sql)) {
cli_error("Error: Could not access collation information on the database.");
}
$sql = "SHOW VARIABLES LIKE 'character_set_database'";
if (!$dbcharset = $DB->get_record_sql($sql)) {
cli_error("Error: Could not access character set information on the database.");
}
if ($dbcollation->value !== $collation || $dbcharset->value !== $charset) {
// Try to convert the DB.
echo "Converting database to '$collation' for $CFG->wwwroot:\n";
$sql = "ALTER DATABASE `$CFG->dbname` DEFAULT CHARACTER SET $charset DEFAULT COLLATE = $collation";
try {
$DB->change_database_structure($sql);
} catch (exception $e) {
cli_error("Error: Tried to alter the database with no success. Please try manually changing the database
to the new collation and character set and then run this script again.");
}
echo "DATABASE CONVERTED\n";
}
echo "Converting tables and columns to '$collation' for $CFG->wwwroot:\n";
$prefix = $DB->get_prefix();
$prefix = str_replace('_', '\\_', $prefix);
@@ -145,25 +80,12 @@ if (!empty($options['collation'])) {
$skipped++;
} else {
try {
$DB->change_database_structure("ALTER TABLE `$table->name` CONVERT TO CHARACTER SET $charset COLLATE $collation");
echo "CONVERTED\n";
$converted++;
} catch (ddl_exception $e) {
$result = mysql_set_row_format($table->name, $charset, $collation, $engine);
if ($result) {
echo "CONVERTED\n";
$converted++;
} else {
// We don't know what the problem is. Stop the conversion.
cli_error("Error: Tried to convert $table->name, but there was a problem. Please check the details of this
table and try again.");
die();
}
}
$DB->change_database_structure("ALTER TABLE $table->name DEFAULT COLLATE = $collation");
echo "CONVERTED\n";
$converted++;
}
$sql = "SHOW FULL COLUMNS FROM `$table->name` WHERE collation IS NOT NULL";
$sql = "SHOW FULL COLUMNS FROM $table->name WHERE collation IS NOT NULL";
$rs2 = $DB->get_recordset_sql($sql);
foreach ($rs2 as $column) {
$column = (object)array_change_key_case((array)$column, CASE_LOWER);
@@ -174,36 +96,22 @@ if (!empty($options['collation'])) {
continue;
}
// Check for utf8mb4 collation.
$rowformat = $DB->get_row_format_sql($engine, $collation);
if ($column->type === 'tinytext' or $column->type === 'mediumtext' or $column->type === 'text' or $column->type === 'longtext') {
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
$default = (!is_null($column->default) and $column->default !== '') ? "DEFAULT '$column->default'" : '';
// primary, unique and inc are not supported for texts
$sql = "ALTER TABLE `$table->name`
MODIFY COLUMN $column->field $column->type
CHARACTER SET $charset
COLLATE $collation $notnull $default";
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default";
$DB->change_database_structure($sql);
} else if (strpos($column->type, 'varchar') === 0) {
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
$default = !is_null($column->default) ? "DEFAULT '$column->default'" : '';
if ($rowformat != '') {
$sql = "ALTER TABLE `$table->name` $rowformat";
$DB->change_database_structure($sql);
}
$sql = "ALTER TABLE `$table->name`
MODIFY COLUMN $column->field $column->type
CHARACTER SET $charset
COLLATE $collation $notnull $default";
// primary, unique and inc are not supported for texts
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default";
$DB->change_database_structure($sql);
} else {
echo "ERROR (unknown column type: $column->type)\n";
$errors++;
$error++;
continue;
}
echo "CONVERTED\n";
@@ -272,9 +180,7 @@ function mysql_get_collations() {
global $DB;
$collations = array();
$sql = "SHOW COLLATION
WHERE Collation LIKE 'utf8\_%' AND Charset = 'utf8'
OR Collation LIKE 'utf8mb4\_%' AND Charset = 'utf8mb4'";
$sql = "SHOW COLLATION WHERE Collation LIKE 'utf8\_%' AND Charset = 'utf8'";
$rs = $DB->get_recordset_sql($sql);
foreach ($rs as $collation) {
$collations[$collation->collation] = $collation->collation;
@@ -303,26 +209,3 @@ function mysql_get_column_collations($tablename) {
$rs->close();
return $collations;
}
function mysql_set_row_format($tablename, $charset, $collation, $engine) {
global $DB;
$sql = "SELECT row_format
FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = DATABASE() AND table_name = ?";
$rs = $DB->get_record_sql($sql, array($tablename));
if ($rs) {
if ($rs->row_format == 'Compact' || $rs->row_format == 'Redundant') {
$rowformat = $DB->get_row_format_sql($engine, $collation);
// Try to convert to compressed format and then try updating the collation again.
$DB->change_database_structure("ALTER TABLE `$tablename` $rowformat");
$DB->change_database_structure("ALTER TABLE `$tablename` CONVERT TO CHARACTER SET $charset COLLATE $collation");
} else {
// Row format may not be the problem. Can not diagnose problem. Send fail reply.
return false;
}
} else {
return false;
}
return true;
}
-202
View File
@@ -1,202 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* MySQL table row compression tool tool.
*
* @package core
* @copyright 2014 Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Petr Skoda <petr.skoda@totaralms.com>
*/
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require_once($CFG->libdir . '/clilib.php');
if ($DB->get_dbfamily() !== 'mysql') {
cli_error('This script is used for MySQL databases only.');
}
$engine = strtolower($DB->get_dbengine());
if ($engine !== 'innodb' and $engine !== 'xtradb') {
cli_error('This script is for MySQL servers using InnoDB or XtraDB engines only.');
}
list($options, $unrecognized) = cli_get_params(
array('help' => false, 'info' => false, 'list' => false, 'fix' => false, 'showsql' => false),
array('h' => 'help', 'i' => 'info', 'l' => 'list', 'f' => 'fix', 's' => 'showsql')
);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
$help =
"Script for detection of row size problems in MySQL InnoDB tables.
By default InnoDB storage table is using legacy Antelope file format
which has major restriction on database row size.
Use this script to detect and fix database tables with potential data
overflow problems.
Options:
-i, --info Show database information
-l, --list List problematic tables
-f, --fix Attempt to fix all tables (requires SUPER privilege)
-s, --showsql Print SQL statements for fixing of tables
-h, --help Print out this help
Example:
\$ sudo -u www-data /usr/bin/php admin/cli/mysql_compressed_rows.php -l
";
/** @var mysql_sql_generator $generator */
$generator = $DB->get_manager()->generator;
$info = $DB->get_server_info();
$filepertable = $DB->get_record_sql("SHOW VARIABLES LIKE 'innodb_file_per_table'");
$filepertable = $filepertable ? $filepertable->value : '';
$fileformat = $DB->get_record_sql("SHOW VARIABLES LIKE 'innodb_file_format'");
$fileformat = $fileformat ? $fileformat->value : '';
$prefix = $DB->get_prefix();
$database = $CFG->dbname;
if (!empty($options['info'])) {
echo "Database version: " . $info['description'] . "\n";
echo "Database name: $database\n";
echo "Database engine: " . $DB->get_dbengine() . "\n";
echo "innodb_file_per_table: $filepertable\n";
echo "innodb_file_format: $fileformat\n";
exit(0);
} else if (!empty($options['list'])) {
$problem = false;
foreach ($DB->get_tables(false) as $table) {
$columns = $DB->get_columns($table, false);
$size = $generator->guess_antelope_row_size($columns);
$format = $DB->get_row_format($table);
if ($size <= $generator::ANTELOPE_MAX_ROW_SIZE) {
continue;
}
echo str_pad($prefix . $table, 32, ' ', STR_PAD_RIGHT);
echo str_pad($format, 11, ' ', STR_PAD_RIGHT);
if ($format === 'Compact' or $format === 'Redundant') {
$problem = true;
echo " (needs fixing)\n";
} else if ($format !== 'Compressed' and $format !== 'Dynamic') {
echo " (unknown)\n";
} else {
echo "\n";
}
}
if ($problem) {
exit(1);
}
exit(0);
} else if (!empty($options['fix'])) {
$fixtables = array();
foreach ($DB->get_tables(false) as $table) {
$columns = $DB->get_columns($table, false);
$size = $generator->guess_antelope_row_size($columns);
$format = $DB->get_row_format($table);
if ($size <= $generator::ANTELOPE_MAX_ROW_SIZE) {
continue;
}
if ($format === 'Compact' or $format === 'Redundant') {
$fixtables[$table] = $table;
}
}
if (!$fixtables) {
echo "No changes necessary\n";
exit(0);
}
if ($filepertable !== 'ON') {
try {
$DB->execute("SET GLOBAL innodb_file_per_table=1");
} catch (dml_exception $e) {
echo "Cannot enable GLOBAL innodb_file_per_table setting, use --showsql option and execute the statements manually.";
throw $e;
}
}
if ($fileformat !== 'Barracuda') {
try {
$DB->execute("SET GLOBAL innodb_file_format=Barracuda");
} catch (dml_exception $e) {
echo "Cannot change GLOBAL innodb_file_format setting, use --showsql option and execute the statements manually.";
throw $e;
}
}
if (!$DB->is_compressed_row_format_supported(false)) {
echo "MySQL server is not compatible with compressed row format.";
exit(1);
}
foreach ($fixtables as $table) {
$DB->change_database_structure("ALTER TABLE `{$prefix}$table` ROW_FORMAT=Compressed");
echo str_pad($prefix . $table, 32, ' ', STR_PAD_RIGHT) . " ... Compressed\n";
}
exit(0);
} else if (!empty($options['showsql'])) {
$fixtables = array();
foreach ($DB->get_tables(false) as $table) {
$columns = $DB->get_columns($table, false);
$size = $generator->guess_antelope_row_size($columns);
$format = $DB->get_row_format($table);
if ($size <= $generator::ANTELOPE_MAX_ROW_SIZE) {
continue;
}
if ($format === 'Compact' or $format === 'Redundant') {
$fixtables[$table] = $table;
}
}
if (!$fixtables) {
echo "No changes necessary\n";
exit(0);
}
echo "Copy the following SQL statements and execute them using account with SUPER privilege:\n\n";
echo "USE $database;\n";
echo "SET SESSION sql_mode=STRICT_ALL_TABLES;\n";
echo "SET GLOBAL innodb_file_per_table=1;\n";
echo "SET GLOBAL innodb_file_format=Barracuda;\n";
foreach ($fixtables as $table) {
echo "ALTER TABLE `{$prefix}$table` ROW_FORMAT=Compressed;\n";
}
echo "\n";
exit(0);
} else {
echo $help;
die;
}
+180
View File
@@ -0,0 +1,180 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* MySQL engine conversion tool.
*
* @package core
* @subpackage cli
* @copyright 2009 Petr Skoda (http://skodak.org)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/clilib.php'); // cli only functions
if ($DB->get_dbfamily() !== 'mysql') {
cli_error('This function is designed for MySQL databases only!');
}
// now get cli options
list($options, $unrecognized) = cli_get_params(array('help'=>false, 'list'=>false, 'engine'=>false, 'available'=>false),
array('h'=>'help', 'l'=>'list', 'a'=>'available'));
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
$help =
"MySQL engine conversions script.
It is recommended to stop the web server before the conversion.
Do not use MyISAM if possible, because it is not ACID compliant
and does not support transactions.
Options:
--engine=ENGINE Convert MySQL tables to different engine
-l, --list Show table information
-a, --available Show list of available engines
-h, --help Print out this help
Example:
\$sudo -u www-data /usr/bin/php admin/cli/mysql_engine.php --engine=InnoDB
";
if (!empty($options['engine'])) {
$engines = mysql_get_engines();
$engine = clean_param($options['engine'], PARAM_ALPHA);
if (!isset($engines[strtoupper($engine)])) {
cli_error("Error: engine '$engine' is not available on this server!");
}
echo "Converting tables to '$engine' for $CFG->wwwroot:\n";
$prefix = $DB->get_prefix();
$prefix = str_replace('_', '\\_', $prefix);
$sql = "SHOW TABLE STATUS WHERE Name LIKE BINARY '$prefix%'";
$rs = $DB->get_recordset_sql($sql);
$converted = 0;
$skipped = 0;
$errors = 0;
foreach ($rs as $table) {
if (strtoupper($table->engine) === strtoupper($engine)) {
$newengine = mysql_get_table_engine($table->name);
echo str_pad($table->name, 40). " - NO CONVERSION NEEDED ($newengine)\n";
$skipped++;
continue;
}
echo str_pad($table->name, 40). " - ";
try {
$DB->change_database_structure("ALTER TABLE {$table->name} ENGINE = $engine");
$newengine = mysql_get_table_engine($table->name);
if (strtoupper($newengine) !== strtoupper($engine)) {
echo "ERROR ($newengine)\n";
$errors++;
continue;
}
echo "DONE ($newengine)\n";
$converted++;
} catch (moodle_exception $e) {
echo $e->getMessage()."\n";
$errors++;
continue;
}
}
$rs->close();
echo "Converted: $converted, skipped: $skipped, errors: $errors\n";
exit(0); // success
} else if (!empty($options['list'])) {
echo "List of tables for $CFG->wwwroot:\n";
$prefix = $DB->get_prefix();
$prefix = str_replace('_', '\\_', $prefix);
$sql = "SHOW TABLE STATUS WHERE Name LIKE BINARY '$prefix%'";
$rs = $DB->get_recordset_sql($sql);
$counts = array();
foreach ($rs as $table) {
if (isset($counts[$table->engine])) {
$counts[$table->engine]++;
} else {
$counts[$table->engine] = 1;
}
echo str_pad($table->engine, 10);
echo $table->name . "\n";
}
$rs->close();
echo "\n";
echo "Table engines summary for $CFG->wwwroot:\n";
foreach ($counts as $engine => $count) {
echo "$engine: $count\n";
}
exit(0); // success
} else if (!empty($options['available'])) {
echo "List of available MySQL engines for $CFG->wwwroot:\n";
$engines = mysql_get_engines();
foreach ($engines as $engine) {
echo " $engine\n";
}
die;
} else {
echo $help;
die;
}
// ========== Some functions ==============
function mysql_get_engines() {
global $DB;
$sql = "SHOW Engines";
$rs = $DB->get_recordset_sql($sql);
$engines = array();
foreach ($rs as $engine) {
if (strtoupper($engine->support) !== 'YES' and strtoupper($engine->support) !== 'DEFAULT') {
continue;
}
$engines[strtoupper($engine->engine)] = $engine->engine;
if (strtoupper($engine->support) === 'DEFAULT') {
$engines[strtoupper($engine->engine)] .= ' (default)';
}
}
$rs->close();
return $engines;
}
function mysql_get_table_engine($tablename) {
global $DB;
$engine = null;
$sql = "SHOW TABLE STATUS WHERE Name = '$tablename'"; // no special chars expected here
$rs = $DB->get_recordset_sql($sql);
if ($rs->valid()) {
$record = $rs->current();
$engine = $record->engine;
}
$rs->close();
return $engine;
}
+8 -31
View File
@@ -15,8 +15,6 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* CLI script to purge caches without asking for confirmation.
*
* @package core
* @subpackage cli
* @copyright 2011 David Mudrak <david@moodle.com>
@@ -25,19 +23,10 @@
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/clilib.php');
$longoptions = [
'help' => false,
'muc' => false,
'theme' => false,
'lang' => false,
'js' => false,
'filter' => false,
'other' => false
];
list($options, $unrecognized) = cli_get_params($longoptions, ['h' => 'help']);
list($options, $unrecognized) = cli_get_params(array('help' => false), array('h' => 'help'));
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
@@ -45,32 +34,20 @@ if ($unrecognized) {
}
if ($options['help']) {
// The indentation of this string is "wrong" but this is to avoid a extra whitespace in console output.
$help = <<<EOF
Invalidates Moodle internal caches
Specific caches can be defined (alone or in combination) using arguments. If none are specified,
all caches will be purged.
$help =
"Invalidates all Moodle internal caches
Options:
-h, --help Print out this help
--muc Purge all MUC caches (includes lang cache)
--theme Purge theme cache
--lang Purge language string cache
--js Purge JavaScript cache
--filter Purge text filter cache
--other Purge all file caches and other miscellaneous caches (may include MUC
if using cachestore_file).
Example:
\$ sudo -u www-data /usr/bin/php admin/cli/purge_caches.php
EOF;
\$sudo -u www-data /usr/bin/php admin/cli/purge_caches.php
";
echo $help;
exit(0);
}
purge_caches(array_filter($options));
purge_all_caches();
exit(0);
exit(0);
+13 -40
View File
@@ -26,26 +26,13 @@
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/clilib.php'); // cli only functions
// Define the input options.
$longparams = array(
'help' => false,
'username' => '',
'password' => '',
'ignore-password-policy' => false
);
$shortparams = array(
'h' => 'help',
'u' => 'username',
'p' => 'password',
'i' => 'ignore-password-policy'
);
// now get cli options
list($options, $unrecognized) = cli_get_params($longparams, $shortparams);
list($options, $unrecognized) = cli_get_params(array('help'=>false),
array('h'=>'help'));
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
@@ -60,43 +47,29 @@ There are no security checks here because anybody who is able to
execute this file may execute any PHP too.
Options:
-h, --help Print out this help
-u, --username=username Specify username to change
-p, --password=newpassword Specify new password
--ignore-password-policy Ignore password policy when setting password
-h, --help Print out this help
Example:
\$sudo -u www-data /usr/bin/php admin/cli/reset_password.php
\$sudo -u www-data /usr/bin/php admin/cli/reset_password.php --username=rosaura --password=jiu3jiu --ignore-password-policy
";
"; //TODO: localize - to be translated later when everything is finished
echo $help;
die;
}
if ($options['username'] == '' ) {
cli_heading('Password reset');
$prompt = "Enter username (manual authentication only)";
$username = cli_input($prompt);
} else {
$username = $options['username'];
}
cli_heading('Password reset'); // TODO: localize
$prompt = "enter username (manual authentication only)"; // TODO: localize
$username = cli_input($prompt);
if (!$user = $DB->get_record('user', array('auth'=>'manual', 'username'=>$username, 'mnethostid'=>$CFG->mnet_localhost_id))) {
cli_error("Can not find user '$username'");
}
if ($options['password'] == '' ) {
$prompt = "Enter new password";
$password = cli_input($prompt);
} else {
$password = $options['password'];
}
$prompt = "Enter new password"; // TODO: localize
$password = cli_input($prompt);
$errmsg = '';//prevent eclipse warning
if (!$options['ignore-password-policy'] ) {
if (!check_password_policy($password, $errmsg, $user)) {
cli_error(html_to_text($errmsg, 0));
}
if (!check_password_policy($password, $errmsg)) {
cli_error($errmsg);
}
$hashedpassword = hash_internal_user_password($password);
@@ -105,4 +78,4 @@ $DB->set_field('user', 'password', $hashedpassword, array('id'=>$user->id));
echo "Password changed\n";
exit(0); // 0 means success.
exit(0); // 0 means success
-109
View File
@@ -1,109 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This script allows to restore a course from CLI.
*
* @package core
* @subpackage cli
* @copyright 2020 Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', 1);
require(__DIR__ . '/../../config.php');
require_once($CFG->libdir . '/clilib.php');
require_once($CFG->dirroot . "/backup/util/includes/restore_includes.php");
list($options, $unrecognized) = cli_get_params([
'file' => '',
'categoryid' => '',
'showdebugging' => false,
'help' => false,
], [
'f' => 'file',
'c' => 'categoryid',
's' => 'showdebugging',
'h' => 'help',
]);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help'] || !($options['file']) || !($options['categoryid'])) {
$help = <<<EOL
Restore backup into provided category.
Options:
-f, --file=STRING Path to the backup file.
-c, --categoryid=INT ID of the category to restore too.
-s, --showdebugging Show developer level debugging information
-h, --help Print out this help.
Example:
\$sudo -u www-data /usr/bin/php admin/cli/restore_backup.php --file=/path/to/backup/file.mbz --categoryid=1\n
EOL;
echo $help;
exit(0);
}
if ($options['showdebugging']) {
set_debugging(DEBUG_DEVELOPER, true);
}
if (!$admin = get_admin()) {
throw new \moodle_exception('noadmins');
}
if (!file_exists($options['file'])) {
throw new \moodle_exception('filenotfound');
}
if (!$category = $DB->get_record('course_categories', ['id' => $options['categoryid']], 'id')) {
throw new \moodle_exception('invalidcategoryid');
}
$backupdir = "restore_" . uniqid();
$path = $CFG->tempdir . DIRECTORY_SEPARATOR . "backup" . DIRECTORY_SEPARATOR . $backupdir;
cli_heading(get_string('extractingbackupfileto', 'backup', $path));
$fp = get_file_packer('application/vnd.moodle.backup');
$fp->extract_to_pathname($options['file'], $path);
cli_heading(get_string('preprocessingbackupfile'));
try {
list($fullname, $shortname) = restore_dbops::calculate_course_names(0, get_string('restoringcourse', 'backup'),
get_string('restoringcourseshortname', 'backup'));
$courseid = restore_dbops::create_new_course($fullname, $shortname, $category->id);
$rc = new restore_controller($backupdir, $courseid, backup::INTERACTIVE_NO,
backup::MODE_GENERAL, $admin->id, backup::TARGET_NEW_COURSE);
$rc->execute_precheck();
$rc->execute_plan();
$rc->destroy();
} catch (Exception $e) {
cli_heading(get_string('cleaningtempdata'));
fulldelete($path);
throw new \moodle_exception('generalexceptionmessage', 'error', '', $e->getMessage());
}
cli_heading(get_string('restoredcourseid', 'backup', $courseid));
exit(0);
-167
View File
@@ -1,167 +0,0 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* CLI task execution.
*
* @package core
* @subpackage cli
* @copyright 2014 Petr Skoda
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('CLI_SCRIPT', true);
require(__DIR__ . '/../../config.php');
require_once("$CFG->libdir/clilib.php");
list($options, $unrecognized) = cli_get_params(
[
'help' => false,
'list' => false,
'execute' => false,
'showsql' => false,
'showdebugging' => false,
'force' => false,
], [
'h' => 'help',
'f' => 'force',
]
);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help'] or (!$options['list'] and !$options['execute'])) {
$help =
"Scheduled cron tasks.
Options:
--execute=\\some\\task Execute scheduled task manually
--list List all scheduled tasks
--showsql Show sql queries before they are executed
--showdebugging Show developer level debugging information
-h, --help Print out this help
-f, --force Execute task even if cron is disabled
Example:
\$sudo -u www-data /usr/bin/php admin/cli/scheduled_task.php --execute=\\core\\task\\session_cleanup_task
";
echo $help;
die;
}
if ($options['showdebugging'] || !empty($CFG->showcrondebugging)) {
set_debugging(DEBUG_DEVELOPER, true);
}
if ($options['showsql'] || !empty($CFG->showcronsql)) {
$DB->set_debug(true);
}
if ($options['list']) {
cli_heading("List of scheduled tasks ($CFG->wwwroot)");
$shorttime = get_string('strftimedatetimeshort');
$tasks = \core\task\manager::get_all_scheduled_tasks();
echo str_pad(get_string('scheduledtasks', 'tool_task'), 50, ' ') . ' ' . str_pad(get_string('runpattern', 'tool_task'), 17, ' ')
. ' ' . str_pad(get_string('lastruntime', 'tool_task'), 40, ' ') . get_string('nextruntime', 'tool_task') . "\n";
foreach ($tasks as $task) {
$class = '\\' . get_class($task);
$schedule = $task->get_minute() . ' '
. $task->get_hour() . ' '
. $task->get_day() . ' '
. $task->get_day_of_week() . ' '
. $task->get_month() . ' '
. $task->get_day_of_week();
$nextrun = $task->get_next_run_time();
$lastrun = $task->get_last_run_time();
$plugininfo = core_plugin_manager::instance()->get_plugin_info($task->get_component());
$plugindisabled = $plugininfo && $plugininfo->is_enabled() === false && !$task->get_run_if_component_disabled();
if ($plugindisabled) {
$nextrun = get_string('plugindisabled', 'tool_task');
} else if ($task->get_disabled()) {
$nextrun = get_string('taskdisabled', 'tool_task');
} else if ($nextrun > time()) {
$nextrun = userdate($nextrun);
} else {
$nextrun = get_string('asap', 'tool_task');
}
if ($lastrun) {
$lastrun = userdate($lastrun);
} else {
$lastrun = get_string('never');
}
echo str_pad($class, 50, ' ') . ' ' . str_pad($schedule, 17, ' ') .
' ' . str_pad($lastrun, 40, ' ') . ' ' . $nextrun . "\n";
}
exit(0);
}
if ($execute = $options['execute']) {
if (!$task = \core\task\manager::get_scheduled_task($execute)) {
mtrace("Task '$execute' not found");
exit(1);
}
if (moodle_needs_upgrading()) {
mtrace("Moodle upgrade pending, cannot execute tasks.");
exit(1);
}
if (!get_config('core', 'cron_enabled') && !$options['force']) {
mtrace('Cron is disabled. Use --force to override.');
exit(1);
}
\core\task\manager::scheduled_task_starting($task);
// Increase memory limit.
raise_memory_limit(MEMORY_EXTRA);
// Emulate normal session - we use admin account by default.
\core\cron::setup_user();
// Execute the task.
\core\local\cli\shutdown::script_supports_graceful_exit();
$cronlockfactory = \core\lock\lock_config::get_lock_factory('cron');
if (!$cronlock = $cronlockfactory->get_lock('core_cron', 10)) {
mtrace('Cannot obtain cron lock');
exit(129);
}
if (!$lock = $cronlockfactory->get_lock('\\' . get_class($task), 10)) {
$cronlock->release();
mtrace('Cannot obtain task lock');
exit(130);
}
$task->set_lock($lock);
if (!$task->is_blocking()) {
$cronlock->release();
} else {
$task->set_cron_lock($cronlock);
}
\core\cron::run_inner_scheduled_task($task);
}

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