Compare commits

..

262 Commits

Author SHA1 Message Date
Eloy Lafuente (stronk7) c948f378b9 Moodle release 2.9.1 2015-07-03 13:38:26 +02:00
Eloy Lafuente (stronk7) 9ecb4e3abd Merge branch 'MDL-50757-29' of git://github.com/damyon/moodle into MOODLE_29_STABLE 2015-07-03 11:27:17 +02:00
Damyon Wiese 17bb213dd3 MDL-50757 upgrade: Unset config value that will never be used again 2015-07-03 16:46:01 +08:00
Adrian Greeve 3c23a2cd2e MDL-50757 gradebook: Update fix for pre 2.8 upgrades.
Moodle installations that updated before the 2.8 grade push
were being flagged for a gradebook freeze. This was resulting in
calculated grades being shown as different to how they were
displayed before the upgrade. This fix retains the original
grade value.
2015-07-03 13:16:29 +08:00
Dan Poltawski 461f479dde weekly release 2.9+ 2015-07-02 14:26:11 +01:00
Dan Poltawski 8946171eca Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2015-07-02 14:26:06 +01:00
Marina Glancy 038b33f0fd MDL-48239 grades: corrected docs url for calculation changes 2015-07-02 15:49:59 +08:00
Marina Glancy ff6fe05733 MDL-48239 grades: fix notification class 2015-07-02 15:49:56 +08:00
Adrian Greeve 9ca6dcd3ba MDL-48239 gradebook: Oracle fix for string compare.
Update to upgradelib.php where string comparisions cause
phpunit failures in Oracle.
2015-07-02 12:30:33 +08:00
Eloy Lafuente (stronk7) 7d803c4c52 Merge branch 'wip-MDL-48239-29' of git://github.com/abgreeve/moodle into MOODLE_29_STABLE 2015-07-02 05:42:23 +02:00
Adrian Greeve 5ab9f04410 MDL-48239 gradebook: Change to calculated grade item min and max.
Regardless of the setting 'Min and max grades used in calculation'
Calculated grade items will always update the min and max raw grade.
2015-07-02 11:27:12 +08:00
Adrian Greeve 9b84c81dfd MDL-48239 gradebook: Unit test for upgrade function. 2015-07-02 11:27:12 +08:00
Adrian Greeve 4a6ed0cf53 MDL-48239 gradebook: Behat tests for calculated grade items. 2015-07-02 11:27:11 +08:00
Adrian Greeve c81c8a2ae8 MDL-48239 gradebook: Calculated grades maxgrade now able to be set. 2015-07-02 11:27:11 +08:00
Rajesh Taneja e6ad444ea1 MDL-50481 behat: SingleSelect can be urlselect and should support id/name 2015-07-01 11:23:33 +08:00
David Monllao e87f4d63c3 Merge branch 'MDL-50497-M29' of git://github.com/lazydaisy/moodle into MOODLE_29_STABLE
Conflicts:
	theme/bootstrapbase/style/moodle.css
2015-07-01 08:56:08 +08:00
Juan Leyva a809a8dcce MDL-50130 users: Filter profile fields data in external functions 2015-06-30 19:51:38 +02:00
AMOS bot 6314335c49 Automatically generated installer lang files 2015-07-01 00:04:59 +08:00
Dan Poltawski 3cb39c2a04 Merge branch 'wip-mdl-50481-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2015-06-30 12:25:53 +02:00
Dan Poltawski 30e59bbc21 Merge branch 'MDL-33765_m29_offset' of git://github.com/markn86/moodle into MOODLE_29_STABLE 2015-06-30 12:20:09 +02:00
Dan Poltawski e228ce6e04 Merge branch 'MDL-47787-m29' of https://github.com/tbannister/moodle into MOODLE_29_STABLE 2015-06-30 10:25:15 +02:00
David Monllao d2cb356582 MDL-50569 backup: Missing get_target call 2015-06-30 10:33:14 +08:00
Dan Marsden 46460a2303 MDL-50614 mod_scorm: Improve validation on currentorg 2015-06-30 10:14:12 +08:00
David Monllao 0b715c77f2 Merge branch 'MDL-50569-29' of git://github.com/FMCorz/moodle into MOODLE_29_STABLE 2015-06-30 09:32:31 +08:00
Mark Nelson adb234e19d MDL-50220 mod_forum: added missing capability check 2015-06-29 18:49:21 +02:00
Eloy Lafuente (stronk7) 5656fdb9c9 Merge branch 'wip-mdl-50675-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2015-06-29 18:33:08 +02:00
Eloy Lafuente (stronk7) 5710353976 MDL-50688 lib: small cleanup + http/https coverage. 2015-06-29 17:49:41 +02:00
Petr Skoda 9580c08e9e MDL-50688 lib: fix local url validation bug
Change-Id: I350bb8c9ace5cc0403f083f728c100097be7aa7e
Reviewed-on: https://review.totaralms.com/8101
Tested-by: Jenkins Automation <jenkins@totaralms.com>
Reviewed-by: Sam Hemelryk <sam.hemelryk@totaralms.com>
Reviewed-by: Alastair Munro <alastair.munro@totaralms.com>
2015-06-29 17:49:38 +02:00
Nadav Kavalerchik a2f36ceef5 MDL-50708 SCORM: Right align menu item folder icon, when in RTL mode. 2015-06-29 15:58:13 +08:00
Frederic Massart d3e9d99ccb MDL-50569 grades: Restore as merge always ignores minmaxtouse 2015-06-29 14:25:58 +08:00
Frederic Massart a603cb5af4 MDL-50569 grades: Handle minmaxtouse in backup/restore 2015-06-29 14:25:58 +08:00
David Monllao f9b6810d4e Merge branch 'MDL-50646-29-preflang' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2015-06-29 13:36:27 +08:00
David Monllao 0b89c8dd85 Merge branch 'MDL-50652_29' of git://github.com/reskit/moodle into MOODLE_29_STABLE 2015-06-29 13:02:06 +08:00
Mark Nelson f521c1e769 MDL-33765 filter_glossary: fixed jshint warning 2015-06-28 21:45:44 -07:00
Martin Mastny 4ca8ff532b MDL-33765 filter_glossary: Stacking JS windows with offset 2015-06-28 21:45:44 -07:00
Martin Mastny d5720db41e MDL-33765 mod_glossary: Concept in ajax request not linking to itself 2015-06-28 21:45:44 -07:00
David Monllao b04406e697 Merge branch 'wip_MDL-50659_m29' of git://github.com/gjb2048/moodle into MOODLE_29_STABLE 2015-06-29 11:48:12 +08:00
Rajesh Taneja 064cfdff92 MDL-50675 repository_wikimedia: Fixed title varaible 2015-06-29 09:57:03 +08:00
Rajesh Taneja dfec225a37 MDL-50675 repository_wikimedia: Wikimedia is using https and not http 2015-06-29 09:57:02 +08:00
Mary Evans b4faba939d MDL-50497 theme_bootstrapbase: Divider colours look wrong when inverted 2015-06-26 22:49:54 +01:00
Gareth J Barnard 5409b5a7ec MDL-50659 themes: Regression: Drag a link makes icons move. 2015-06-26 11:43:53 +01:00
Tyler Bannister 8f683efff3 MDL-47787 course: Added question delete to cm delete. 2015-06-25 16:37:52 -04:00
Marc Català d68806edf9 MDL-50652 workshop: Workshop module allows duplicated ID number 2015-06-25 14:26:29 +02:00
Marina Glancy a8646c70fa MDL-49257 grades: apply freeze when restoring with contents deleting 2015-06-25 14:40:36 +08:00
David Monllao d783a8fba7 weekly release 2.9+ 2015-06-25 13:50:14 +08:00
David Monllao 147aca3043 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2015-06-25 13:50:12 +08:00
Rajesh Taneja 532acaf5ac MDL-50481 core_grades: Fixed behat feature and step to work with non-js
xPath used in step is not using proper oring
and fails with goutee driver. Also, feature don't
really need to be executed in js, so setting that
as non-js
2015-06-25 13:14:08 +08:00
Rajesh Taneja bc7b926591 MDL-50481 behat: Press go button for given single select in non-js
For non-js mode, ensure we press the go button
for the specified single select, as there can be
multiple single selects on the page with go button
2015-06-25 13:14:08 +08:00
Marina Glancy b3892e62a5 MDL-49257 grades: strings adjustments 2015-06-25 10:00:02 +08:00
Eloy Lafuente (stronk7) e09d38647b MDL-49022 auth_ldap: keep method visibility unmodified. 2015-06-24 03:07:21 +02:00
Eloy Lafuente (stronk7) 005ead1f8a Merge branch 'wip-mdl-49022-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2015-06-24 03:03:07 +02:00
Eloy Lafuente (stronk7) c5bc16fe8a MDL-49497 curl: keep api private and test it using reflection.
While strictly we should not be testing private APIs, in order
to get this backported to stables without changing visibility
we use reflection to access to such private properties and methods.

Also added one exttest to verify user agent is properly sent.

Finally, fix some wrong whitespace and changed the helper class name
to better alternative.
2015-06-23 16:25:53 +01:00
Dan Poltawski cdca00ca81 Merge branch 'MDL-49497-29' of git://github.com/gurgus/moodle into MOODLE_29_STABLE 2015-06-23 16:25:40 +01:00
Dan Poltawski b29b31dc12 Merge branch 'MDL-50533-29' of git://github.com/jethac/moodle into MOODLE_29_STABLE 2015-06-23 14:13:13 +01:00
Dan Poltawski 4342a37310 Merge branch 'wip-MDL-49257-m29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2015-06-23 11:20:28 +01:00
Rajesh Taneja 824bbbcb3f MDL-49022 auth_ldap: Updated unit test, checking sync_user events 2015-06-23 17:02:36 +08:00
Mark Ward fd954ad01b MDL-49022 auth_ldap: trigger event when required.
When calling update_user_record() for auth_ldap the method
now has option to trigger event core\event\user_updated when
syncing with domain controller.
This means that the event will be triggered by sync_users()
but not by user_signup().
2015-06-23 17:02:36 +08:00
Marina Glancy 5edd9315d1 MDL-49257 grades: behat tests for extra credit 2015-06-23 14:24:37 +08:00
Marina Glancy 9c4b068082 MDL-49257 grades: fix bugs with extra credit weights
When we adjust the weights in natural grading (setup screen), the extra credit items
should not depend on other overrides. If extra credit item's weight was overriden, it stays as it is.
Otherwise it is calculated as itemgrademax / totalgrademax (total excludes extra credit items)
2015-06-23 14:24:37 +08:00
Marina Glancy e806e2c9f7 MDL-49257 grades: introduce calculation freeze
In order to prevent changes in the existing grades when we fix bugs
we are introducing the gradebook code versioning. Each course may
"freeze" the code version to the older date. Freezing is usually done
during upgrade or restore and can be removed by the teacher by pressing
the button and accepting potential grade changes. There is no visible
setting and not possible to change the version back manually.

See MDL-50432 and MDL-50522
2015-06-23 14:24:33 +08:00
David Monllao ba0e10425f MDL-50611 testing: Extra http status code checking 2015-06-23 10:38:00 +08:00
David Monllao 0c2db45a76 Merge branch 'MDL-50611-29' of git://github.com/LukeCarrier/moodle into MOODLE_29_STABLE 2015-06-23 10:28:19 +08:00
Eloy Lafuente (stronk7) 3f33350e0d Merge branch 'MDL-50171-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2015-06-23 01:43:08 +02:00
Eloy Lafuente (stronk7) c9f8064b23 Merge branch 'MDL-50089-29' of git://github.com/merrill-oakland/moodle into MOODLE_29_STABLE 2015-06-22 19:59:14 +02:00
Eloy Lafuente (stronk7) e107f6227c Merge branch 'MDL-50583_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2015-06-22 19:22:48 +02:00
Eric Merrill f5273c374f MDL-50089 grades: Use grade item min/max in exports 2015-06-22 12:59:30 -04:00
Luke Carrier 0e1a2090b8 MDL-50611 test: use cURL extension to download Composer
The curl binary is nowhere near as common in Windows environments as it is
in Linux and Mac ones. In order to encourage more users to adopt Behat and
PHPUnit for their testing, we should avoid introducing unnecessary
hurdles.
2015-06-22 15:50:46 +01:00
Dan Poltawski 1ee0876d3d Merge branch 'MDL-50460_M29' of git://github.com/lazydaisy/moodle into MOODLE_29_STABLE 2015-06-22 13:29:12 +01:00
Dan Poltawski a6640dcbe5 Merge branch 'MDL-50091_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2015-06-22 12:06:50 +01:00
David Monllao 73441dca38 Merge branch 'MDL-50622-29-enfix' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2015-06-22 17:44:31 +08:00
David Monllao f8cc4ea4a1 Merge branch 'MDL-50561-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2015-06-22 16:04:10 +08:00
David Monllao 9d1d7caafd Merge branch 'wip-MDL-50568-m29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2015-06-22 15:33:28 +08:00
David Monllao d88fa5e681 Merge branch 'wip-MDL-50580-m29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2015-06-22 12:50:29 +08:00
Tim Hunt 76ef7726e2 MDL-50648 grader report: columns misaligned with some permissions
If a user can see the grader report and singleview report, but not
the user report ($CFG->grade_profilereport) then the colspans
were wrong and so the columns did not line up under the right headers.
2015-06-19 12:37:24 +01:00
David Mudrák 5ac3194c6f MDL-50646 admin: Use site default lang as new user's preferred lang
As a result of MDL-49632, the preferred language is no longer part of
the "Add a new user" form. So the lang property is not passed to the
user_create_user() when creating a new user and the value always falls
back to "en" (which is the default defined in the database for this
column).

This patch makes sure that the site default language is used in such
case.
2015-06-19 13:17:52 +02:00
Helen Foster 497e490a6b MDL-50622 lang: Merge English strings from the en_fix language pack 2015-06-19 12:13:48 +02:00
Juan Leyva 5b41ec52f7 MDL-50561 messages: Add missing __isset magic method 2015-06-19 09:44:59 +02:00
Juan Leyva 45ced3d17d MDL-50171 data: Fixed incorrect text formatting in external functions 2015-06-19 09:44:07 +02:00
Mary Evans 200e4da537 MDL-50460 theme_bootstrapbase: Profile image overlays docked blocks. 2015-06-19 02:50:38 +01:00
AMOS bot 11189884a8 Automatically generated installer lang files 2015-06-19 00:04:11 +08:00
Dan Poltawski ca587e8819 weekly release 2.9+ 2015-06-18 14:03:11 +01:00
Dan Poltawski bffd9c6ad2 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2015-06-18 14:03:09 +01:00
Tim Hunt 0aa98ebda1 MDL-50091 grade singleview: use standard API to build the link
Acutally the necessary code was already there. There was just some
unnecessary code that was added with the issue number MDL-47746. I have
just stripped out the unused code, which fixes the bug where a missing
activity caused a fatal error.
2015-06-17 13:56:31 +01:00
Eloy Lafuente (stronk7) 78c315db76 Merge branch 'MDL-50004-M29' of git://github.com/lazydaisy/moodle into MOODLE_29_STABLE 2015-06-17 00:59:05 +02:00
Eloy Lafuente (stronk7) 8ceecd98a8 Merge branch 'MDL-50107-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2015-06-17 00:16:34 +02:00
AMOS bot 775f5d6a9f Automatically generated installer lang files 2015-06-17 00:04:02 +08:00
AMOS bot 99f4c550f2 Automatically generated installer lang files 2015-06-17 00:04:02 +08:00
Dan Poltawski f102573e45 Merge branch 'MDL-49959_course_dnd_message_MDL29' of https://github.com/barrysspace/moodle into MOODLE_29_STABLE 2015-06-16 13:08:40 +01:00
Martin Mastny b848eeacc8 MDL-49744 JavaScript: Glossary term window is draggable 2015-06-16 10:19:23 +01:00
Jetha Chan c74f2c3e70 MDL-50533 theme_bootstrapbase: retarget collapse styles 2015-06-16 16:29:12 +08:00
Andrew Nicols 95554b45b6 Merge branch 'wip-MDL-50216-29' of git://github.com/abgreeve/moodle into MOODLE_29_STABLE 2015-06-16 12:22:28 +08:00
Andrew Nicols 2bea2a1918 MDL-39353 xmlrpc: Add note to upgrde.txt regarding proxybypass 2015-06-16 11:34:21 +08:00
Andrew Nicols f934fdf46c Merge branch 'MDL-39353-29' of https://github.com/rtcn2/moodle into MOODLE_29_STABLE 2015-06-16 11:33:16 +08:00
Martin Mastny 7d1d36e036 MDL-50216 JavaScript: Default visibility of M.core.info set to false 2015-06-16 11:20:51 +08:00
Andrew Nicols ca4c8b1942 Merge branch 'MDL-50380-29' of git://github.com/lameze/moodle into MOODLE_29_STABLE 2015-06-16 07:58:16 +08:00
Dan Poltawski d0a5d336f7 Merge branch 'MDL-49368_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2015-06-15 12:33:30 +01:00
Marina Glancy 893d5e69a0 MDL-50580 signup: move recaptcha outside of category 2015-06-15 17:14:59 +08:00
Andrew Nicols f74ae05201 Merge branch 'MDL-50459-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2015-06-15 16:03:38 +08:00
Andrew Nicols 14e7f3c3b7 Merge branch 'wip-MDL-50222-m29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2015-06-15 15:17:04 +08:00
GeekSmith 7c6d8dd8e0 MDL-50583 upgrade: Optimize upgrade_minmaxgrade
Reverse join order to use existing database keys. Changed query to use the
more easily read NOT IN.
2015-06-15 10:39:26 +08:00
Andrew Nicols e82c2eb2b1 Merge branch 'MDL-50438-29' of git://github.com/mastnym/moodle into MOODLE_29_STABLE 2015-06-15 10:21:13 +08:00
Andrew Nicols 87cd84ddb7 Merge branch 'MDL-50509-29-vartypo' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2015-06-15 09:59:25 +08:00
Andrew Nicols 531908df75 MDL-50554 themes: Rebuild of bootstrapbase 2015-06-15 09:46:29 +08:00
Andrew Nicols ced7d04d07 Merge branch 'MDL-50520-29' of git://github.com/jethac/moodle into MOODLE_29_STABLE 2015-06-15 09:26:36 +08:00
Mary Evans d16724b42b MDL-50004 theme: Fixes frontpage coursename and enrolment icons. 2015-06-15 00:25:56 +01:00
Gareth J Barnard e0a114e4f5 MDL-50554 themes: Drag a link move mouse makes icons move in Chrome. 2015-06-14 21:40:16 +01:00
Dan Poltawski 0d7f387b37 weekly release 2.9+ 2015-06-12 10:24:43 +01:00
Dan Poltawski b8e8cbf3bb Merge branch 'MDL-48618_29-test-calculated' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2015-06-12 10:19:31 +01:00
Eloy Lafuente (stronk7) 887d0618cc MDL-50176 repository_youtube: delay loading google service stuff
Loading Google client services is a little monster, eating around
2MB (opcache enabled) of memory. As far as we instantiate the
repository instances really early, no matter they are not used
later (editor, file picker, admin...).. we are delaying the
load of the service until we know we are going to use it.

Surely applying this very same (sort of lazy load) techinque
to other repositories could lead to a nice memory reduction
in lots of pages.

MDL-50176 repository_youtube: also delay the inclusion of client.

While memory was fixed with previous commit, still some extra included
files where being reported, so go crazy and move all the stuff to
the new init delayed method.
2015-06-12 10:29:03 +02:00
David Monllao ab4665046a MDL-48618 grades: Testing calculated items with minmaxtouse 2015-06-12 14:06:18 +08:00
Marina Glancy 72e0a56673 MDL-50568 navigation: correct cap check 2015-06-12 10:48:08 +08:00
Frederic Massart eaf0d255b4 MDL-48618 grades: Do not run minmax upgrade for fresh installs 2015-06-11 17:16:40 +08:00
Rajesh Taneja ebae161cdf MDL-49659 theme_clean: Add login info in the nav bar 2015-06-11 10:00:30 +01:00
David Monllao 691c2913bb MDL-48618 upgrade: Matching conditions and upgrade savepoints 2015-06-11 15:03:19 +08:00
David Monllao fce1153108 MDL-48618 grades: Forcing new upgrade savepoint 2015-06-11 14:34:25 +08:00
David Monllao 2817ff06ae Merge branch 'MDL-48618-29' of git://github.com/FMCorz/moodle into MOODLE_29_STABLE 2015-06-11 14:22:27 +08:00
Juan Leyva 61c8747a39 MDL-50107 webservices: Enable CORS in login/token.php 2015-06-10 11:36:28 +02:00
Rod Norfor 6e0401d61f MDL-39353 xmlrpc: Add proxy support 2015-06-10 08:19:39 +01:00
Frederic Massart 3391ece9f8 MDL-48618 grades: Test for the minmax upgrade step 2015-06-10 12:42:57 +08:00
Frederic Massart 6be25bc988 MDL-48618 grades: Behat tests to cover min/max grade changes
The values provided as part of this test are similar to values
that can be found in 2.7. This is to ensure that users will not
experience changes in grades.
2015-06-10 12:42:57 +08:00
Frederic Massart 3eb9b4a316 MDL-48618 grades: Unit tests for grade_grade::get_min/max_grade() 2015-06-10 12:42:56 +08:00
Frederic Massart f872eef1e9 MDL-48618 grades: Handling of inconsistencies due to min/max grades 2015-06-10 12:42:54 +08:00
Eric Merrill 0624b774d0 MDL-48618 gradebook: Only use individual min/max for aggrigate grades 2015-06-10 12:37:09 +08:00
Eloy Lafuente (stronk7) 3783dde956 Merge branch 'MDL-47480-29' of git://github.com/ankitagarwal/moodle into MOODLE_29_STABLE 2015-06-10 00:33:20 +02:00
Eloy Lafuente (stronk7) 98a8ef2777 Merge branch 'MDL-50145_m29' of git://github.com/markn86/moodle into MOODLE_29_STABLE 2015-06-09 20:43:01 +02:00
Eloy Lafuente (stronk7) e3cd190100 Merge branch 'm29_MDL-50415_Add_PHP_Variables_In_PHPInfo_Admin_Page' of https://github.com/scara/moodle into MOODLE_29_STABLE 2015-06-09 20:37:19 +02:00
Eloy Lafuente (stronk7) 9b1539c5d6 Merge branch 'wip-mdl-50179-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2015-06-09 20:33:04 +02:00
Eloy Lafuente (stronk7) d4990e4c94 Merge branch 'MDL-50176_29' of git://github.com/aolley/moodle into MOODLE_29_STABLE
Fixed the plugin version to have sticky YYYYMMDD
2015-06-09 20:17:45 +02:00
Ramindu Deshapriya 99422f333b MDL-43731 mod_book: Added Behat test to automate MDLQA-1791 2015-06-09 15:01:31 +01:00
Dan Poltawski 128a866390 Merge branch 'MDL-49659_M29' of git://github.com/lazydaisy/moodle into MOODLE_29_STABLE 2015-06-09 14:42:04 +01:00
Marina Glancy 1187ce03ec MDL-50222 admin: do not use deprecated print_textarea() 2015-06-09 20:58:32 +08:00
Andrew Davis 8f1d67ea09 MDL-49885 core_blocks: fixed course_overview block applicable_formats() 2015-06-09 13:57:44 +01:00
Martin Mastny 97c9eaefa8 MDL-50186 forms: Removed special characters from id attribute 2015-06-09 13:32:59 +01:00
Mark Nelson ca0042ca80 MDL-50145 mod_lesson: added behat test for multiple dashboard lessons 2015-06-09 00:49:19 -07:00
Mark Nelson bc10960447 MDL-50145 mod_lesson: fixed issue with duplicate values 2015-06-09 00:49:18 -07:00
Jetha Chan 7d0bdbe264 MDL-50520 templates: fix helpers not firing inside pix helper 2015-06-09 15:23:43 +08:00
Rajesh Taneja 4c07dea461 MDL-50179 lesson: Get student/attempts only when showing overview 2015-06-09 09:35:02 +08:00
Rajesh Taneja b09e7b4c7d MDL-50179 behat: Use %d for windows compatibility 2015-06-09 09:34:52 +08:00
Eloy Lafuente (stronk7) c0be92c749 Merge branch 'MDL-50394_m29' of git://github.com/markn86/moodle into MOODLE_29_STABLE 2015-06-08 18:40:38 +02:00
Eloy Lafuente (stronk7) ee4c6f78c6 Merge branch 'MDL-50408_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2015-06-08 15:49:16 +02:00
Juan Leyva e003e65ea8 MDL-50459 messages: Handle deleted users in external functions 2015-06-08 14:38:43 +02:00
David Mudrák b25bb3cf29 MDL-50509 datalib: Fix the typo in the variable name
The line is supposed to sanitize the function parameter.
2015-06-08 11:16:39 +02:00
Dave Cooper 5d8cfda315 MDL-49497 curl: Add configurable User-Agent unit tests. 2015-06-08 17:02:54 +08:00
Dave Cooper 1f2fbac207 MDL-49497 curl: Allow configurable User-Agent.
Thanks to Kartik Yadav for assistance with this patch.
2015-06-08 17:02:54 +08:00
Barry Oosthuizen 7955318e45 MDL-49959 course: Fix hidden drag and drop message 2015-06-08 09:35:59 +01:00
David Monllao 2799e8f70e MDL-50408 tool_log: Extra deprecation tip
Adding a debugging message and returning alternative data to keep backwards
compatibility as get_readers is a widely used function.
2015-06-08 15:57:41 +08:00
Eloy Lafuente (stronk7) 69ece23a48 Merge branch 'MDL-50456-29' of git://github.com/damyon/moodle into MOODLE_29_STABLE 2015-06-07 21:56:37 +02:00
Mary Evans a81d590726 MDL-49659 theme: Removed home link and limited login info in secure.php
Credits: Thanks go to Andreas Hruska [https://github.com/ahruska] for the original patch for this issue.
2015-06-04 17:45:51 +01:00
Eloy Lafuente (stronk7) c3661ca0cc weekly release 2.9+ 2015-06-04 12:09:15 +02:00
Eloy Lafuente (stronk7) 5be5d4d2c9 Merge branch 'install_29_STABLE' of https://git.in.moodle.com/amosbot/moodle-install into MOODLE_29_STABLE 2015-06-04 12:09:10 +02:00
Rajesh Taneja 629f298ce7 MDL-47995 lib: encode title properly, before additing it to image title 2015-06-04 12:56:20 +08:00
Matteo Scaramuccia 8172729a07 MDL-50415 Admin: added the PHP Variables section in the PHPinfo page. 2015-06-03 21:19:07 +02:00
Eloy Lafuente (stronk7) 78285d5c9c Merge branch 'MDL-47995-29' of git://github.com/lameze/moodle into MOODLE_29_STABLE 2015-06-03 11:10:57 +02:00
Simey Lameze 1fab00298d MDL-50380 mod_wiki: fix missing parameter on wiki edit files page
Also fixing a typo on the $referer variable.
2015-06-03 16:46:25 +08:00
Damyon Wiese e27f30b7c8 MDL-50456 Javascript: Fix simple logic error in core/url amd module 2015-06-03 15:59:53 +08:00
Mark Nelson 3af357dd2c MDL-50394 core_course: fixed form validation of 'gradepass' 2015-06-03 00:36:13 -07:00
Dan Poltawski c5e83ccab0 Merge branch 'MDL-49323-29' of git://github.com/nmoller/moodle into MOODLE_29_STABLE 2015-06-02 13:23:29 +01:00
Dan Poltawski ea20d927ad Merge branch 'MDL-46927_m29' of git://github.com/markn86/moodle into MOODLE_29_STABLE 2015-06-02 09:03:53 +01:00
Martin Mastny 6964dc6e73 MDL-50438 filter_glossary: Added missing exception classes 2015-06-02 14:22:43 +08:00
Mark Nelson 80f8e00bd7 MDL-46927 core_files: fixed issue with system course restores
When clicking on 'Restore' next to a file in the 'Course
backup area' in the system context the message 'Sorry,
the requested file could not be found' was displayed.
This fix adds missing functionality to the class
'file_info_context_system' so that the file information
is correctly returned.
2015-06-01 23:09:17 -07:00
Ankit Agarwal 53f0b8ae3c MDL-47480 tasks: Define order for getting tasks 2015-06-02 08:18:42 +05:30
AMOS bot 377ec4c107 Automatically generated installer lang files 2015-06-02 00:04:16 +08:00
Nelson Moller 659c60614b MDL-49323 mod_assign: Fixed numeric validation in grade form.
The behat test for another decimal separator was incorporated.
2015-06-01 11:00:12 -04:00
Dan Poltawski f0a7bbcd14 Merge branch 'MDL-50341_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2015-06-01 15:03:42 +01:00
Dan Poltawski 3372a99e13 MDL-50322 forum: add basic split post behat coverage
Also bump version for autoloading new class.
2015-06-01 14:59:41 +01:00
Martin Mastny 6f7bf269b2 MDL-50322 mod_forum: Added validation when spliting discussions 2015-06-01 14:56:31 +01:00
Dan Poltawski a48f97d414 Merge branch 'MDL-50304_29' of https://github.com/jinhofer/moodle into MOODLE_29_STABLE 2015-06-01 13:21:55 +01:00
Dan Poltawski 8f4a31ce65 MDL-50406 less: build css 2015-06-01 12:01:07 +01:00
Dan Poltawski 4f27bea28b Merge branch 'MDL-50406_M29' of git://github.com/nadavkav/moodle into MOODLE_29_STABLE 2015-06-01 11:42:23 +01:00
Dan Poltawski caaf4113ce Merge branch 'MDL-50309_m29' of git://github.com/markn86/moodle into MOODLE_29_STABLE 2015-06-01 10:26:50 +01:00
Dan Poltawski 5ed79f4e97 Merge branch 'MDL-49707-29' of git://github.com/ankitagarwal/moodle into MOODLE_29_STABLE 2015-06-01 10:19:37 +01:00
Ankit Agarwal 1f797413d4 MDL-49707 inbound: localpart should be < 15 2015-06-01 10:10:39 +05:30
Adam Olley 28e427c0f9 MDL-50176 repository_youtube: Switch to using YouTube Data API
As of April 20, 2015, the old API used by repository_youtube is no longer
accessible. This change switches over to using the standard Google Data
API v3.

Unfortunately this means that to search YouTube, a developer api key is now
*required*.

Special thanks to UNSW for sponsoring this work.
2015-06-01 09:40:14 +09:30
Tim Hunt 71b448e27d MDL-50341 quiz statistics: non-attempted questions broke first-try stats
For behaviours that allow multiple tries, and when the teacher had chosen to
generate statistics for the first tries only, and when a student had not
attempted one question, then an error occurred. It should have been classified
as no response.
2015-05-31 13:53:08 +01:00
AMOS bot 47596be087 Automatically generated installer lang files 2015-05-31 00:03:58 +08:00
Nadav Kavalerchik 199fbeb647 MDL-50406 Messages: Right align messages menu box, in RTL mode. 2015-05-30 12:13:16 +03:00
AMOS bot 8389e416a4 Automatically generated installer lang files 2015-05-30 00:04:06 +08:00
AMOS bot 3143816be1 Automatically generated installer lang files 2015-05-29 00:03:59 +08:00
jinhofer 5a561e90c3 MDL-50304 atto/plugins/table: Fixed _addRowAfter function 2015-05-28 07:55:26 -05:00
AMOS bot 314eb4342c Automatically generated installer lang files 2015-05-28 14:21:58 +08:00
Mark Nelson b73491b280 MDL-50309 core_upgrade: fixed undefined '$customusermenuitems' notice 2015-05-27 22:43:25 -07:00
David Monllao d91491569c weekly release 2.9+ 2015-05-28 10:55:09 +08:00
David Monllao a38b6660e4 Merge branch 'MDL-50373_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2015-05-28 09:28:10 +08:00
Tim Hunt 18dd4e5d9b MDL-50373 questions: random Qs must not pick deleted or sub- questions
This was a regression caused by MDL-6340. I missed the necessary
    AND parent = 0 AND hidden = 0
in one query of the question table.
2015-05-27 20:35:24 +01:00
Eloy Lafuente (stronk7) 3d944b0454 Merge branch 'wip-mdl-49806-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2015-05-27 12:36:49 +02:00
David Monllao a8b977172a MDL-50330 blog: Make other users blogs accessible 2015-05-27 14:10:20 +08:00
David Monllao deb125fa6d Merge branch 'MDL-50340-29' of git://github.com/ankitagarwal/moodle into MOODLE_29_STABLE 2015-05-27 11:58:41 +08:00
Rajesh Taneja 1cb3091780 MDL-49772 behat: Removed optimization as it's not required
This api is called very few times in behat
initilisation process, so such optimization
is an over engineer. Hence removing it.
2015-05-27 11:51:34 +08:00
Rajesh Taneja 3ac8f0c5e3 MDL-49806 behat: Ensure user is marked complete before runnning cron 2015-05-27 09:25:47 +08:00
Aaron Barnes 7ee737690a MDL-49611 completion: Update dangling err_nocriteria lang strings 2015-05-27 08:49:46 +08:00
Eloy Lafuente (stronk7) e600df800c Merge branch 'wip-mdl-49772-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2015-05-27 01:45:50 +02:00
Eloy Lafuente (stronk7) b77a45c3a2 Merge branch 'wip-MDL-50191-m29' of https://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2015-05-26 18:19:49 +02:00
Dan Poltawski 0e0e83abdf Merge branch 'MDL-50318-29-courseresources' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2015-05-26 13:05:06 +01:00
Dan Poltawski 777f822fad Merge branch 'MDL-49787_email_attachments_symlink_fix_29' of https://github.com/iamandrew/moodle into MOODLE_29_STABLE 2015-05-26 12:56:31 +01:00
Dan Poltawski a694acd9b8 Merge branch 'MDL-49776-29' of git://github.com/lameze/moodle into MOODLE_29_STABLE 2015-05-26 11:53:46 +01:00
Marina Glancy 0676b9c186 MDL-49560 webservice: avoid recursion in soap
Thanks to El Leonidych for providing a patch
2015-05-26 11:33:42 +01:00
Dan Poltawski 5c5fb8bd8f Merge branch 'MDL-50271-29' of git://github.com/jleyva/moodle into MOODLE_29_STABLE 2015-05-26 11:31:48 +01:00
David Monllao cdd1fcbf45 Merge branch 'MDL-50344-29' of git://github.com/ankitagarwal/moodle into MOODLE_29_STABLE 2015-05-26 17:29:38 +08:00
Jetha Chan 55cf90e9db MDL-48664 output: change paging_bar to not use non-breaking spaces 2015-05-26 14:46:12 +08:00
Ankit Agarwal f59d6a6fcf MDL-50340 adminstration: Fix restore course links 2015-05-26 12:04:41 +05:30
David Monllao ad9131d75d Merge branch 'MDL-46550-29' of git://github.com/ankitagarwal/moodle into MOODLE_29_STABLE 2015-05-26 12:29:17 +08:00
David Monllao 6e54261fe8 Merge branch 'MDL-50289-29-notes' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2015-05-26 12:23:34 +08:00
Dan Poltawski fdfea113b5 Merge branch 'MDL-50313-29-featureidnumber' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2015-05-25 13:54:06 +01:00
Dan Poltawski 267238bac4 Merge branch 'MDL-50321-29-modupgradetxt' of git://github.com/mudrd8mz/moodle into MOODLE_29_STABLE 2015-05-25 12:30:34 +01:00
Nadav Kavalerchik 83a061c8e8 MDL-40592 assign/grading: Display default user picture, if none is set. 2015-05-25 12:28:49 +01:00
Martin Mastny e1cd01e60e MDL-49493 backup: Implemented missing methods for anonymous backup 2015-05-25 12:02:02 +01:00
David Mudrák 32eb50d49b MDL-50289 notes: No navigation to notes if the feature is disabled 2015-05-25 12:36:10 +02:00
David Monllao c3b65cc9e9 Merge branch 'wip-MDL-49572-m29' of git://github.com/marinaglancy/moodle into MOODLE_29_STABLE 2015-05-25 17:54:31 +08:00
Damien Bezborodov 544a4f57ec MDL-50285 gradereport_user: Grade categories calculate wrong with suspended users (Student's view) 2015-05-25 17:44:09 +08:00
Ankit Agarwal 44ad175eda MDL-50344 restore: Make restore file required 2015-05-25 12:08:51 +05:30
spvickers 628bee355e MDL-49776 mod_lti: Set parameter in privacy check
Moved sending of the lis_result_sourcedid parameter to within the block
which checks that grades are being accepted for the link.
2015-05-25 13:02:11 +08:00
iclearn fcd6880e1e MDL-47995 mod_url: add proper title encoding on url mod 2015-05-25 12:55:22 +08:00
iclearn 159a8fda78 MDL-47995 mod_resource: properly encode resource title 2015-05-25 12:55:22 +08:00
Juan Leyva ecdadf2a18 MDL-50271 webservices: Allow to load multiple themes in WS_SERVER mode 2015-05-22 13:27:14 +02:00
Adrian Greeve c1813cf5d9 MDL-50330 blog: Behat test for blog visibility. 2015-05-22 16:15:59 +08:00
Adrian Greeve ed97ad100b MDL-50330 blog: Fixed fatal error accessing blogs. 2015-05-22 16:15:46 +08:00
Tim Hunt 609e3cfc0b MDL-49368 qtypes match & multichice: cope with editing after attempt
Teachers should not radically edit a question after it has been
attempted. However, if they do, we should handle it gracefully, rather
than triggering PHP errors.
2015-05-21 18:17:40 +01:00
David Mudrák f2a6afba21 MDL-50321 docs: Add info about deprecated method into mod/upgrade.txt
This was forgotten in MDL-49101.
2015-05-21 18:03:26 +02:00
David Mudrák 60fa8157f2 MDL-50318 course: Fix the URL of embedded images at resources overview
Not only mod_resource instances are listed here. All modules that
declare their FEATURE_MOD_ARCHETYPE as MOD_ARCHETYPE_RESOURCE (well, all
but those without own view page, such as mod_label) are listed. So we
must use the real plugin name when rendering the intro field.
2015-05-21 17:22:42 +02:00
David Mudrák 723f9b73eb MDL-50313 docs: Fix the documentation for the FEATURE_IDNUMBER constant
The constant is used by course/moodleform_mod.php to decide whether the
field 'ID number' (cmidnumber) should be included in the common module
settings section of the activity settings form. Activity modules that do
not use grades (such as the Label) can explicitly return false when
checking for this feature support. By default, all activity modules are
supposed to support it.
2015-05-21 16:51:31 +02:00
Eloy Lafuente (stronk7) 4cf3969700 weekly release 2.9+ 2015-05-21 12:37:27 +02:00
Rajesh Taneja 73cc1d04c9 MDL-49772 behat: Added support to updatestep file by parallel run 2015-05-21 14:46:13 +08:00
Marina Glancy bd13927c47 MDL-50191 cohorts: check manage cap to display hide icon 2015-05-21 11:11:42 +08:00
Andrew Nicols 198c3fb3f0 MDL-50277 Javascript: Hardcode nodejs dependencies
In order to produce a consistent build across the board, we must hardcode
several package versions. We must additionally specify compatible
versions for any sub-dependency that we have a requirement upon.

In this instance, the only sub-dependency which has an effect upon the
overall output is grunt-contrib-uglify's dependency upon uglify-js.

Since change in uglify-js may lead to changes in the generated output, we
must specify a fixed version of that dependency. That version must be
compatible with the dependency signature for grunt-contrib-uglify or the
dependency manager will just download a different version.

This issue also bumps the version of uglify-js to a version which changes
the output. This is the latest version at time of commit.
2015-05-20 11:09:25 +02:00
Marina Glancy 690725416b MDL-49572 cache: correctly purge cache on event 2015-05-20 14:07:11 +08:00
Rajesh Taneja 058b07958b MDL-49061 behat: Fixed input name to use full activity name 2015-05-20 10:18:53 +08:00
Eloy Lafuente (stronk7) d5307d89e3 Merge branch 'wip-mdl-50259-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2015-05-19 18:02:43 +02:00
Marina Glancy d5df44623f MDL-49061 reports: call format_string on activities names 2015-05-19 15:00:46 +01:00
Dan Poltawski dfa7e964c5 Merge branch 'wip-mdl-50203-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2015-05-19 12:38:58 +01:00
Ankit Agarwal 7c964c9fac MDL-50276 forums: Add a new line in forum emails 2015-05-19 15:47:02 +08:00
Dan Poltawski d014bdea09 Merge branch 'wip-mdl-50116-m29' of https://github.com/rajeshtaneja/moodle into MOODLE_29_STABLE 2015-05-19 08:27:56 +01:00
Rajesh Taneja 5c57e2ad47 MDL-50259 behat: Use strict activity name checking
contains might select wrong activity
so using strict activity text checking
2015-05-19 14:47:24 +08:00
Rajesh Taneja 7e41013038 MDL-50116 behat: Fixed xpath for selecting table row 2015-05-19 13:36:07 +08:00
Skylar Kelty 35a0d15031 MDL-50169: Fix grade report SQL logic 2015-05-19 02:03:30 +02:00
Eloy Lafuente (stronk7) aff87a12e2 Merge branch 'MDL-50280_29' of https://github.com/sk-unikent/moodle into MOODLE_29_STABLE 2015-05-19 01:43:13 +02:00
Eric Merrill 954626a2b9 MDL-48467 atto: Clean the textarea during submission when in HTML mode 2015-05-19 01:38:29 +02:00
Eloy Lafuente (stronk7) 41c398aa5c Merge branch 'MDL-50197_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2015-05-19 00:35:40 +02:00
Eloy Lafuente (stronk7) 0809c38938 Merge branch 'MDL-50245_29' of git://github.com/timhunt/moodle into MOODLE_29_STABLE 2015-05-19 00:33:15 +02:00
Skylar Kelty 69afba56e6 MDL-50280 WebCT import scripts don't always clean up 2015-05-18 16:47:25 +01:00
Martin Mastny 44be211cb2 MDL-49949 grader: Using method to determine item name 2015-05-18 15:34:06 +01:00
Dan Poltawski 3dd7be272f Merge branch 'MDL-49764_29' of https://github.com/jinhofer/moodle into MOODLE_29_STABLE 2015-05-18 15:28:59 +01:00
Dan Poltawski ea3f6e2b75 Merge branch 'MDL-49906-29' of git://github.com/lameze/moodle into MOODLE_29_STABLE 2015-05-18 14:04:12 +01:00
Dan Poltawski 22d4ded11f Merge branch 'MDL-50092_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2015-05-18 13:58:21 +01:00
jinhofer 0161f4f957 MDL-49764 grade/report/grader: Fixed height issue for IE 2015-05-18 07:48:43 -05:00
Damyon Wiese 383aa049c0 MDL-50254 Mustache: Missing alias for namespaced class in mustache
Thanks to Francesco Bigiarini for the report and suggested fix.
2015-05-18 13:09:54 +01:00
Dan Poltawski 3257b829a8 Merge branch 'MDL-50177_29' of git://github.com/dmonllao/moodle into MOODLE_29_STABLE 2015-05-18 13:03:25 +01:00
Andrew Davidson 38a659dc10 MDL-49787 email: Updated email attachement path check to use realpath() in order to allow for symlinked temp directories 2015-05-18 12:03:40 +01:00
Ankit Agarwal 356c4ae63e MDL-46550 logs: Fix incorrect url
Thanks to Nadav Kavalerchik for the suggestion on patch
2015-05-18 12:02:48 +05:30
Adrian Greeve 3f87e8e54b MDL-49742 lib: Removed additional names on tables for sorting.
When additional names are disabled, they are no longer shown as
sortable headings in the enrolment and admin user tables.
2015-05-15 15:45:04 +08:00
Rajesh Taneja 859aac85c4 MDL-50116 behat: updated symfony/symfony version 2015-05-15 10:10:13 +08:00
Tim Hunt 55f468ff62 MDL-50245 quiz: fix CSS of search options in the qbank dialogue 2015-05-14 14:41:14 +01:00
David Monllao 2138e7eddc weekly release 2.9+ 2015-05-14 11:34:32 +08:00
Rajesh Taneja f47d844c68 MDL-50203 behat: Click on link in student 1 row 2015-05-13 15:21:00 +08:00
Simey Lameze f007447294 MDL-49906 core_user: add require login exception message 2015-05-13 13:54:48 +08:00
Damyon Wiese 4590d1be1e MDL-25138 core_tags: remove duplicated related tags 2015-05-13 10:25:17 +08:00
Simey Lameze a236699367 MDL-25138 core_tag: fix correlated tags query unique error 2015-05-13 10:25:11 +08:00
David Monllao f461827532 MDL-50187 docs: Including all x.y releases 2015-05-12 09:51:55 +02:00
David Monllao 406af5521c MDL-50177 completion: Also accepting cm integer strings 2015-05-12 12:21:39 +08:00
David Monllao a229c2fb0f Merge branch 'MDL-34102' of git://github.com/jmvedrine/moodle into MOODLE_29_STABLE 2015-05-12 12:09:06 +08:00
Eloy Lafuente (stronk7) 057cf60bd7 MDL-50183 upgrade: add 2.9.0 separation line to all upgrade scripts 2015-05-12 00:23:59 +02:00
Tim Hunt cd3cd9ffc3 MDL-50197 quiz editing: fix dialogue titles at the end of the quiz 2015-05-11 17:21:02 +01:00
David Monllao 5e236840b0 MDL-50092 enrol_imsenterprise: Fixing wrong field name
Thanks to JD for the fix.
2015-05-11 14:55:22 +08:00
19175 changed files with 645168 additions and 2042691 deletions
+3
View File
@@ -0,0 +1,3 @@
--errors=errors,duplicate-properties
--warnings=known-properties,display-property-grouping,empty-rules,important
--exclude-list=vendor/,lib/editor/tinymce/,lib/yuilib/,theme/bootstrapbase/style/
-307
View File
@@ -1,307 +0,0 @@
{
'plugins': [
'babel',
'promise',
'jsdoc',
],
'env': {
'browser': 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-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"],
// 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 support es6 now. Woot!
env: {
es6: true
},
// We're using babel transpiling so use their parser
// for linting.
parser: 'babel-eslint',
// 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: {
'ecmaVersion': 9,
'sourceType': 'module'
}
}
]
}
-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');
-114
View File
@@ -1,114 +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.0
jobs:
Grunt:
runs-on: ubuntu-18.04
steps:
- name: Checking out code
uses: actions/checkout@v2
- name: Configuring node & npm
uses: actions/setup-node@v2
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:
- os: ubuntu-18.04
php: 7.3
extensions:
db: mysqli
- os: ubuntu-18.04
php: 8.0
db: pgsql
extensions: xmlrpc-beta
steps:
- name: Setting up DB mysql
if: ${{ matrix.db == 'mysqli' }}
uses: johanmeiring/mysql-action@tmpfs-patch
with:
collation server: utf8mb4_bin
mysql version: 5.7
mysql database: test
mysql user: test
mysql password: test
use tmpfs: true
- name: Setting up DB pgsql
if: ${{ matrix.db == 'pgsql' }}
uses: m4nu56/postgresql-action@v1
with:
postgresql version: 9.6
postgresql db: test
postgresql user: test
postgresql password: test
- name: Configuring git vars
uses: rlespinasse/github-slug-action@v3.x
- 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@v2
- 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 }}
run: vendor/bin/phpunit -v
+2 -17
View File
@@ -9,24 +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
@@ -34,7 +25,6 @@ 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.phar
@@ -46,8 +36,3 @@ composer.phar
/lib/yuilib/*/*/*-coverage.js
atlassian-ide-plugin.xml
/node_modules/
/.vscode/
moodle-plugin-ci.phar
.eslintignore
.stylelintignore
/jsdoc
-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);
}
}
}
};
};
-243
View File
@@ -1,243 +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').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;
};
module.exports = {
getAmdSrcGlobList,
getComponentFromPath,
getComponentPaths,
getOwningComponentDirectory,
getYuiSrcGlobList,
getThirdPartyLibsList,
getThirdPartyPaths,
};
-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,
},
};
-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();
});
};
-89
View File
@@ -1,89 +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'],
},
},
});
return handler;
};
-60
View File
@@ -1,60 +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');
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',
].concat(thirdPartyPaths);
grunt.file.write('.stylelintignore', stylelintIgnores.join('\n') + '\n');
};
grunt.registerTask('ignorefiles', 'Generate ignore files for linters', handler);
return handler;
};
-147
View File
@@ -1,147 +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('src', '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 JSDoc.
require('./jsdoc')(grunt);
const path = require('path');
// Register JS tasks.
grunt.registerTask('yui', ['eslint:yui', 'shifter']);
grunt.registerTask('amd', ['ignorefiles', 'eslint:amd', 'babel']);
grunt.registerTask('js', ['amd', 'yui']);
// Register NPM tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
// Load the Babel tasks and config.
grunt.loadNpmTasks('grunt-babel');
grunt.config.merge({
babel: {
options: {
sourceMaps: true,
comments: 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: [
['minify', {
// This minification plugin needs to be disabled because it breaks the
// source map generation and causes invalid source maps to be output.
simplify: false,
builtIns: false
}],
['@babel/preset-env', {
targets: {
browsers: [
">0.25%",
"last 2 versions",
"not ie <= 10",
"not op_mini all",
"not Opera > 0",
"not dead"
]
},
modules: false,
useBuiltIns: 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']
},
},
});
// 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('babel.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,
};
};
-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('node-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;
};
-48
View File
@@ -1,48 +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 them all!.
grunt.task.run('css');
grunt.task.run('js');
grunt.task.run('gherkinlint');
}
};
// Register the startup task.
grunt.registerTask('startup', 'Run the correct tasks for the current directory', handler);
return handler;
};
-32
View File
@@ -1,32 +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);
};
-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']
},
},
});
};
-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
+1 -5
View File
@@ -1,6 +1,3 @@
// 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,
@@ -38,8 +35,7 @@
"plusplus": false,
"predef": [
"M",
"define",
"require"
"define"
],
"proto": false,
"regexdash": false,
-1
View File
@@ -1 +0,0 @@
v14.18.0
-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",
}
}
-266
View File
@@ -1,266 +0,0 @@
# PLEASE NOTE: Travis is not currently utilised by the Moodle core integration
# process (which uses our internal CI system) this file is here for the benefit
# of community developers git clones - see MDL-51458.
notifications:
email:
if: env(MOODLE_EMAIL) != no
language: php
os: linux
dist: bionic
services:
- mysql
- docker
addons:
postgresql: "9.6"
branches:
except:
- master
- /MOODLE_[0-9]+_STABLE/
- /^v[0-9]+\.[0-9]+\.[0-9]+.*/
jobs:
# Enable fast finish.
# This will fail the build if a single job fails (except those in allow_failures).
# It will not stop the jobs from running.
fast_finish: true
include:
# First all the lowest php ones (7.3)
- php: 7.3
env: DB=none TASK=CITEST
- php: 7.3
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
- if: env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present
php: 7.3
env: DB=pgsql TASK=PHPUNIT
- if: env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all"
php: 7.3
env: DB=mysqli TASK=PHPUNIT
# Then, conditionally, all the highest php ones (8.0)
- if: env(MOODLE_PHP) = "all"
php: 8.0
env: DB=none TASK=CITEST
- if: env(MOODLE_PHP) = "all"
php: 8.0
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present)
php: 8.0
env: DB=pgsql TASK=PHPUNIT
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all")
php: 8.0
env: DB=mysqli TASK=PHPUNIT
cache:
directories:
- $HOME/.composer/cache
- $HOME/.npm
before_install:
- docker run -d -p 127.0.0.1:8080:80 --name exttests moodlehq/moodle-exttests
# Avoid IPv6 default binding as service (causes redis not to start).
- sudo service redis-server start --bind 127.0.0.1
install:
- >
if [ "$DB" = 'mysqli' ];
then
sudo mkdir /mnt/ramdisk
sudo mount -t tmpfs -o size=1024m tmpfs /mnt/ramdisk
sudo service mysql stop
sudo mv /var/lib/mysql /mnt/ramdisk
sudo ln -s /mnt/ramdisk/mysql /var/lib/mysql
sudo service mysql restart
fi
- >
if [ "$DB" = 'pgsql' ];
then
sudo mkdir /mnt/ramdisk
sudo mount -t tmpfs -o size=1024m tmpfs /mnt/ramdisk
sudo service postgresql stop
sudo mv /var/lib/postgresql /mnt/ramdisk
sudo ln -s /mnt/ramdisk/postgresql /var/lib/postgresql
sudo service postgresql start 9.6
fi
- >
if [ "$TASK" = 'PHPUNIT' ];
then
if [ -n "$GITHUB_APITOKEN" ]; then
composer config github-oauth.github.com $GITHUB_APITOKEN;
echo 'auth.json' >> .git/info/exclude
fi
echo 'extension="redis.so"' > /tmp/redis.ini
phpenv config-add /tmp/redis.ini
# Install composer dependencies.
# We need --no-interaction in case we hit API limits for composer. This causes it to fall back to a standard clone.
# Typically it should be able to use the Composer cache if any other job has already completed before we started here.
travis_retry composer install --prefer-dist --no-interaction;
fi
- >
if [ "$TASK" = 'GRUNT' ];
then
nvm install $NVM_VERSION ;
nvm use $NVM_VERSION ;
fi
before_script:
- if [[ ${TRAVIS_PHP_VERSION:0:1} -gt 7 ]]; then pecl install xmlrpc-beta; fi
- echo 'max_input_vars=5000' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
- phpenv config-rm xdebug.ini
- >
if [ "$TASK" = 'PHPUNIT' ];
then
# Copy generic configuration in place.
cp config-dist.php config.php ;
# Create the moodledata directory.
mkdir -p "$HOME"/roots/base
# The database name and password.
sed -i \
-e "s%= 'moodle'%= 'travis_ci_test'%" \
-e "s%= 'password'%= ''%" \
config.php ;
# The wwwroot and dataroot.
sed -i \
-e "s%http://example.com/moodle%https://localhost%" \
-e "s%/home/example/moodledata%/home/travis/roots/base%" \
config.php ;
if [ "$DB" = 'pgsql' ];
then
# Postgres-specific setup.
sed -i \
-e "s%= 'username'%= 'postgres'%" \
config.php ;
psql -c 'CREATE DATABASE travis_ci_test;' -U postgres;
fi
if [ "$DB" = 'mysqli' ];
then
# MySQL-specific setup.
sed -i \
-e "s%= 'pgsql'%= 'mysqli'%" \
-e "s%= 'username'%= 'travis'%" \
-e "s%=> 'utf8mb4_unicode_ci'%=> 'utf8mb4_bin'%" \
config.php;
mysql -u root -e 'SET GLOBAL innodb_file_format=barracuda;' ;
mysql -u root -e 'SET GLOBAL innodb_file_per_table=ON;' ;
mysql -u root -e 'SET GLOBAL innodb_large_prefix=ON;' ;
mysql -e 'CREATE DATABASE travis_ci_test DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_bin;' ;
fi
fi
- >
if [ "$TASK" = 'PHPUNIT' ];
then
# Create a directory for the phpunit dataroot.
mkdir -p "$HOME"/roots/phpunit
# The phpunit dataroot and prefix..
sed -i \
-e "/require_once/i \\\$CFG->phpunit_dataroot = '\/home\/travis\/roots\/phpunit';" \
-e "/require_once/i \\\$CFG->phpunit_prefix = 'p_';" \
config.php ;
# Enable test external resources
sed -i \
-e "/require_once/i \\define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://127.0.0.1:8080');" \
-e "/require_once/i \\define('TEST_EXTERNAL_FILES_HTTPS_URL', 'http://127.0.0.1:8080');" \
config.php ;
# Redis cache store tests
sed -i \
-e "/require_once/i \\define('TEST_CACHESTORE_REDIS_TESTSERVERS', '127.0.0.1');" \
config.php ;
# Redis session tests
sed -i \
-e "/require_once/i \\define('TEST_SESSION_REDIS_HOST', '127.0.0.1');" \
config.php ;
# Initialise PHPUnit for Moodle.
php admin/tool/phpunit/cli/init.php
fi
- >
if [ "$TASK" = 'GRUNT' ];
then
npm install --no-spin;
npm install --no-spin -g grunt ;
fi
########################################################################
# CI Tests
########################################################################
- >
if [ "$TASK" = 'CITEST' ];
then
# Note - this is deliberately placed in the script section as we
# should not add any code until after phpunit has run.
# The following repositories are required.
# The local_ci repository does the actual checking.
git clone https://github.com/moodlehq/moodle-local_ci.git local/ci
# We need the official upstream for comparison
git remote add upstream https://github.com/moodle/moodle.git;
git fetch upstream MOODLE_311_STABLE;
export GIT_PREVIOUS_COMMIT="`git merge-base FETCH_HEAD $TRAVIS_COMMIT`";
export GIT_COMMIT="$TRAVIS_COMMIT";
export UPSTREAM_FETCH_HEAD=`git rev-parse FETCH_HEAD`
# Variables required by our linter.
export gitcmd=`which git`;
export gitdir="$TRAVIS_BUILD_DIR";
export phpcmd=`which php`;
fi
script:
- >
if [ "$TASK" = 'PHPUNIT' ];
then
vendor/bin/phpunit --fail-on-risky --disallow-test-output --verbose;
fi
- >
if [ "$TASK" = 'CITEST' ];
then
bash local/ci/php_lint/php_lint.sh;
fi
- >
if [ "$TASK" = 'GRUNT' ];
then
grunt ;
# Add all files to the git index and then run diff --cached to see all changes.
# This ensures that we get the status of all files, including new files.
# We ignore npm-shrinkwrap.json to make the tasks immune to npm changes.
git add . ;
git reset -- npm-shrinkwrap.json ;
git diff --cached --exit-code ;
fi
after_script:
- >
if [ "$TASK" = 'PHPUNIT' ];
then
EXTTESTS_HITS=$(docker logs exttests 2>&1 | grep -Fv -e 'AH00558' -e '[pid 1]' | wc -l)
echo -e "\nTest local resources number of hits: ${EXTTESTS_HITS}.\n"
fi
-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>.
+115 -225
View File
@@ -12,250 +12,140 @@
//
// 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}
* Grunt configuration
*/
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);
var path = require('path'),
tasks = {},
cwd = process.env.PWD || process.cwd();
// Setup the Moodle environemnt within the Grunt object.
grunt.moodleEnv = setupMoodleEnvironment(grunt);
// Project configuration.
grunt.initConfig({
jshint: {
options: {jshintrc: '.jshintrc'},
files: ['**/amd/src/*.js']
},
uglify: {
dynamic_mappings: {
files: grunt.file.expandMapping(
['**/src/*.js', '!**/node_modules/**'],
'',
{
cwd: cwd,
rename: function(destBase, destPath) {
destPath = destPath.replace('src', 'build');
destPath = destPath.replace('.js', '.min.js');
destPath = path.resolve(cwd, destPath);
return destPath;
}
}
)
}
}
});
/**
* 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`);
tasks.shifter = function() {
var exec = require('child_process').spawn,
done = this.async(),
args = [],
options = {
recursive: true,
watch: false,
walk: false,
module: false
},
shifter;
grunt.log.debug(`Including tasks for ${name} from ${taskPath}`);
args.push( path.normalize(__dirname + '/node_modules/shifter/bin/shifter'));
require(path.resolve(`./.grunt/tasks/${name}.js`))(grunt);
// Determine the most appropriate options to run with based upon the current location.
if (path.basename(cwd) === 'src') {
// Detect whether we're in a src directory.
grunt.log.debug('In a src directory');
args.push('--walk');
options.walk = true;
} else if (path.basename(path.dirname(cwd)) === 'src') {
// Detect whether we're in a module directory.
grunt.log.debug('In a module directory');
options.module = true;
}
if (grunt.option('watch')) {
if (!options.walk && !options.module) {
grunt.fail.fatal('Unable to watch unless in a src or module directory');
}
// It is not advisable to run with recursivity and watch - this
// leads to building the build directory in a race-like fashion.
grunt.log.debug('Detected a watch - disabling recursivity');
options.recursive = false;
args.push('--watch');
}
if (options.recursive) {
args.push('--recursive');
}
// Always ignore the node_modules directory.
args.push('--excludes', 'node_modules');
// Add the stderr option if appropriate
if (grunt.option('verbose')) {
args.push('--lint-stderr');
}
// Actually run shifter.
shifter = exec("node", args, {
cwd: cwd,
stdio: 'inherit',
env: process.env
});
// Tidy up after exec.
shifter.on('exit', function (code) {
if (code) {
grunt.fail.fatal('Shifter failed with code: ' + code);
} else {
grunt.log.ok('Shifter build complete.');
done();
}
});
};
tasks.startup = function() {
// Are we in a YUI directory?
if (path.basename(path.resolve(cwd, '../../')) == 'yui') {
grunt.task.run('shifter');
// Are we in an AMD directory?
} else if (path.basename(cwd) == 'amd') {
grunt.task.run('jshint');
grunt.task.run('uglify');
} else {
// Run them all!.
grunt.task.run('shifter');
grunt.task.run('jshint');
grunt.task.run('uglify');
}
};
// Add Moodle task configuration.
addTask('gherkinlint', grunt);
addTask('ignorefiles', grunt);
// Register NPM tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
addTask('javascript', grunt);
addTask('style', grunt);
// Register the shifter task.
grunt.registerTask('shifter', 'Run Shifter against the current directory', tasks.shifter);
addTask('watch', grunt);
addTask('startup', grunt);
// Register the startup task.
grunt.registerTask('startup', 'Run the correct tasks for the current directory', tasks.startup);
// 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 -42
View File
@@ -1,48 +1,34 @@
MOODLE TRADEMARKS POLICY
========================
------------------------
Moodle Trademark License
------------------------
The word "Moodle" is trademarked in many countries around the world. The word
was originally coined as an acronym: Modular Object-Oriented Dynamic Learning
Environment. The trademark is owned by Martin Dougiamas, Founder and Director
of Moodle.
The name Moodle is a registered trademark of the Moodle Trust.
The law obligates trademark owners to police their marks and prevent the use of
confusingly similar names by third parties. Through this policy wed like to
make it clear how Moodle-related projects, organisations, and people can use
the Moodle trademark. Wed also like to be clear about how use of the word is
restricted when used to promote commercial Moodle services. We do this to
protect the very business model that allows us to continue developing Moodle
for you.
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).
Allowed uses
------------
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 dont require any permission at all:
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.)
* Referring to the software or the Moodle project.
* Describing your own Moodle implementation (including within corporate
settings).
* Describing a Moodle-based community hub.
* Describing some software youve made that integrates with Moodle
(eg a Moodle integration feature on another system).
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.
Restricted uses
---------------
The following uses are generally prohibited without explicit and direct
permission being granted to you by Moodle Pty Ltd. We do this to protect the
Moodle project from software and sites which could confuse people. Please
contact us to ask for permission in writing.
* You cant use "Moodle" in the name of your software (including Mobile apps)
* You cant use "Moodle" in your company name
* You cant use "Moodle" in your domain name
* You cant use "Moodle" in advertising-related keywords (such as Adsense)
* You cant use "Moodle" to describe services around Moodle (such as hosting,
training, support, consulting, course creation services, theme development,
customisation, installation, integration and certification). This applies
even if you do not charge for the services. Note that usually only Moodle
Partners have this permission.
For information about the Moodle Partner Certification Mark as well as for how
to contact us, please see <https://moodle.com/trademarks/>.
Martin Dougiamas
Executive Director
Moodle Trust
http://moodle.com
-107
View File
@@ -1,107 +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);
}
switch ($action) {
case 'disable':
// Remove from enabled list.
$key = array_search($antivirus, $activeantiviruses);
unset($activeantiviruses[$key]);
break;
case 'enable':
// Add to enabled list.
if (!in_array($antivirus, $activeantiviruses)) {
$activeantiviruses[] = $antivirus;
$activeantiviruses = array_unique($activeantiviruses);
}
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;
}
}
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;
}
}
break;
default:
break;
}
$new = implode(',', $activeantiviruses);
add_to_config_log('antiviruses', $CFG->antiviruses, $new, 'core');
set_config('antiviruses', $new);
core_plugin_manager::reset_caches();
redirect ($returnurl);
+6 -14
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'));
@@ -44,9 +45,7 @@ switch ($action) {
$key = array_search($auth, $authsenabled);
if ($key !== false) {
unset($authsenabled[$key]);
$value = implode(',', $authsenabled);
add_to_config_log('auth', $CFG->auth, $value, 'core');
set_config('auth', $value);
set_config('auth', implode(',', $authsenabled));
}
if ($auth == $CFG->registerauth) {
@@ -61,11 +60,8 @@ switch ($action) {
if (!in_array($auth, $authsenabled)) {
$authsenabled[] = $auth;
$authsenabled = array_unique($authsenabled);
$value = implode(',', $authsenabled);
add_to_config_log('auth', $CFG->auth, $value, 'core');
set_config('auth', $value);
set_config('auth', implode(',', $authsenabled));
}
\core\session\manager::gc(); // Remove stale sessions.
core_plugin_manager::reset_caches();
break;
@@ -81,9 +77,7 @@ switch ($action) {
$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;
@@ -98,9 +92,7 @@ switch ($action) {
$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;
+8 -29
View File
@@ -16,9 +16,6 @@ $err = array();
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=manageauths";
debugging("Use of config.html files in authentication plugins have been deprecated. " .
" Please migrate your plugin to use the admin settings API", DEBUG_DEVELOPER);
// save configuration changes
if ($frm = data_submitted() and confirm_sesskey()) {
@@ -89,28 +86,12 @@ exit;
/// Functions /////////////////////////////////////////////////////////////////
/**
* auth field locking
* 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.
*
* @param string $auth authentication plugin shortname
* @param array $user_fields user profile fields
* @param string $helptext help text to be displayed at top of form
* @param boolean $retrieveopts Map fields or lock only.
* @param boolean $updateopts Allow remote updates
* @param array $customfields list of custom profile fields
* @deprecated since Moodle 3.3
*/
// 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, $customfields = array()) {
global $DB, $OUTPUT;
debugging("The function 'print_auth_lock_options' has been deprecated, " .
"Please migrate your code to use the admin settings API and use the function 'display_auth_lock_options' instead. ",
DEBUG_DEVELOPER);
echo '<tr><td colspan="3">';
if ($retrieveopts) {
echo $OUTPUT->heading(get_string('auth_data_mapping', 'auth'));
@@ -165,12 +146,10 @@ function print_auth_lock_options($auth, $user_fields, $helptext, $retrieveopts,
// If custom field then pick name from database.
$fieldshortname = str_replace('profile_field_', '', $fieldname);
$fieldname = $customfieldname[$fieldshortname]->name;
if (core_text::strlen($fieldshortname) > 67) {
// If custom profile field name is longer than 67 characters we will not be able to store the setting
// such as 'field_updateremote_profile_field_NOTSOSHORTSHORTNAME' in the database because the character
// limit for the setting name is 100.
continue;
}
} 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);
}
+28 -17
View File
@@ -4,7 +4,6 @@
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/blocklib.php');
require_once($CFG->libdir.'/tablelib.php');
admin_externalpage_setup('manageblocks');
@@ -37,7 +36,6 @@
print_error('blockdoesnotexist', 'error');
}
$DB->set_field('block', 'visible', '0', array('id'=>$block->id)); // Hide block
add_to_config_log('block_visibility', $block->visible, '0', $block->name);
core_plugin_manager::reset_caches();
admin_get_root(true, false); // settings not required - only pages
}
@@ -47,23 +45,40 @@
print_error('blockdoesnotexist', 'error');
}
$DB->set_field('block', 'visible', '1', array('id'=>$block->id)); // Show block
add_to_config_log('block_visibility', $block->visible, '1', $block->name);
core_plugin_manager::reset_caches();
admin_get_root(true, false); // settings not required - only pages
}
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($protect) && confirm_sesskey()) {
block_manager::protect_block((int)$protect);
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()) {
block_manager::unprotect_block((int)$unprotect);
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
}
$undeletableblocktypes = block_manager::get_undeletable_block_types();
echo $OUTPUT->header();
echo $OUTPUT->heading($strmanageblocks);
@@ -139,12 +154,8 @@
$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 if (!file_exists($CFG->dirroot.'/blocks/'.$block->name.'/settings.php')) {
// If the block's settings node was not found, we check that the block really provides the settings.php file.
// Note that blocks can inject their settings to other nodes in the admin tree without using the default locations.
// This can be done by assigning null to $setting in settings.php and it is a valid case.
debugging('Warning: block_'.$block->name.' returns true in has_config() but does not provide a settings.php file',
DEBUG_DEVELOPER);
} else {
$settings = '<a href="block.php?block='.$blockid.'">'.$strsettings.'</a>';
}
}
@@ -168,10 +179,10 @@
$visible = '';
} else if ($blocks[$blockid]->visible) {
$visible = '<a href="blocks.php?hide='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strhide.'">'.
$OUTPUT->pix_icon('t/hide', $strhide) . '</a>';
'<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.'">'.
$OUTPUT->pix_icon('t/show', $strshow) . '</a>';
'<img src="'.$OUTPUT->pix_url('t/show') . '" class="iconsmall" alt="'.$strshow.'" /></a>';
$class = 'dimmed_text';
}
@@ -186,10 +197,10 @@
$undeletable = '';
} else if (in_array($blockname, $undeletableblocktypes)) {
$undeletable = '<a href="blocks.php?unprotect='.$blockid.'&amp;sesskey='.sesskey().'" title="'.$strunprotect.'">'.
$OUTPUT->pix_icon('t/unlock', $strunprotect) . '</a>';
'<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.'">'.
$OUTPUT->pix_icon('t/lock', $strprotect) . '</a>';
'<img src="'.$OUTPUT->pix_url('t/lock') . '" class="iconsmall" alt="'.$strprotect.'" /></a>';
}
$row = array(
+12 -20
View File
@@ -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));
@@ -53,16 +54,14 @@ $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');
@@ -74,7 +73,7 @@ if ($data = data_submitted() and confirm_sesskey()) {
if ($PAGE->user_allowed_editing() && $adminediting != -1) {
$USER->editing = $adminediting;
}
$buttons = null;
if ($PAGE->user_allowed_editing()) {
$url = clone($PAGE->url);
if ($PAGE->user_is_editing()) {
@@ -90,7 +89,7 @@ if ($PAGE->user_allowed_editing()) {
$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) {
@@ -121,16 +120,14 @@ foreach ($settingspage->children as $childpage) {
}
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();
@@ -158,9 +155,4 @@ echo $outputhtml;
echo html_writer::end_tag('fieldset');
echo html_writer::end_tag('form');
$PAGE->requires->yui_module('moodle-core-formchangechecker', 'M.core_formchangechecker.init', [[
'formid' => 'adminsettings'
]]);
$PAGE->requires->string_for_js('changesmadereallygoaway', 'moodle');
echo $OUTPUT->footer();
-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,59 +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');
$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');
}
}
@@ -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);
}
/**
* 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,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);
}
}
-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';
}
}
-293
View File
@@ -1,293 +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 log table.
*
* @package core_admin
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_admin;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/tablelib.php');
/**
* Table to display list of task logs.
*
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class task_log_table extends \table_sql {
/**
* Constructor for the task_log table.
*
* @param string $filter
* @param int $resultfilter
*/
public function __construct(string $filter = '', int $resultfilter = null) {
global $DB;
if (-1 === $resultfilter) {
$resultfilter = null;
}
parent::__construct('tasklogs');
$columnheaders = [
'classname' => get_string('name'),
'type' => get_string('tasktype', 'admin'),
'userid' => get_string('user', 'admin'),
'timestart' => get_string('task_starttime', 'admin'),
'duration' => get_string('task_duration', 'admin'),
'hostname' => get_string('hostname', 'tool_task'),
'pid' => get_string('pid', 'tool_task'),
'db' => get_string('task_dbstats', 'admin'),
'result' => get_string('task_result', 'admin'),
'actions' => '',
];
$this->define_columns(array_keys($columnheaders));
$this->define_headers(array_values($columnheaders));
// The name column is a header.
$this->define_header_column('classname');
// This table is not collapsible.
$this->collapsible(false);
// The actions class should not wrap. Use the BS text utility class.
$this->column_class('actions', 'text-nowrap');
// Allow pagination.
$this->pageable(true);
// Allow sorting. Default to sort by timestarted DESC.
$this->sortable(true, 'timestart', SORT_DESC);
// Add filtering.
$where = [];
$params = [];
if (!empty($filter)) {
$orwhere = [];
$filter = str_replace('\\', '\\\\', $filter);
// Check the class name.
$orwhere[] = $DB->sql_like('classname', ':classfilter', false, false);
$params['classfilter'] = '%' . $DB->sql_like_escape($filter) . '%';
$orwhere[] = $DB->sql_like('output', ':outputfilter', false, false);
$params['outputfilter'] = '%' . $DB->sql_like_escape($filter) . '%';
$where[] = "(" . implode(' OR ', $orwhere) . ")";
}
if (null !== $resultfilter) {
$where[] = 'tl.result = :result';
$params['result'] = $resultfilter;
}
$where = implode(' AND ', $where);
$this->set_sql('', '', $where, $params);
}
/**
* Query the db. Store results in the table object for use by build_table.
*
* @param int $pagesize size of page for paginated displayed table.
* @param bool $useinitialsbar do you want to use the initials bar. Bar
* will only be used if there is a fullname column defined for the table.
*/
public function query_db($pagesize, $useinitialsbar = true) {
global $DB;
// Fetch the attempts.
$sort = $this->get_sql_sort();
if ($sort) {
$sort = "ORDER BY $sort";
}
// TODO Does not support custom user profile fields (MDL-70456).
$userfieldsapi = \core_user\fields::for_identity(\context_system::instance(), false)->with_userpic();
$userfields = $userfieldsapi->get_sql('u', false, 'user', 'userid2', false)->selects;
$where = '';
if (!empty($this->sql->where)) {
$where = "WHERE {$this->sql->where}";
}
$sql = "SELECT
tl.id, tl.type, tl.component, tl.classname, tl.userid, tl.timestart, tl.timeend,
tl.hostname, tl.pid,
tl.dbreads, tl.dbwrites, tl.result,
tl.dbreads + tl.dbwrites AS db,
tl.timeend - tl.timestart AS duration,
{$userfields}
FROM {task_log} tl
LEFT JOIN {user} u ON u.id = tl.userid
{$where}
{$sort}";
$this->pagesize($pagesize, $DB->count_records_sql("SELECT COUNT('x') FROM {task_log} tl {$where}", $this->sql->params));
if (!$this->is_downloading()) {
$this->rawdata = $DB->get_records_sql($sql, $this->sql->params, $this->get_page_start(), $this->get_page_size());
} else {
$this->rawdata = $DB->get_records_sql($sql, $this->sql->params);
}
}
/**
* Format the name cell.
*
* @param \stdClass $row
* @return string
*/
public function col_classname($row) : string {
$output = '';
if (class_exists($row->classname)) {
$task = new $row->classname;
if ($task instanceof \core\task\scheduled_task) {
$output = $task->get_name();
}
}
$output .= \html_writer::tag('div', "\\{$row->classname}", [
'class' => 'task-class',
]);
return $output;
}
/**
* Format the type cell.
*
* @param \stdClass $row
* @return string
*/
public function col_type($row) : string {
if (\core\task\database_logger::TYPE_SCHEDULED == $row->type) {
return get_string('task_type:scheduled', 'admin');
} else {
return get_string('task_type:adhoc', 'admin');
}
}
/**
* Format the timestart cell.
*
* @param \stdClass $row
* @return string
*/
public function col_result($row) : string {
if ($row->result) {
return get_string('task_result:failed', 'admin');
} else {
return get_string('success');
}
}
/**
* Format the timestart cell.
*
* @param \stdClass $row
* @return string
*/
public function col_timestart($row) : string {
return userdate($row->timestart, get_string('strftimedatetimeshort', 'langconfig'));
}
/**
* Format the duration cell.
*
* @param \stdClass $row
* @return string
*/
public function col_duration($row) : string {
$duration = round($row->timeend - $row->timestart, 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);
}
/**
* Format the DB details cell.
*
* @param \stdClass $row
* @return string
*/
public function col_db($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;
}
/**
* Format the actions cell.
*
* @param \stdClass $row
* @return string
*/
public function col_actions($row) : string {
global $OUTPUT;
$actions = [];
$url = new \moodle_url('/admin/tasklogs.php', ['logid' => $row->id]);
// Quick view.
$actions[] = $OUTPUT->action_icon(
$url,
new \pix_icon('e/search', get_string('view')),
new \popup_action('click', $url)
);
// Download.
$actions[] = $OUTPUT->action_icon(
new \moodle_url($url, ['download' => true]),
new \pix_icon('t/download', get_string('download'))
);
return implode('&nbsp;', $actions);
}
/**
* Format the user cell.
*
* @param \stdClass $row
* @return string
*/
public function col_userid($row) : string {
if (empty($row->userid)) {
return '';
}
$user = (object) [];
username_load_fields_from_object($user, $row, 'user');
return fullname($user);
}
}
-131
View File
@@ -1,131 +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");
require_once("{$CFG->libdir}/cronlib.php");
list($options, $unrecognized) = cli_get_params(
[
'execute' => false,
'help' => false,
'keep-alive' => 0,
'showsql' => false,
'showdebugging' => false,
'ignorelimits' => false,
'force' => false,
], [
'h' => 'help',
'e' => 'execute',
'k' => 'keep-alive',
'i' => 'ignorelimits',
'f' => 'force',
]
);
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
if ($options['help'] or empty($options['execute'])) {
$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
Example:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --execute
EOT;
echo $help;
die;
}
if ($options['showdebugging']) {
set_debugging(DEBUG_DEVELOPER, true);
}
if ($options['showsql']) {
$DB->set_debug(true);
}
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 (empty($options['execute'])) {
exit(0);
}
if (!get_config('core', 'cron_enabled') && !$options['force']) {
mtrace('Cron is disabled. Use --force to override.');
exit(1);
}
if (empty($options['keep-alive'])) {
$options['keep-alive'] = 0;
}
if (!empty($CFG->showcronsql)) {
$DB->set_debug(true);
}
if (!empty($CFG->showcrondebugging)) {
set_debugging(DEBUG_DEVELOPER, true);
}
$checklimits = empty($options['ignorelimits']);
core_php_time_limit::raise();
// Increase memory limit.
raise_memory_limit(MEMORY_EXTRA);
// Emulate normal session - we use admin account by default.
cron_setup_user();
$humantimenow = date('r', time());
$keepalive = (int)$options['keep-alive'];
\core\local\cli\shutdown::script_supports_graceful_exit();
mtrace("Server Time: {$humantimenow}\n");
cron_run_adhoc_tasks(time(), $keepalive, $checklimits);
+1 -1
View File
@@ -28,7 +28,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
require_once($CFG->libdir.'/cronlib.php');
+1 -1
View File
@@ -25,7 +25,7 @@
define('CLI_SCRIPT', 1);
require(__DIR__.'/../../config.php');
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/clilib.php');
require_once($CFG->dirroot . '/backup/util/includes/backup_includes.php');
-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);
}
-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);
+4 -121
View File
@@ -30,30 +30,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
require_once($CFG->libdir.'/cronlib.php');
// now get cli options
list($options, $unrecognized) = cli_get_params(
[
'help' => false,
'stop' => false,
'list' => false,
'force' => false,
'enable' => false,
'disable' => false,
'disable-wait' => false,
], [
'h' => 'help',
's' => 'stop',
'l' => 'list',
'f' => 'force',
'e' => 'enable',
'd' => 'disable',
'w' => 'disable-wait',
]
);
list($options, $unrecognized) = cli_get_params(array('help'=>false),
array('h'=>'help'));
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
@@ -65,13 +48,7 @@ if ($options['help']) {
"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)
-h, --help Print out this help
Example:
\$sudo -u www-data /usr/bin/php admin/cli/cron.php
@@ -81,98 +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();
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);
-1
View File
@@ -73,7 +73,6 @@ foreach ($rs as $user) {
echo "Redeleting user $user->id: $user->username ($user->email)\n";
delete_user($user);
}
$rs->close();
cli_heading('Deleting all leftovers');
-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.");
}
-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";
+200 -259
View File
@@ -74,14 +74,12 @@ Options:
--adminpass=PASSWORD Password for the moodle admin account,
required in non-interactive mode.
--adminemail=STRING Email address for the moodle admin account.
--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:
@@ -90,7 +88,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);
@@ -100,7 +98,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');
@@ -146,15 +144,20 @@ 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.4.4") < 0) {
$phpversion = phpversion();
// do NOT localise - lang strings would not work here and we CAN NOT move it after installib
fwrite(STDERR, "Moodle 2.7 or later requires at least PHP 5.4.4 (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;
@@ -167,7 +170,7 @@ $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
@@ -215,11 +218,11 @@ 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) {
@@ -239,7 +242,7 @@ 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',
@@ -254,11 +257,9 @@ list($options, $unrecognized) = cli_get_params(
'adminuser' => 'admin',
'adminpass' => '',
'adminemail' => '',
'upgradekey' => '',
'non-interactive' => false,
'agree-license' => false,
'allow-unstable' => false,
'skip-database' => false,
'help' => false
),
array(
@@ -267,12 +268,10 @@ 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;
}
@@ -287,41 +286,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;
@@ -393,6 +379,7 @@ if ($interactive) {
$CFG->wwwroot = $wwwroot;
$CFG->httpswwwroot = $CFG->wwwroot;
//We need dataroot before lang download
$CFG->dataroot = $options['dataroot'];
if ($interactive) {
@@ -443,7 +430,6 @@ if ($interactive) {
}
}
$CFG->tempdir = $CFG->dataroot.'/temp';
$CFG->backuptempdir = $CFG->tempdir.'/backup';
$CFG->cachedir = $CFG->dataroot.'/cache';
$CFG->localcachedir = $CFG->dataroot.'/localcache';
@@ -515,105 +501,100 @@ 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 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->dboptions['dbport'] = (int)$options['dbport'];
}
if ($CFG->dboptions['dbport'] <= 0) {
$CFG->dboptions['dbport'] = '';
}
// 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 {
$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 {
@@ -621,157 +602,127 @@ 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, 'dbport'=>$CFG->dboptions['dbport'], 'dbsocket'=>$CFG->dboptions['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, 'dbport'=>$CFG->dboptions['dbport'], 'dbsocket'=>$CFG->dboptions['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'));
}
} else {
$CFG->dbpass = $options['dbpass'];
$hint_database = 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 ($hint_database !== '') {
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'));
// 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']));
if ($options['fullname'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $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']];
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));
}
}
// Ask for the upgrade key.
// ask for shortname
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('shortsitename', 'moodle'));
if ($options['shortname'] !== '') {
$prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
} else {
$prompt = get_string('clitypevalue', 'admin');
$options['upgradekey'] = cli_input($prompt);
}
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));
}
}
// Set the upgrade key if it was provided.
if ($options['upgradekey'] !== '') {
$CFG->upgradekey = $options['upgradekey'];
// 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']) or $options['adminuser'] === 'guest') {
$a = (object)array('option'=>'adminuser', 'value'=>$options['adminuser']);
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);
}
}
} else {
if (!$options['agree-license'] && !$skipdatabase) {
cli_error(get_string('climustagreelicense', 'install'));
// 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));
}
}
// 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);
}
// 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));
}
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
@@ -819,17 +770,7 @@ if (!core_plugin_manager::instance()->all_plugins_ok($version, $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
+14 -23
View File
@@ -56,19 +56,23 @@ Options:
--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.4.4") < 0) {
$phpversion = phpversion();
// do NOT localise - lang strings would not work here and we CAN NOT move it after installib
fwrite(STDERR, "Moodle 2.7 or later requires at least PHP 5.4.4 (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 +87,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);
@@ -97,7 +106,6 @@ list($options, $unrecognized) = cli_get_params(
'adminemail' => '',
'fullname' => '',
'shortname' => '',
'summary' => '',
'agree-license' => false,
'help' => false
),
@@ -106,22 +114,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
}
@@ -185,12 +183,5 @@ if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
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);
+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;
}
+3 -3
View File
@@ -25,7 +25,7 @@
define('CLI_SCRIPT', true);
require(__DIR__.'/../../config.php');
require(dirname(__FILE__).'/../../config.php');
require_once($CFG->libdir . '/clilib.php');
if ($DB->get_dbfamily() !== 'mysql') {
@@ -158,7 +158,7 @@ if (!empty($options['info'])) {
}
foreach ($fixtables as $table) {
$DB->change_database_structure("ALTER TABLE `{$prefix}$table` ROW_FORMAT=Compressed");
$DB->change_database_structure("ALTER TABLE {$prefix}$table ROW_FORMAT=Compressed");
echo str_pad($prefix . $table, 32, ' ', STR_PAD_RIGHT) . " ... Compressed\n";
}
@@ -189,7 +189,7 @@ if (!empty($options['info'])) {
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 "ALTER TABLE {$prefix}$table ROW_FORMAT=Compressed;\n";
}
echo "\n";
exit(0);
+1 -1
View File
@@ -26,7 +26,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') {
+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()) {
print_error('noadmins');
}
if (!file_exists($options['file'])) {
print_error('filenotfound');
}
if (!$category = $DB->get_record('course_categories', ['id' => $options['categoryid']], 'id')) {
print_error('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);
print_error('generalexceptionmessage', 'error', '', $e->getMessage());
}
cli_heading(get_string('restoredcourseid', 'backup', $courseid));
exit(0);
-168
View File
@@ -1,168 +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");
require_once("$CFG->libdir/cronlib.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']) {
set_debugging(DEBUG_DEVELOPER, true);
}
if ($options['showsql']) {
$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.
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);
}
cron_run_inner_scheduled_task($task);
}
-183
View File
@@ -1,183 +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 uninstall plugins.
*
* @package core
* @subpackage cli
* @copyright 2018 Dmitrii Metelkin <dmitriim@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->libdir . '/adminlib.php');
$help = "Command line tool to uninstall plugins.
Options:
-h --help Print this help.
--show-all Displays a list of all installed plugins.
--show-contrib Displays a list of all third-party installed plugins.
--show-missing Displays a list of plugins missing from disk.
--purge-missing Uninstall all missing from disk plugins.
--plugins=<plugin name> A comma separated list of plugins to be uninstalled. E.g. mod_assign,mod_forum
--run Execute uninstall. If this option is not set, then the script will be run in a dry mode.
--showsql Show sql queries before they are executed.
--showdebugging Show developer level debugging information.
Examples:
# php uninstall_plugins.php --show-all
Prints tab-separated list of all installed plugins.
# php uninstall_plugins.php --show-contrib
Prints tab-separated list of all third-party installed plugins.
# php uninstall_plugins.php --show-missing
Prints tab-separated list of all missing from disk plugins.
# php uninstall_plugins.php --purge-missing
A dry run of uninstalling all missing plugins.
# php uninstall_plugins.php --purge-missing --run
Run uninstall of all missing plugins.
# php uninstall_plugins.php --plugins=mod_assign,mod_forum
A dry run of uninstalling mod_assign and mod_forum plugins.
# php uninstall_plugins.php --plugins=mod_assign,mod_forum --run
Run uninstall for mod_assign and mod_forum plugins.
";
list($options, $unrecognised) = cli_get_params([
'help' => false,
'show-all' => false,
'show-contrib' => false,
'show-missing' => false,
'purge-missing' => false,
'plugins' => false,
'run' => false,
'showsql' => false,
'showdebugging' => false,
], [
'h' => 'help'
]);
if ($unrecognised) {
$unrecognised = implode(PHP_EOL.' ', $unrecognised);
cli_error(get_string('cliunknowoption', 'core_admin', $unrecognised));
}
if ($options['help']) {
cli_writeln($help);
exit(0);
}
if ($options['showdebugging']) {
set_debugging(DEBUG_DEVELOPER, true);
}
if ($options['showsql']) {
$DB->set_debug(true);
}
$pluginman = core_plugin_manager::instance();
$plugininfo = $pluginman->get_plugins();
if ($options['show-all'] || $options['show-missing'] || $options['show-contrib']) {
foreach ($plugininfo as $type => $plugins) {
foreach ($plugins as $name => $plugin) {
if ($options['show-contrib'] && $plugin->is_standard()) {
continue;
}
$pluginstring = $plugin->component . "\t" . $plugin->displayname;
if ($options['show-all'] || $options['show-contrib']) {
cli_writeln($pluginstring);
} else {
if ($plugin->get_status() === core_plugin_manager::PLUGIN_STATUS_MISSING) {
cli_writeln($pluginstring);
}
}
}
}
exit(0);
}
if ($options['purge-missing']) {
foreach ($plugininfo as $type => $plugins) {
foreach ($plugins as $name => $plugin) {
if ($plugin->get_status() === core_plugin_manager::PLUGIN_STATUS_MISSING) {
$pluginstring = $plugin->component . "\t" . $plugin->displayname;
if ($pluginman->can_uninstall_plugin($plugin->component)) {
if ($options['run']) {
cli_writeln('Uninstalling: ' . $pluginstring);
$progress = new progress_trace_buffer(new text_progress_trace(), true);
$pluginman->uninstall_plugin($plugin->component, $progress);
$progress->finished();
cli_write($progress->get_buffer());
} else {
cli_writeln('Will be uninstalled: ' . $pluginstring);
}
} else {
cli_writeln('Can not be uninstalled: ' . $pluginstring);
}
}
}
}
exit(0);
}
if ($options['plugins']) {
$components = explode(',', $options['plugins']);
foreach ($components as $component) {
$plugin = $pluginman->get_plugin_info($component);
if (is_null($plugin)) {
cli_writeln('Unknown plugin: ' . $component);
} else {
$pluginstring = $plugin->component . "\t" . $plugin->displayname;
if ($pluginman->can_uninstall_plugin($plugin->component)) {
if ($options['run']) {
cli_writeln('Uninstalling: ' . $pluginstring);
$progress = new progress_trace_buffer(new text_progress_trace(), true);
$pluginman->uninstall_plugin($plugin->component, $progress);
$progress->finished();
cli_write($progress->get_buffer());
} else {
cli_writeln('Will be uninstalled: ' . $pluginstring);
}
} else {
cli_writeln('Can not be uninstalled: ' . $pluginstring);
}
}
}
exit(0);
}
cli_writeln($help);
exit(0);
+10 -62
View File
@@ -38,32 +38,24 @@ if (function_exists('opcache_reset') and !isset($_SERVER['REMOTE_ADDR'])) {
define('CLI_SCRIPT', true);
define('CACHE_DISABLE_ALL', true);
require(__DIR__.'/../../config.php');
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/adminlib.php'); // various admin-only functions
require_once($CFG->libdir.'/upgradelib.php'); // general upgrade/install related functions
require_once($CFG->libdir.'/clilib.php'); // cli only functions
require_once($CFG->libdir.'/environmentlib.php');
// now get cli options
$lang = isset($SESSION->lang) ? $SESSION->lang : $CFG->lang;
list($options, $unrecognized) = cli_get_params(
array(
'non-interactive' => false,
'allow-unstable' => false,
'help' => false,
'lang' => $lang,
'verbose-settings' => false,
'is-pending' => false,
'help' => false
),
array(
'h' => 'help'
)
);
if ($options['lang']) {
$SESSION->lang = $options['lang'];
}
$interactive = empty($options['non-interactive']);
if ($unrecognized) {
@@ -82,15 +74,6 @@ Options:
--non-interactive No interactive questions or confirmations
--allow-unstable Upgrade even if the version is not marked as stable yet,
required in non-interactive mode.
--lang=CODE Set preferred language for CLI output. Defaults to the
site language if not set. Defaults to 'en' if the lang
parameter is invalid or if the language pack is not
installed.
--verbose-settings Show new settings values. By default only the name of
new core or plugin settings are displayed. This option
outputs the new values as well as the setting name.
--is-pending If an upgrade is needed it exits with an error code of
2 so it distinct from other types of errors.
-h, --help Print out this help
Example:
@@ -119,10 +102,6 @@ if (!moodle_needs_upgrading()) {
cli_error(get_string('cliupgradenoneed', 'core_admin', $newversion), 0);
}
if ($options['is-pending']) {
cli_error(get_string('cliupgradepending', 'core_admin'), 2);
}
// Test environment first.
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
if (!$envstatus) {
@@ -135,27 +114,17 @@ if (!$envstatus) {
exit(1);
}
// Make sure there are no files left over from previous versions.
if (upgrade_stale_php_files_present()) {
cli_problem(get_string('upgradestalefiles', 'admin'));
// Stale file info contains HTML elements which aren't suitable for CLI.
$upgradestalefilesinfo = get_string('upgradestalefilesinfo', 'admin', get_docs_url('Upgrading'));
cli_error(strip_tags($upgradestalefilesinfo));
}
// Test plugin dependencies.
$failed = array();
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed, $CFG->branch)) {
if (!core_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'));
}
$a = new stdClass();
$a->oldversion = $oldversion;
$a->newversion = $newversion;
if ($interactive) {
$a = new stdClass();
$a->oldversion = $oldversion;
$a->newversion = $newversion;
echo cli_heading(get_string('databasechecking', '', $a)) . PHP_EOL;
}
@@ -204,30 +173,9 @@ upgrade_noncore(true);
// log in as admin - we need doanything permission when applying defaults
\core\session\manager::set_user(get_admin());
// Apply default settings and output those that have changed.
cli_heading(get_string('cliupgradedefaultheading', 'admin'));
$settingsoutput = admin_apply_default_settings(null, false);
// apply all default settings, just in case do it twice to fill all defaults
admin_apply_default_settings(NULL, false);
admin_apply_default_settings(NULL, false);
foreach ($settingsoutput as $setting => $value) {
if ($options['verbose-settings']) {
$stringvlaues = array(
'name' => $setting,
'defaultsetting' => var_export($value, true) // Expand objects.
);
echo get_string('cliupgradedefaultverbose', 'admin', $stringvlaues) . PHP_EOL;
} else {
echo get_string('cliupgradedefault', 'admin', $setting) . PHP_EOL;
}
}
// 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.
upgrade_themes();
echo get_string('cliupgradefinished', 'admin', $a)."\n";
echo get_string('cliupgradefinished', 'admin')."\n";
exit(0); // 0 means success
-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/>.
/**
* Content bank and its plugins settings.
*
* @package core
* @subpackage contentbank
* @copyright 2020 Amaia Anabitarte <amaia@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
$action = required_param('action', PARAM_ALPHANUMEXT);
$name = required_param('name', PARAM_PLUGIN);
$syscontext = context_system::instance();
$PAGE->set_url('/admin/contentbank.php');
$PAGE->set_context($syscontext);
require_admin();
require_sesskey();
$return = new moodle_url('/admin/settings.php', array('section' => 'managecontentbanktypes'));
$plugins = core_plugin_manager::instance()->get_plugins_of_type('contenttype');
$sortorder = array_flip(array_keys($plugins));
if (!isset($plugins[$name])) {
print_error('contenttypenotfound', 'error', $return, $name);
}
switch ($action) {
case 'disable':
if ($plugins[$name]->is_enabled()) {
set_config('disabled', 1, 'contentbank_'. $name);
}
break;
case 'enable':
if (!$plugins[$name]->is_enabled()) {
unset_config('disabled', 'contentbank_'. $name);
}
break;
case 'up':
if ($sortorder[$name]) {
$currentindex = $sortorder[$name];
$seq = array_keys($plugins);
$seq[$currentindex] = $seq[$currentindex - 1];
$seq[$currentindex - 1] = $name;
set_config('contentbank_plugins_sortorder', implode(',', $seq));
}
break;
case 'down':
if ($sortorder[$name] < count($sortorder) - 1) {
$currentindex = $sortorder[$name];
$seq = array_keys($plugins);
$seq[$currentindex] = $seq[$currentindex + 1];
$seq[$currentindex + 1] = $name;
set_config('contentbank_plugins_sortorder', implode(',', $seq));
}
break;
}
core_plugin_manager::reset_caches();
$cache = cache::make('core', 'contentbank_enabled_extensions');
$cache->purge();
$cache = cache::make('core', 'contentbank_context_extensions');
$cache->purge();
redirect($return);
+2 -1
View File
@@ -32,7 +32,8 @@ $syscontext = context_system::instance();
$PAGE->set_url('/admin/courseformats.php');
$PAGE->set_context($syscontext);
require_admin();
require_login();
require_capability('moodle/site:config', $syscontext);
require_sesskey();
$return = new moodle_url('/admin/settings.php', array('section' => 'manageformats'));
-61
View File
@@ -1,61 +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 the admin to enable, disable and uninstall custom fields
*
* @package core_admin
* @copyright 2018 Daniel Neis Araujo
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
$action = required_param('action', PARAM_ALPHANUMEXT);
$customfieldname = required_param('field', PARAM_PLUGIN);
$syscontext = context_system::instance();
$PAGE->set_url('/admin/customfields.php');
$PAGE->set_context($syscontext);
require_admin();
require_sesskey();
$return = new moodle_url('/admin/settings.php', array('section' => 'managecustomfields'));
$customfieldplugins = core_plugin_manager::instance()->get_plugins_of_type('customfield');
$sortorder = array_flip(array_keys($customfieldplugins));
if (!isset($customfieldplugins[$customfieldname])) {
print_error('customfieldnotfound', 'error', $return, $customfieldname);
}
switch ($action) {
case 'disable':
if ($customfieldplugins[$customfieldname]->is_enabled()) {
set_config('disabled', 1, 'customfield_'. $customfieldname);
core_plugin_manager::reset_caches();
}
break;
case 'enable':
if (!$customfieldplugins[$customfieldname]->is_enabled()) {
unset_config('disabled', 'customfield_'. $customfieldname);
core_plugin_manager::reset_caches();
}
break;
}
redirect($return);
-81
View File
@@ -1,81 +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/>.
/**
* Lets users manage data formats
*
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @copyright 2016 Brendan Heywood (brendan@catalyst-au.net)
* @package core
* @subpackage dataformat
*/
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
$action = required_param('action', PARAM_ALPHANUMEXT);
$name = required_param('name', PARAM_PLUGIN);
$syscontext = context_system::instance();
$PAGE->set_url('/admin/dataformats.php');
$PAGE->set_context($syscontext);
require_admin();
require_sesskey();
$return = new moodle_url('/admin/settings.php', array('section' => 'managedataformats'));
$plugins = core_plugin_manager::instance()->get_plugins_of_type('dataformat');
$sortorder = array_flip(array_keys($plugins));
if (!isset($plugins[$name])) {
print_error('courseformatnotfound', 'error', $return, $name);
}
switch ($action) {
case 'disable':
if ($plugins[$name]->is_enabled()) {
set_config('disabled', 1, 'dataformat_'. $name);
core_plugin_manager::reset_caches();
}
break;
case 'enable':
if (!$plugins[$name]->is_enabled()) {
unset_config('disabled', 'dataformat_'. $name);
core_plugin_manager::reset_caches();
}
break;
case 'up':
if ($sortorder[$name]) {
$currentindex = $sortorder[$name];
$seq = array_keys($plugins);
$seq[$currentindex] = $seq[$currentindex - 1];
$seq[$currentindex - 1] = $name;
set_config('dataformat_plugins_sortorder', implode(',', $seq));
}
break;
case 'down':
if ($sortorder[$name] < count($sortorder) - 1) {
$currentindex = $sortorder[$name];
$seq = array_keys($plugins);
$seq[$currentindex] = $seq[$currentindex + 1];
$seq[$currentindex + 1] = $name;
set_config('dataformat_plugins_sortorder', implode(',', $seq));
}
break;
}
redirect($return);
+2 -5
View File
@@ -15,7 +15,8 @@ $confirm = optional_param('confirm', 0, PARAM_BOOL);
$PAGE->set_url('/admin/editors.php', array('action'=>$action, 'editor'=>$editor));
$PAGE->set_context(context_system::instance());
require_admin();
require_login();
require_capability('moodle/site:config', context_system::instance());
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=manageeditors";
@@ -46,7 +47,6 @@ switch ($action) {
// remove from enabled list
$key = array_search($editor, $active_editors);
unset($active_editors[$key]);
add_to_config_log('editor_visibility', '1', '0', $editor);
break;
case 'enable':
@@ -54,7 +54,6 @@ switch ($action) {
if (!in_array($editor, $active_editors)) {
$active_editors[] = $editor;
$active_editors = array_unique($active_editors);
add_to_config_log('editor_visibility', '0', '1', $editor);
}
break;
@@ -67,7 +66,6 @@ switch ($action) {
$fsave = $active_editors[$key];
$active_editors[$key] = $active_editors[$key + 1];
$active_editors[$key + 1] = $fsave;
add_to_config_log('editor_position', $key, $key + 1, $editor);
}
}
break;
@@ -81,7 +79,6 @@ switch ($action) {
$fsave = $active_editors[$key];
$active_editors[$key] = $active_editors[$key - 1];
$active_editors[$key - 1] = $fsave;
add_to_config_log('editor_position', $key, $key - 1, $editor);
}
}
break;
+2 -1
View File
@@ -35,7 +35,8 @@ $confirm = optional_param('confirm', 0, PARAM_BOOL);
$PAGE->set_url('/admin/enrol.php');
$PAGE->set_context(context_system::instance());
require_admin();
require_login();
require_capability('moodle/site:config', context_system::instance());
require_sesskey();
$enabled = enrol_get_plugins(true);
File diff suppressed because it is too large Load Diff
+6 -2
View File
@@ -22,12 +22,16 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->libdir . '/adminlib.php');
$action = optional_param('action', '', PARAM_ALPHA);
$filterpath = optional_param('filterpath', '', PARAM_PLUGIN);
require_login();
$systemcontext = context_system::instance();
require_capability('moodle/site:config', $systemcontext);
admin_externalpage_setup('managefilters');
// Clean up bogus filter states first.
@@ -214,7 +218,7 @@ function get_table_row(\core\plugininfo\filter $plugininfo, $state, $isfirstrow,
// Re-order.
$updown = '';
$spacer = $OUTPUT->spacer();
$spacer = '<img src="' . $OUTPUT->pix_url('spacer') . '" class="iconsmall" alt="" />';
if ($state->active != TEXTFILTER_DISABLED) {
if (!$isfirstrow) {
$updown .= $OUTPUT->action_icon(filters_action_url($filter, 'up'), new pix_icon('t/up', get_string('up'), '', array('class' => 'iconsmall')));
+74 -389
View File
@@ -29,9 +29,14 @@ if (!file_exists('../config.php')) {
die();
}
// 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 as soon as possible
if (version_compare(phpversion(), '5.4.4') < 0) {
$phpversion = phpversion();
// do NOT localise - lang strings would not work here and we CAN NOT move it to later place
echo "Moodle 2.7 or later requires at least PHP 5.4.4 (currently using version $phpversion).<br />";
echo "Please upgrade your server software or install older Moodle version.";
die();
}
// make sure iconv is available and actually works
if (!function_exists('iconv')) {
@@ -47,24 +52,8 @@ if (!function_exists('json_encode') || !function_exists('json_decode')) {
die();
}
// Make sure xml extension is available.
if (!extension_loaded('xml')) {
echo 'Moodle requires the xml PHP extension. Please install or enable the xml extension.';
die();
}
define('NO_OUTPUT_BUFFERING', true);
if (isset($_POST['upgradekey'])) {
// Before you start reporting issues about the collision attacks against
// SHA-1, you should understand that we are not actually attempting to do
// any cryptography here. This is hashed purely so that the key is not
// that apparent in the address bar itself. Anyone who catches the HTTP
// traffic can immediately use it as a valid admin key.
header('Location: index.php?cache=0&upgradekeyhash='.sha1($_POST['upgradekey']));
die();
}
if ((isset($_GET['cache']) and $_GET['cache'] === '0')
or (isset($_POST['cache']) and $_POST['cache'] === '0')
or (!isset($_POST['cache']) and !isset($_GET['cache']) and empty($_GET['sesskey']) and empty($_POST['sesskey']))) {
@@ -96,60 +85,25 @@ if (function_exists('opcache_invalidate')) {
// indirectly calls the protected init() method is good here.
core_component::get_core_subsystems();
if (is_major_upgrade_required() && isloggedin()) {
// A major upgrade is required.
// Terminate the session and redirect back here before anything DB-related happens.
redirect_if_major_upgrade_required();
}
require_once($CFG->libdir.'/adminlib.php'); // various admin-only functions
require_once($CFG->libdir.'/upgradelib.php'); // general upgrade/install related functions
$confirmupgrade = optional_param('confirmupgrade', 0, PARAM_BOOL); // Core upgrade confirmed?
$confirmrelease = optional_param('confirmrelease', 0, PARAM_BOOL); // Core release info and server checks confirmed?
$confirmplugins = optional_param('confirmplugincheck', 0, PARAM_BOOL); // Plugins check page confirmed?
$showallplugins = optional_param('showallplugins', 0, PARAM_BOOL); // Show all plugins on the plugins check page?
$agreelicense = optional_param('agreelicense', 0, PARAM_BOOL); // GPL license confirmed for installation?
$fetchupdates = optional_param('fetchupdates', 0, PARAM_BOOL); // Should check for available updates?
$newaddonreq = optional_param('installaddonrequest', null, PARAM_RAW); // Plugin installation requested at moodle.org/plugins.
$upgradekeyhash = optional_param('upgradekeyhash', null, PARAM_ALPHANUM); // Hash of provided upgrade key.
$installdep = optional_param('installdep', null, PARAM_COMPONENT); // Install given missing dependency (required plugin).
$installdepx = optional_param('installdepx', false, PARAM_BOOL); // Install all missing dependencies.
$confirminstalldep = optional_param('confirminstalldep', false, PARAM_BOOL); // Installing dependencies confirmed.
$abortinstall = optional_param('abortinstall', null, PARAM_COMPONENT); // Cancel installation of the given new plugin.
$abortinstallx = optional_param('abortinstallx', null, PARAM_BOOL); // Cancel installation of all new plugins.
$confirmabortinstall = optional_param('confirmabortinstall', false, PARAM_BOOL); // Installation cancel confirmed.
$abortupgrade = optional_param('abortupgrade', null, PARAM_COMPONENT); // Cancel upgrade of the given existing plugin.
$abortupgradex = optional_param('abortupgradex', null, PARAM_BOOL); // Cancel upgrade of all upgradable plugins.
$confirmabortupgrade = optional_param('confirmabortupgrade', false, PARAM_BOOL); // Upgrade cancel confirmed.
$installupdate = optional_param('installupdate', null, PARAM_COMPONENT); // Install given available update.
$installupdateversion = optional_param('installupdateversion', null, PARAM_INT); // Version of the available update to install.
$installupdatex = optional_param('installupdatex', false, PARAM_BOOL); // Install all available plugin updates.
$confirminstallupdate = optional_param('confirminstallupdate', false, PARAM_BOOL); // Available update(s) install confirmed?
if (!empty($CFG->disableupdateautodeploy)) {
// Invalidate all requests to install plugins via the admin UI.
$newaddonreq = null;
$installdep = null;
$installdepx = false;
$abortupgrade = null;
$abortupgradex = null;
$installupdate = null;
$installupdateversion = null;
$installupdatex = false;
}
$confirmupgrade = optional_param('confirmupgrade', 0, PARAM_BOOL);
$confirmrelease = optional_param('confirmrelease', 0, PARAM_BOOL);
$confirmplugins = optional_param('confirmplugincheck', 0, PARAM_BOOL);
$showallplugins = optional_param('showallplugins', 0, PARAM_BOOL);
$agreelicense = optional_param('agreelicense', 0, PARAM_BOOL);
$fetchupdates = optional_param('fetchupdates', 0, PARAM_BOOL);
$newaddonreq = optional_param('installaddonrequest', null, PARAM_RAW);
// Set up PAGE.
$url = new moodle_url('/admin/index.php');
$url->param('cache', $cache);
if (isset($upgradekeyhash)) {
$url->param('upgradekeyhash', $upgradekeyhash);
}
$PAGE->set_url($url);
unset($url);
// Are we returning from an add-on installation request at moodle.org/plugins?
if ($newaddonreq and !$cache and empty($CFG->disableupdateautodeploy)) {
if ($newaddonreq and !$cache and empty($CFG->disableonclickaddoninstall)) {
$target = new moodle_url('/admin/tool/installaddon/index.php', array(
'installaddonrequest' => $newaddonreq,
'confirm' => 0));
@@ -220,13 +174,14 @@ if (!core_tables_exist()) {
$PAGE->set_heading($strinstallation);
$PAGE->set_cacheable(false);
/** @var core_admin_renderer $output */
$output = $PAGE->get_renderer('core', 'admin');
echo $output->install_licence_page();
die();
}
if (empty($confirmrelease)) {
require_once($CFG->libdir.'/environmentlib.php');
list($envstatus, $environmentresults) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
$strcurrentrelease = get_string('currentrelease');
$PAGE->navbar->add($strcurrentrelease);
@@ -234,20 +189,21 @@ if (!core_tables_exist()) {
$PAGE->set_heading($strinstallation . ' - Moodle ' . $CFG->target_release);
$PAGE->set_cacheable(false);
/** @var core_admin_renderer $output */
$output = $PAGE->get_renderer('core', 'admin');
echo $output->install_environment_page($maturity, $envstatus, $environmentresults, $release);
echo $output->install_environment_page($maturity, $envstatus, $environment_results, $release);
die();
}
// check plugin dependencies
$failed = array();
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed, $CFG->branch)) {
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
$PAGE->navbar->add(get_string('pluginscheck', 'admin'));
$PAGE->set_title($strinstallation);
$PAGE->set_heading($strinstallation . ' - Moodle ' . $CFG->target_release);
$output = $PAGE->get_renderer('core', 'admin');
$url = new moodle_url($PAGE->url, array('agreelicense' => 1, 'confirmrelease' => 1, 'lang' => $CFG->lang));
$url = new moodle_url('/admin/index.php', array('agreelicense' => 1, 'confirmrelease' => 1, 'lang' => $CFG->lang));
echo $output->unsatisfied_dependencies_page($version, $failed, $url);
die();
}
@@ -297,30 +253,17 @@ if (empty($CFG->version)) {
// Detect config cache inconsistency, this happens when you switch branches on dev servers.
if ($CFG->version != $DB->get_field('config', 'value', array('name'=>'version'))) {
purge_all_caches();
redirect(new moodle_url($PAGE->url), 'Config cache inconsistency detected, resetting caches...');
redirect(new moodle_url('/admin/index.php'), 'Config cache inconsistency detected, resetting caches...');
}
if (!$cache and $version > $CFG->version) { // upgrade
$PAGE->set_url(new moodle_url($PAGE->url, array(
'confirmupgrade' => $confirmupgrade,
'confirmrelease' => $confirmrelease,
'confirmplugincheck' => $confirmplugins,
)));
check_upgrade_key($upgradekeyhash);
// Warning about upgrading a test site.
$testsite = false;
if (defined('BEHAT_SITE_RUNNING')) {
$testsite = 'behat';
}
if (isset($CFG->themerev)) {
// Store the themerev to restore after purging caches.
$themerev = $CFG->themerev;
}
// We purge all of MUC's caches here.
// Caches are disabled for upgrade by CACHE_DISABLE_ALL so we must set the first arg to true.
// This ensures a real config object is loaded and the stores will be purged.
@@ -330,11 +273,7 @@ if (!$cache and $version > $CFG->version) { // upgrade
// We then purge the regular caches.
purge_all_caches();
if (isset($themerev)) {
// Restore the themerev
set_config('themerev', $themerev);
}
/** @var core_admin_renderer $output */
$output = $PAGE->get_renderer('core', 'admin');
if (upgrade_stale_php_files_present()) {
@@ -358,9 +297,9 @@ if (!$cache and $version > $CFG->version) { // upgrade
echo $output->upgrade_confirm_page($a->newversion, $maturity, $testsite);
die();
} else if (empty($confirmrelease)) {
} else if (empty($confirmrelease)){
require_once($CFG->libdir.'/environmentlib.php');
list($envstatus, $environmentresults) = check_moodle_environment($release, ENV_SELECT_RELEASE);
list($envstatus, $environment_results) = check_moodle_environment($release, ENV_SELECT_RELEASE);
$strcurrentrelease = get_string('currentrelease');
$PAGE->navbar->add($strcurrentrelease);
@@ -368,7 +307,7 @@ if (!$cache and $version > $CFG->version) { // upgrade
$PAGE->set_heading($strcurrentrelease);
$PAGE->set_cacheable(false);
echo $output->upgrade_environment_page($release, $envstatus, $environmentresults);
echo $output->upgrade_environment_page($release, $envstatus, $environment_results);
die();
} else if (empty($confirmplugins)) {
@@ -379,138 +318,40 @@ if (!$cache and $version > $CFG->version) { // upgrade
$PAGE->set_heading($strplugincheck);
$PAGE->set_cacheable(false);
$pluginman = core_plugin_manager::instance();
$reloadurl = new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1, 'cache' => 0));
// Check for available updates.
if ($fetchupdates) {
// No sesskey support guaranteed here, because sessions might not work yet.
$updateschecker = \core\update\checker::instance();
if ($updateschecker->enabled()) {
$updateschecker->fetch();
}
redirect($PAGE->url);
redirect($reloadurl);
}
// Cancel all plugin installations.
if ($abortinstallx) {
// No sesskey support guaranteed here, because sessions might not work yet.
$abortables = $pluginman->list_cancellable_installations();
if ($abortables) {
if ($confirmabortinstall) {
foreach ($abortables as $plugin) {
$pluginman->cancel_plugin_installation($plugin->component);
}
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstallx' => $abortinstallx, 'confirmabortinstall' => 1));
echo $output->upgrade_confirm_abort_install_page($abortables, $continue);
die();
}
}
redirect($PAGE->url);
}
$deployer = \core\update\deployer::instance();
if ($deployer->enabled()) {
$deployer->initialize($reloadurl, $reloadurl);
// Cancel single plugin installation.
if ($abortinstall) {
// No sesskey support guaranteed here, because sessions might not work yet.
if ($confirmabortinstall) {
$pluginman->cancel_plugin_installation($abortinstall);
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstall' => $abortinstall, 'confirmabortinstall' => 1));
$abortable = $pluginman->get_plugin_info($abortinstall);
if ($pluginman->can_cancel_plugin_installation($abortable)) {
echo $output->upgrade_confirm_abort_install_page(array($abortable), $continue);
die();
}
redirect($PAGE->url);
}
}
// Cancel all plugins upgrades (that is, restore archived versions).
if ($abortupgradex) {
// No sesskey support guaranteed here, because sessions might not work yet.
$restorable = $pluginman->list_restorable_archives();
if ($restorable) {
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgradex' => 1, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}
// Cancel single plugin upgrade (that is, install the archived version).
if ($abortupgrade) {
// No sesskey support guaranteed here, because sessions might not work yet.
$restorable = $pluginman->list_restorable_archives();
if (isset($restorable[$abortupgrade])) {
$restorable = array($restorable[$abortupgrade]);
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgrade' => $abortupgrade, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}
// Install all available missing dependencies.
if ($installdepx) {
// No sesskey support guaranteed here, because sessions might not work yet.
$installable = $pluginman->filter_installable($pluginman->missing_dependencies(true));
upgrade_install_plugins($installable, $confirminstalldep,
get_string('dependencyinstallhead', 'core_plugin'),
new moodle_url($PAGE->url, array('installdepx' => 1, 'confirminstalldep' => 1))
);
}
// Install single available missing dependency.
if ($installdep) {
// No sesskey support guaranteed here, because sessions might not work yet.
$installable = $pluginman->filter_installable($pluginman->missing_dependencies(true));
if (!empty($installable[$installdep])) {
$installable = array($installable[$installdep]);
upgrade_install_plugins($installable, $confirminstalldep,
get_string('dependencyinstallhead', 'core_plugin'),
new moodle_url($PAGE->url, array('installdep' => $installdep, 'confirminstalldep' => 1))
);
}
}
// Install all available updates.
if ($installupdatex) {
// No sesskey support guaranteed here, because sessions might not work yet.
$installable = $pluginman->filter_installable($pluginman->available_updates());
upgrade_install_plugins($installable, $confirminstallupdate,
get_string('updateavailableinstallallhead', 'core_admin'),
new moodle_url($PAGE->url, array('installupdatex' => 1, 'confirminstallupdate' => 1))
);
}
// Install single available update.
if ($installupdate and $installupdateversion) {
// No sesskey support guaranteed here, because sessions might not work yet.
if ($pluginman->is_remote_plugin_installable($installupdate, $installupdateversion)) {
$installable = array($pluginman->get_remote_plugin_info($installupdate, $installupdateversion, true));
upgrade_install_plugins($installable, $confirminstallupdate,
get_string('updateavailableinstallallhead', 'core_admin'),
new moodle_url($PAGE->url, array('installupdate' => $installupdate,
'installupdateversion' => $installupdateversion, 'confirminstallupdate' => 1)
)
);
$deploydata = $deployer->submitted_data();
if (!empty($deploydata)) {
// No sesskey support guaranteed here, because sessions might not work yet.
echo $output->upgrade_plugin_confirm_deploy_page($deployer, $deploydata);
die();
}
}
echo $output->upgrade_plugin_check_page(core_plugin_manager::instance(), \core\update\checker::instance(),
$version, $showallplugins, $PAGE->url, new moodle_url($PAGE->url, array('confirmplugincheck' => 1)));
$version, $showallplugins, $reloadurl,
new moodle_url('/admin/index.php', array('confirmupgrade'=>1, 'confirmrelease'=>1, 'confirmplugincheck'=>1, 'cache'=>0)));
die();
} else {
// Always verify plugin dependencies!
$failed = array();
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed, $CFG->branch)) {
echo $output->unsatisfied_dependencies_page($version, $failed, new moodle_url($PAGE->url,
array('confirmplugincheck' => 0)));
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
$reloadurl = new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1, 'cache' => 0));
echo $output->unsatisfied_dependencies_page($version, $failed, $reloadurl);
die();
}
unset($failed);
@@ -533,35 +374,10 @@ if (!$cache and $branch <> $CFG->branch) { // Update the branch
}
if (!$cache and moodle_needs_upgrading()) {
$PAGE->set_url(new moodle_url($PAGE->url, array(
'confirmrelease' => $confirmrelease,
'confirmplugincheck' => $confirmplugins,
)));
check_upgrade_key($upgradekeyhash);
if (!$PAGE->headerprinted) {
// means core upgrade or installation was not already done
$pluginman = core_plugin_manager::instance();
$output = $PAGE->get_renderer('core', 'admin');
if (empty($confirmrelease)) {
require_once($CFG->libdir . '/environmentlib.php');
list($envstatus, $environmentresults) = check_moodle_environment($release, ENV_SELECT_RELEASE);
$strcurrentrelease = get_string('currentrelease');
$PAGE->navbar->add($strcurrentrelease);
$PAGE->set_title($strcurrentrelease);
$PAGE->set_heading($strcurrentrelease);
$PAGE->set_cacheable(false);
echo $output->upgrade_environment_page($release, $envstatus, $environmentresults);
die();
} else if (!$confirmplugins) {
if (!$confirmplugins) {
$strplugincheck = get_string('plugincheck');
$PAGE->navbar->add($strplugincheck);
@@ -569,7 +385,6 @@ if (!$cache and moodle_needs_upgrading()) {
$PAGE->set_heading($strplugincheck);
$PAGE->set_cacheable(false);
// Check for available updates.
if ($fetchupdates) {
require_sesskey();
$updateschecker = \core\update\checker::instance();
@@ -579,131 +394,36 @@ if (!$cache and moodle_needs_upgrading()) {
redirect($PAGE->url);
}
// Cancel all plugin installations.
if ($abortinstallx) {
require_sesskey();
$abortables = $pluginman->list_cancellable_installations();
if ($abortables) {
if ($confirmabortinstall) {
foreach ($abortables as $plugin) {
$pluginman->cancel_plugin_installation($plugin->component);
}
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstallx' => $abortinstallx,
'confirmabortinstall' => 1));
echo $output->upgrade_confirm_abort_install_page($abortables, $continue);
die();
}
}
redirect($PAGE->url);
}
/** @var core_admin_renderer $output */
$output = $PAGE->get_renderer('core', 'admin');
// Cancel single plugin installation.
if ($abortinstall) {
require_sesskey();
if ($confirmabortinstall) {
$pluginman->cancel_plugin_installation($abortinstall);
redirect($PAGE->url);
} else {
$continue = new moodle_url($PAGE->url, array('abortinstall' => $abortinstall, 'confirmabortinstall' => 1));
$abortable = $pluginman->get_plugin_info($abortinstall);
if ($pluginman->can_cancel_plugin_installation($abortable)) {
echo $output->upgrade_confirm_abort_install_page(array($abortable), $continue);
die();
}
redirect($PAGE->url);
}
}
$deployer = \core\update\deployer::instance();
if ($deployer->enabled()) {
$deployer->initialize($PAGE->url, $PAGE->url);
// Cancel all plugins upgrades (that is, restore archived versions).
if ($abortupgradex) {
require_sesskey();
$restorable = $pluginman->list_restorable_archives();
if ($restorable) {
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgradex' => 1, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}
// Cancel single plugin upgrade (that is, install the archived version).
if ($abortupgrade) {
require_sesskey();
$restorable = $pluginman->list_restorable_archives();
if (isset($restorable[$abortupgrade])) {
$restorable = array($restorable[$abortupgrade]);
upgrade_install_plugins($restorable, $confirmabortupgrade,
get_string('cancelupgradehead', 'core_plugin'),
new moodle_url($PAGE->url, array('abortupgrade' => $abortupgrade, 'confirmabortupgrade' => 1))
);
}
redirect($PAGE->url);
}
// Install all available missing dependencies.
if ($installdepx) {
require_sesskey();
$installable = $pluginman->filter_installable($pluginman->missing_dependencies(true));
upgrade_install_plugins($installable, $confirminstalldep,
get_string('dependencyinstallhead', 'core_plugin'),
new moodle_url($PAGE->url, array('installdepx' => 1, 'confirminstalldep' => 1))
);
}
// Install single available missing dependency.
if ($installdep) {
require_sesskey();
$installable = $pluginman->filter_installable($pluginman->missing_dependencies(true));
if (!empty($installable[$installdep])) {
$installable = array($installable[$installdep]);
upgrade_install_plugins($installable, $confirminstalldep,
get_string('dependencyinstallhead', 'core_plugin'),
new moodle_url($PAGE->url, array('installdep' => $installdep, 'confirminstalldep' => 1))
);
}
}
// Install all available updates.
if ($installupdatex) {
require_sesskey();
$installable = $pluginman->filter_installable($pluginman->available_updates());
upgrade_install_plugins($installable, $confirminstallupdate,
get_string('updateavailableinstallallhead', 'core_admin'),
new moodle_url($PAGE->url, array('installupdatex' => 1, 'confirminstallupdate' => 1))
);
}
// Install single available update.
if ($installupdate and $installupdateversion) {
require_sesskey();
if ($pluginman->is_remote_plugin_installable($installupdate, $installupdateversion)) {
$installable = array($pluginman->get_remote_plugin_info($installupdate, $installupdateversion, true));
upgrade_install_plugins($installable, $confirminstallupdate,
get_string('updateavailableinstallallhead', 'core_admin'),
new moodle_url($PAGE->url, array('installupdate' => $installupdate,
'installupdateversion' => $installupdateversion, 'confirminstallupdate' => 1)
)
);
$deploydata = $deployer->submitted_data();
if (!empty($deploydata)) {
require_sesskey();
echo $output->upgrade_plugin_confirm_deploy_page($deployer, $deploydata);
die();
}
}
// Show plugins info.
echo $output->upgrade_plugin_check_page($pluginman, \core\update\checker::instance(),
echo $output->upgrade_plugin_check_page(core_plugin_manager::instance(), \core\update\checker::instance(),
$version, $showallplugins,
new moodle_url($PAGE->url),
new moodle_url($PAGE->url, array('confirmplugincheck' => 1, 'cache' => 0)));
new moodle_url('/admin/index.php', array('confirmplugincheck'=>1, 'cache'=>0)));
die();
}
// Make sure plugin dependencies are always checked.
$failed = array();
if (!$pluginman->all_plugins_ok($version, $failed, $CFG->branch)) {
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
/** @var core_admin_renderer $output */
$output = $PAGE->get_renderer('core', 'admin');
echo $output->unsatisfied_dependencies_page($version, $failed, new moodle_url($PAGE->url,
array('confirmplugincheck' => 0)));
$reloadurl = new moodle_url('/admin/index.php', array('cache' => 0));
echo $output->unsatisfied_dependencies_page($version, $failed, $reloadurl);
die();
}
unset($failed);
@@ -718,7 +438,6 @@ if (!$cache and moodle_needs_upgrading()) {
if (during_initial_install()) {
set_config('rolesactive', 1); // after this, during_initial_install will return false.
set_config('adminsetuppending', 1);
set_config('registrationpending', 1); // Remind to register site after all other setup is finished.
// we need this redirect to setup proper session
upgrade_finished("index.php?sessionstarted=1&amp;lang=$CFG->lang");
}
@@ -794,15 +513,7 @@ if (isguestuser()) {
redirect(get_login_url());
}
$context = context_system::instance();
if (!has_capability('moodle/site:config', $context)) {
// Do not throw exception display an empty page with administration menu if visible for current user.
$PAGE->set_title($SITE->fullname);
$PAGE->set_heading($SITE->fullname);
echo $OUTPUT->header();
echo $OUTPUT->footer();
exit;
}
require_capability('moodle/site:config', $context);
// check that site is properly customized
$site = get_site();
@@ -821,7 +532,7 @@ $SESSION->admin_critical_warning = ($insecuredataroot==INSECURE_DATAROOT_ERROR);
$adminroot = admin_get_root();
// Check if there are any new admin settings which have still yet to be set
if (any_new_admin_settings($adminroot)) {
if (any_new_admin_settings($adminroot)){
redirect('upgradesettings.php');
}
@@ -834,20 +545,14 @@ if (isset($SESSION->pluginuninstallreturn)) {
}
}
// If site registration needs updating, redirect.
\core\hub\registration::registration_reminder('/admin/index.php');
// Everything should now be set up, and the user is an admin
// Print default admin page with notifications.
$errorsdisplayed = defined('WARN_DISPLAY_ERRORS_ENABLED');
$lastcron = get_config('tool_task', 'lastcronstart');
// We make the assumption that at least one schedule task should run once per day.
$lastcron = $DB->get_field_sql('SELECT MAX(lastruntime) FROM {task_scheduled}');
$cronoverdue = ($lastcron < time() - 3600 * 24);
$lastcroninterval = get_config('tool_task', 'lastcroninterval');
$expectedfrequency = $CFG->expectedcronfrequency ?? MINSECS;
$croninfrequent = !$cronoverdue && ($lastcroninterval > ($expectedfrequency + MINSECS) || $lastcron < time() - $expectedfrequency);
$dbproblems = $DB->diagnose();
$maintenancemode = !empty($CFG->maintenance_enabled);
@@ -856,7 +561,7 @@ $updateschecker = \core\update\checker::instance();
$availableupdates = array();
$availableupdatesfetch = null;
if ($updateschecker->enabled()) {
if (empty($CFG->disableupdatenotifications)) {
// Only compute the update information when it is going to be displayed to the user.
$availableupdates['core'] = $updateschecker->get_update_info('core',
array('minmaturity' => $CFG->updateminmaturity, 'notifybuilds' => $CFG->updatenotifybuilds));
@@ -865,13 +570,14 @@ if ($updateschecker->enabled()) {
$pluginman = core_plugin_manager::instance();
foreach ($pluginman->get_plugins() as $plugintype => $plugintypeinstances) {
foreach ($plugintypeinstances as $pluginname => $plugininfo) {
$pluginavailableupdates = $plugininfo->available_updates();
if (!empty($pluginavailableupdates)) {
foreach ($pluginavailableupdates as $pluginavailableupdate) {
if (!isset($availableupdates[$plugintype.'_'.$pluginname])) {
$availableupdates[$plugintype.'_'.$pluginname] = array();
if (!empty($plugininfo->availableupdates)) {
foreach ($plugininfo->availableupdates as $pluginavailableupdate) {
if ($pluginavailableupdate->version > $plugininfo->versiondisk) {
if (!isset($availableupdates[$plugintype.'_'.$pluginname])) {
$availableupdates[$plugintype.'_'.$pluginname] = array();
}
$availableupdates[$plugintype.'_'.$pluginname][] = $pluginavailableupdate;
}
$availableupdates[$plugintype.'_'.$pluginname][] = $pluginavailableupdate;
}
}
}
@@ -883,36 +589,15 @@ if ($updateschecker->enabled()) {
$buggyiconvnomb = (!function_exists('mb_convert_encoding') and @iconv('UTF-8', 'UTF-8//IGNORE', '100'.chr(130).'€') !== '100€');
//check if the site is registered on Moodle.org
$registered = \core\hub\registration::is_registered();
$registered = $DB->count_records('registration_hubs', array('huburl' => HUB_MOODLEORGHUBURL, 'confirmed' => 1));
// Check if there are any cache warnings.
$cachewarnings = cache_helper::warnings();
// Check if there are events 1 API handlers.
$eventshandlers = $DB->get_records_sql('SELECT DISTINCT component FROM {events_handlers}');
$themedesignermode = !empty($CFG->themedesignermode);
$mobileconfigured = !empty($CFG->enablemobilewebservice);
$invalidforgottenpasswordurl = !empty($CFG->forgottenpasswordurl) && empty(clean_param($CFG->forgottenpasswordurl, PARAM_URL));
// Check if a directory with development libraries exists.
if (empty($CFG->disabledevlibdirscheck) && (is_dir($CFG->dirroot.'/vendor') || is_dir($CFG->dirroot.'/node_modules'))) {
$devlibdir = true;
} else {
$devlibdir = false;
}
// Check if the site is being foced onto ssl.
$overridetossl = !empty($CFG->overridetossl);
// Check if moodle campaign content setting is enabled or not.
$showcampaigncontent = !isset($CFG->showcampaigncontent) || $CFG->showcampaigncontent;
// Encourage admins to enable the user feedback feature if it is not enabled already.
$showfeedbackencouragement = empty($CFG->enableuserfeedback);
admin_externalpage_setup('adminnotifications');
/* @var core_admin_renderer $output */
$output = $PAGE->get_renderer('core', 'admin');
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed, $cronoverdue, $dbproblems,
$maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
$registered, $cachewarnings, $eventshandlers, $themedesignermode, $devlibdir,
$mobileconfigured, $overridetossl, $invalidforgottenpasswordurl, $croninfrequent,
$showcampaigncontent, $showfeedbackencouragement);
$registered, $cachewarnings);
-85
View File
@@ -24,8 +24,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Return a list of page types
* @param string $pagetype current page type
@@ -39,86 +37,3 @@ function admin_page_type_list($pagetype, $parentcontext, $currentcontext) {
);
return $array;
}
/**
* File serving.
*
* @param stdClass $course The course object.
* @param stdClass $cm The cm object.
* @param context $context The context object.
* @param string $filearea The file area.
* @param array $args List of arguments.
* @param bool $forcedownload Whether or not to force the download of the file.
* @param array $options Array of options.
* @return void|false
*/
function core_admin_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
global $CFG;
if (in_array($filearea, ['logo', 'logocompact'])) {
$size = array_shift($args); // The path hides the size.
$itemid = clean_param(array_shift($args), PARAM_INT);
$filename = clean_param(array_shift($args), PARAM_FILE);
$themerev = theme_get_revision();
if ($themerev <= 0) {
// Normalise to 0 as -1 doesn't place well with paths.
$themerev = 0;
}
// Extract the requested width and height.
$maxwidth = 0;
$maxheight = 0;
if (preg_match('/^\d+x\d+$/', $size)) {
list($maxwidth, $maxheight) = explode('x', $size);
$maxwidth = clean_param($maxwidth, PARAM_INT);
$maxheight = clean_param($maxheight, PARAM_INT);
}
$lifetime = 0;
if ($itemid > 0 && $themerev == $itemid) {
// The itemid is $CFG->themerev, when 0 or less no caching. Also no caching when they don't match.
$lifetime = DAYSECS * 60;
}
// Anyone, including guests and non-logged in users, can view the logos.
$options = ['cacheability' => 'public'];
// Check if we've got a cached file to return. When lifetime is 0 then we don't want to cached one.
$candidate = $CFG->localcachedir . "/core_admin/$themerev/$filearea/{$maxwidth}x{$maxheight}/$filename";
if (file_exists($candidate) && $lifetime > 0) {
send_file($candidate, $filename, $lifetime, 0, false, false, '', false, $options);
}
// Find the original file.
$fs = get_file_storage();
$filepath = "/{$context->id}/core_admin/{$filearea}/0/{$filename}";
if (!$file = $fs->get_file_by_hash(sha1($filepath))) {
send_file_not_found();
}
// No need for resizing, but if the file should be cached we save it so we can serve it fast next time.
if (empty($maxwidth) && empty($maxheight)) {
if ($lifetime) {
file_safe_save_content($file->get_content(), $candidate);
}
send_stored_file($file, $lifetime, 0, false, $options);
}
// Proceed with the resizing.
$filedata = $file->resize_image($maxwidth, $maxheight);
if (!$filedata) {
send_file_not_found();
}
// If we don't want to cached the file, serve now and quit.
if (!$lifetime) {
send_content_uncached($filedata, $filename);
}
// Save, serve and quit.
file_safe_save_content($filedata, $candidate);
send_file($candidate, $filename, $lifetime, 0, false, false, '', false, $options);
}
send_file_not_found();
}
+57
View File
@@ -0,0 +1,57 @@
<?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 licenses.
*/
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/licenselib.php');
require_login();
require_capability('moodle/site:config', context_system::instance());
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=managelicenses";
$action = optional_param('action', '', PARAM_ALPHANUMEXT);
$license = optional_param('license', '', PARAM_SAFEDIR);
////////////////////////////////////////////////////////////////////////////////
// process actions
if (!confirm_sesskey()) {
redirect($returnurl);
}
$return = true;
switch ($action) {
case 'disable':
license_manager::disable($license);
break;
case 'enable':
license_manager::enable($license);
break;
default:
break;
}
if ($return) {
redirect ($returnurl);
}
+1 -1
View File
@@ -27,7 +27,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php');
-96
View File
@@ -1,96 +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 file is used to display a categories sub categories, external pages, and settings.
*
* @package admin
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../config.php');
require_once("{$CFG->libdir}/adminlib.php");
$contextid = required_param('id', PARAM_INT);
$confirm = optional_param('confirm', null, PARAM_INT);
$returnurl = optional_param('returnurl', null, PARAM_LOCALURL);
$PAGE->set_url('/admin/lock.php', ['id' => $contextid]);
list($context, $course, $cm) = get_context_info_array($contextid);
$parentcontext = $context->get_parent_context();
if ($parentcontext && !empty($parentcontext->locked)) {
// Can't make changes to a context whose parent is locked.
throw new \coding_exception('Not sure how you got here');
}
if ($course) {
$isfrontpage = ($course->id == SITEID);
} else {
$isfrontpage = false;
$course = $SITE;
}
require_login($course, false, $cm);
require_capability('moodle/site:managecontextlocks', $context);
$PAGE->set_pagelayout('admin');
$PAGE->navigation->clear_cache();
$a = (object) [
'contextname' => $context->get_context_name(),
];
if (null !== $confirm && confirm_sesskey()) {
$context->set_locked(!empty($confirm));
if ($context->locked) {
$lockmessage = get_string('managecontextlocklocked', 'admin', $a);
} else {
$lockmessage = get_string('managecontextlockunlocked', 'admin', $a);
}
if (empty($returnurl)) {
$returnurl = $context->get_url();
} else {
$returnurl = new moodle_url($returnurl);
}
redirect($returnurl, $lockmessage);
}
$heading = get_string('managecontextlock', 'admin');
$PAGE->set_title($heading);
$PAGE->set_heading($heading);
echo $OUTPUT->header();
if ($context->locked) {
$confirmstring = get_string('confirmcontextunlock', 'admin', $a);
$target = 0;
} else {
$confirmstring = get_string('confirmcontextlock', 'admin', $a);
$target = 1;
}
$confirmurl = new \moodle_url($PAGE->url, ['confirm' => $target]);
if (!empty($returnurl)) {
$confirmurl->param('returnurl', $returnurl);
}
echo $OUTPUT->confirm($confirmstring, $confirmurl, $context->get_url());
echo $OUTPUT->footer();
+1 -1
View File
@@ -29,7 +29,7 @@
*/
// Security check.
if (!file_exists(__DIR__.'/mailout-debugger.enable')) {
if (!file_exists(dirname(__FILE__).'/mailout-debugger.enable')) {
mdie("Disabled.");
}
$tmpdir=sys_get_temp_dir(); // default
-78
View File
@@ -1,78 +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/>.
/**
* Enrol config manipulation script.
*
* @package core
* @subpackage media
* @copyright 2016 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('NO_OUTPUT_BUFFERING', true);
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
$action = required_param('action', PARAM_ALPHANUMEXT);
$media = required_param('media', PARAM_PLUGIN);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$PAGE->set_url('/admin/media.php');
$PAGE->set_context(context_system::instance());
require_admin();
require_sesskey();
$plugins = core_plugin_manager::instance()->get_plugins_of_type('media');
$sortorder = array_values(\core\plugininfo\media::get_enabled_plugins());
$return = new moodle_url('/admin/settings.php', array('section' => 'managemediaplayers'));
if (!array_key_exists($media, $plugins)) {
redirect($return);
}
switch ($action) {
case 'disable':
$plugins[$media]->set_enabled(false);
break;
case 'enable':
$plugins[$media]->set_enabled(true);
break;
case 'up':
if (($pos = array_search($media, $sortorder)) > 0) {
$tmp = $sortorder[$pos - 1];
$sortorder[$pos - 1] = $sortorder[$pos];
$sortorder[$pos] = $tmp;
\core\plugininfo\media::set_enabled_plugins($sortorder);
}
break;
case 'down':
if ((($pos = array_search($media, $sortorder)) !== false) && ($pos < count($sortorder) - 1)) {
$tmp = $sortorder[$pos + 1];
$sortorder[$pos + 1] = $sortorder[$pos];
$sortorder[$pos] = $tmp;
\core\plugininfo\media::set_enabled_plugins($sortorder);
}
break;
}
redirect($return);
+30 -110
View File
@@ -21,134 +21,54 @@
* @copyright 2011 Lancaster University Network Services Limited
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->dirroot . '/message/lib.php');
require_once($CFG->libdir.'/adminlib.php');
// This is an admin page.
// This is an admin page
admin_externalpage_setup('managemessageoutputs');
// Fetch processors.
$allprocessors = get_message_processors();
$processors = array_filter($allprocessors, function($processor) {
return $processor->enabled;
});
$disabledprocessors = array_filter($allprocessors, function($processor) {
return !$processor->enabled;
});
// Require site configuration capability
require_capability('moodle/site:config', context_system::instance());
// Fetch message providers.
$providers = get_message_providers();
// Fetch the manage message outputs interface.
$preferences = get_message_output_default_preferences();
// Get the submitted params
$disable = optional_param('disable', 0, PARAM_INT);
$enable = optional_param('enable', 0, PARAM_INT);
if (($form = data_submitted()) && confirm_sesskey()) {
$newpreferences = array();
// Prepare default message outputs settings.
foreach ($providers as $provider) {
$componentproviderbase = $provider->component.'_'.$provider->name;
$disableprovidersetting = $componentproviderbase.'_disable';
$providerdisabled = false;
if (!isset($form->$disableprovidersetting)) {
$providerdisabled = true;
$newpreferences[$disableprovidersetting] = 1;
} else {
$newpreferences[$disableprovidersetting] = 0;
}
$headingtitle = get_string('managemessageoutputs', 'message');
foreach (array('permitted', 'loggedin', 'loggedoff') as $setting) {
$value = null;
$componentprovidersetting = $componentproviderbase.'_'.$setting;
if ($setting == 'permitted') {
// If we deal with permitted select element, we need to create individual
// setting for each possible processor. Note that this block will
// always be processed first after entring parental foreach iteration
// so we can change form values on this stage.
foreach ($processors as $processor) {
$value = '';
if (isset($form->{$componentprovidersetting}[$processor->name])) {
$value = $form->{$componentprovidersetting}[$processor->name];
}
// Ensure that loggedin loggedoff options are set correctly for this permission.
if (($value == 'disallowed') || $providerdisabled) {
// It might be better to unset them, but I can't figure out why that cause error.
$form->{$componentproviderbase.'_loggedin'}[$processor->name] = 0;
$form->{$componentproviderbase.'_loggedoff'}[$processor->name] = 0;
} else if ($value == 'forced') {
$form->{$componentproviderbase.'_loggedin'}[$processor->name] = 1;
$form->{$componentproviderbase.'_loggedoff'}[$processor->name] = 1;
}
// Record the site preference.
$newpreferences[$processor->name.'_provider_'.$componentprovidersetting] = $value;
}
} else {
$newsettings = array();
if (property_exists($form, $componentprovidersetting)) {
// We must be processing loggedin or loggedoff checkboxes.
// Store defained comma-separated processors as setting value.
// Using array_filter eliminates elements set to 0 above.
$newsettings = array_keys(array_filter($form->{$componentprovidersetting}));
}
// Let's join existing setting values for disabled processors.
$property = 'message_provider_'.$componentprovidersetting;
if (property_exists($preferences, $property)) {
$existingsetting = $preferences->$property;
foreach ($disabledprocessors as $disable) {
if (strpos($existingsetting, $disable->name) > -1) {
$newsettings[] = $disable->name;
}
}
}
$value = join(',', $newsettings);
if (empty($value)) {
$value = null;
}
}
if ($setting != 'permitted') {
// We have already recoded site preferences for 'permitted' type.
$newpreferences['message_provider_'.$componentprovidersetting] = $value;
}
}
if (!empty($disable) && confirm_sesskey()) {
if (!$processor = $DB->get_record('message_processors', array('id'=>$disable))) {
print_error('outputdoesnotexist', 'message');
}
// Update database.
$transaction = $DB->start_delegated_transaction();
// Save processors enabled/disabled status.
foreach ($allprocessors as $processor) {
$enabled = isset($form->{$processor->name});
if ($enabled != $processor->enabled) {
add_to_config_log($processor->name, $processor->enabled, $enabled, 'core');
}
\core_message\api::update_processor_status($processor, $enabled);
}
foreach ($newpreferences as $name => $value) {
$old = isset($preferences->$name) ? $preferences->$name : '';
if ($old != $value) {
add_to_config_log($name, $old, $value, 'core');
}
set_config($name, $value, 'message');
}
$transaction->allow_commit();
$DB->set_field('message_processors', 'enabled', '0', array('id'=>$processor->id)); // Disable output
core_plugin_manager::reset_caches();
}
if (!empty($enable) && confirm_sesskey()) {
if (!$processor = $DB->get_record('message_processors', array('id'=>$enable))) {
print_error('outputdoesnotexist', 'message');
}
$DB->set_field('message_processors', 'enabled', '1', array('id'=>$processor->id)); // Enable output
core_plugin_manager::reset_caches();
}
if ($disable || $enable) {
$url = new moodle_url('message.php');
redirect($url);
}
// Page settings
$PAGE->set_context(context_system::instance());
$PAGE->requires->js_init_call('M.core_message.init_defaultoutputs');
// Grab the renderer
$renderer = $PAGE->get_renderer('core', 'message');
// Display the page.
// Display the manage message outputs interface
$processors = get_message_processors();
$messageoutputs = $renderer->manage_messageoutputs($processors);
// Display the page
echo $OUTPUT->header();
echo $renderer->manage_messageoutput_settings($allprocessors, $processors, $providers, $preferences);
echo $OUTPUT->heading($headingtitle);
echo $messageoutputs;
echo $OUTPUT->footer();
+4 -2
View File
@@ -2,7 +2,7 @@
// Allows the admin to control user logins from remote moodles.
require_once(__DIR__ . '/../../config.php');
require_once dirname(dirname(dirname(__FILE__))) . '/config.php';
require_once($CFG->libdir.'/adminlib.php');
include_once($CFG->dirroot.'/mnet/lib.php');
@@ -12,6 +12,8 @@ $page = optional_param('page', 0, PARAM_INT);
$perpage = optional_param('perpage', 30, PARAM_INT);
$action = trim(strtolower(optional_param('action', '', PARAM_ALPHA)));
require_login();
admin_externalpage_setup('ssoaccesscontrol');
if (!extension_loaded('openssl')) {
@@ -148,7 +150,7 @@ foreach ($columns as $column) {
} else {
$columndir = $dir == "ASC" ? "DESC" : "ASC";
$columnicon = $dir == "ASC" ? "down" : "up";
$columnicon = " " . $OUTPUT->pix_icon('t/' . $columnicon, get_string('sort'));
$columnicon = " <img src=\"" . $OUTPUT->pix_url('t/' . $columnicon) . "\" alt=\"\" />";
}
$headings[$column] = "<a href=\"?sort=$column&amp;dir=$columndir&amp;\">".$string[$column]."</a>$columnicon";
}
+6 -1
View File
@@ -27,13 +27,18 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require(__DIR__.'/../../config.php');
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once($CFG->libdir . '/adminlib.php');
$step = optional_param('step', 'verify', PARAM_ALPHA);
$hostid = required_param('hostid', PARAM_INT);
require_login();
$context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, "nopermissions");
$mnet = get_mnet_environment();
$PAGE->set_url('/admin/mnet/delete.php');
+3 -1
View File
@@ -2,14 +2,16 @@
// Allows the admin to configure mnet stuff
require(__DIR__.'/../../config.php');
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once($CFG->libdir.'/adminlib.php');
include_once($CFG->dirroot.'/mnet/lib.php');
require_login();
admin_externalpage_setup('net');
$context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, "nopermissions");
$site = get_site();
$mnet = get_mnet_environment();
+2 -3
View File
@@ -60,8 +60,7 @@ class mnet_simple_host_form extends moodleform {
}
if ($host = $DB->get_record('mnet_host', array('wwwroot' => $wwwroot))) {
global $CFG;
return array('wwwroot' => get_string('hostexists', 'mnet',
new moodle_url('/admin/mnet/peers.php', array('hostid' => $host->id))));
return array('wwwroot' => get_string('hostexists', 'mnet', $CFG->wwwroot . '/admin/mnet/peers.php?hostid=' . $host->id));
}
return array();
}
@@ -156,7 +155,7 @@ class mnet_review_host_form extends moodleform {
if ($mnet_peer && !empty($mnet_peer->deleted)) {
$radioarray = array();
$radioarray[] = $mform->createElement('static', 'deletedinfo', '',
$OUTPUT->container(get_string('deletedhostinfo', 'mnet'), 'alert alert-warning'));
$OUTPUT->container(get_string('deletedhostinfo', 'mnet'), 'deletedhostinfo'));
$radioarray[] = $mform->createElement('radio', 'deleted', '', get_string('yes'), 1);
$radioarray[] = $mform->createElement('radio', 'deleted', '', get_string('no'), 0);
$mform->addGroup($radioarray, 'radioar', get_string('deleted'), array(' ', ' '), false);
+7 -3
View File
@@ -27,11 +27,15 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require(__DIR__.'/../../config.php');
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->dirroot.'/mnet/lib.php');
require_once($CFG->dirroot.'/'.$CFG->admin.'/mnet/peer_forms.php');
require_login();
$context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, 'nopermissions');
/// Initialize variables.
$hostid = optional_param('hostid', 0, PARAM_INT);
@@ -105,7 +109,7 @@ if (!empty($hostid)) {
$mnet_peer->set_id($hostid);
echo $OUTPUT->header();
$currenttab = 'mnetdetails';
require_once($CFG->dirroot . '/' . $CFG->admin . '/mnet/tabs.php');
require_once($CFG->dirroot . '/admin/mnet/tabs.php');
if ($hostid != $CFG->mnet_all_hosts_id) {
$mnet_peer->currentkey = mnet_get_public_key($mnet_peer->wwwroot, $mnet_peer->application);
@@ -140,7 +144,7 @@ if (empty($noreviewform) && $id = optional_param('id', 0, PARAM_INT)) {
// we're editing an existing one, so set up the tabs
$currenttab = 'mnetdetails';
$mnet_peer->set_id($id);
require_once($CFG->dirroot . '/' . $CFG->admin . '/mnet/tabs.php');
require_once($CFG->dirroot . '/admin/mnet/tabs.php');
} else if (empty($noreviewform) && ($wwwroot = optional_param('wwwroot', '', PARAM_URL)) && ($applicationid = optional_param('applicationid', 0, PARAM_INT))) {
$application = $DB->get_field('mnet_application', 'name', array('id'=>$applicationid));
$mnet_peer->bootstrap($wwwroot, null, $application);
+6 -2
View File
@@ -24,15 +24,19 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require(__DIR__.'/../../config.php');
require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->dirroot . '/' . $CFG->admin .'/mnet/profilefields_form.php');
require_once($CFG->dirroot . '/admin/mnet/profilefields_form.php');
$mnet = get_mnet_environment();
require_login();
$hostid = required_param('hostid', PARAM_INT);
$mnet_peer = new mnet_peer();
$mnet_peer->set_id($hostid);
$context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, 'nopermissions');
admin_externalpage_setup('mnetpeers');
$form = new mnet_profile_form(null, array('hostid' => $hostid));
+6 -3
View File
@@ -25,13 +25,16 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require(__DIR__.'/../../config.php');
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->dirroot . '/' . $CFG->admin . '/mnet/services_form.php');
require_once($CFG->dirroot . '/admin/mnet/services_form.php');
$mnet = get_mnet_environment();
require_login();
admin_externalpage_setup('mnetpeers');
$context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, "nopermissions");
$hostid = required_param('hostid', PARAM_INT);
@@ -79,7 +82,7 @@ if ($formdata = $mform->get_data()) {
echo $OUTPUT->header();
$currenttab = 'mnetservices';
require_once($CFG->dirroot . '/' . $CFG->admin . '/mnet/tabs.php');
require_once($CFG->dirroot . '/admin/mnet/tabs.php');
echo $OUTPUT->box_start();
$s = mnet_get_service_info($mnet_peer, false); // basic data only
$mform->set_data($s);
+5 -1
View File
@@ -12,7 +12,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package mnet
*/
require(__DIR__.'/../../config.php');
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once $CFG->dirroot.'/mnet/xmlrpc/client.php';
require_once($CFG->libdir.'/adminlib.php');
include_once($CFG->dirroot.'/mnet/lib.php');
@@ -21,8 +21,12 @@ if ($CFG->mnet_dispatcher_mode === 'off') {
print_error('mnetdisabled', 'mnet');
}
require_login();
admin_externalpage_setup('mnettestclient');
$context = context_system::instance();
require_capability('moodle/site:config', $context);
error_reporting(DEBUG_ALL);
echo $OUTPUT->header();
+5 -1
View File
@@ -1,12 +1,16 @@
<?php
// Allows the admin to configure services for remote hosts
require(__DIR__.'/../../config.php');
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once($CFG->libdir.'/adminlib.php');
include_once($CFG->dirroot.'/mnet/lib.php');
require_login();
admin_externalpage_setup('trustedhosts');
$context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, "nopermissions");
if (!extension_loaded('openssl')) {
echo $OUTPUT->header();
+6 -12
View File
@@ -49,7 +49,6 @@
array($module->id));
core_plugin_manager::reset_caches();
admin_get_root(true, false); // settings not required - only pages
redirect(new moodle_url('/admin/modules.php'));
}
if (!empty($show) and confirm_sesskey()) {
@@ -67,7 +66,6 @@
array($module->id));
core_plugin_manager::reset_caches();
admin_get_root(true, false); // settings not required - only pages
redirect(new moodle_url('/admin/modules.php'));
}
echo $OUTPUT->header();
@@ -89,18 +87,14 @@
$table->set_attribute('class', 'admintable generaltable');
$table->setup();
$pluginmanager = core_plugin_manager::instance();
foreach ($modules as $module) {
$plugininfo = $pluginmanager->get_plugin_info('mod_'.$module->name);
$status = $plugininfo->get_status();
if ($status === core_plugin_manager::PLUGIN_STATUS_MISSING) {
if (!file_exists("$CFG->dirroot/mod/$module->name/lib.php")) {
$strmodulename = '<span class="notifyproblem">'.$module->name.' ('.get_string('missingfromdisk').')</span>';
$missing = true;
} else {
// took out hspace="\10\", because it does not validate. don't know what to replace with.
$icon = "<img src=\"" . $OUTPUT->image_url('icon', $module->name) . "\" class=\"icon\" alt=\"\" />";
$icon = "<img src=\"" . $OUTPUT->pix_url('icon', $module->name) . "\" class=\"icon\" alt=\"\" />";
$strmodulename = $icon.' '.get_string('modulename', $module->name);
$missing = false;
}
@@ -123,8 +117,8 @@
$count = -1;
}
if ($count>0) {
$countlink = $OUTPUT->action_link(new moodle_url('/course/search.php', ['modulelist' => $module->name]),
$count, null, ['title' => $strshowmodulecourse]);
$countlink = "<a href=\"{$CFG->wwwroot}/course/search.php?modulelist=$module->name" .
"&amp;sesskey=".sesskey()."\" title=\"$strshowmodulecourse\">$count</a>";
} else if ($count < 0) {
$countlink = get_string('error');
} else {
@@ -136,11 +130,11 @@
$class = '';
} else if ($module->visible) {
$visible = "<a href=\"modules.php?hide=$module->name&amp;sesskey=".sesskey()."\" title=\"$strhide\">".
$OUTPUT->pix_icon('t/hide', $strhide) . '</a>';
"<img src=\"" . $OUTPUT->pix_url('t/hide') . "\" class=\"iconsmall\" alt=\"$strhide\" /></a>";
$class = '';
} else {
$visible = "<a href=\"modules.php?show=$module->name&amp;sesskey=".sesskey()."\" title=\"$strshow\">".
$OUTPUT->pix_icon('t/show', $strshow) . '</a>';
"<img src=\"" . $OUTPUT->pix_url('t/show') . "\" class=\"iconsmall\" alt=\"$strshow\" /></a>";
$class = 'dimmed_text';
}
if ($module->name == "forum") {
+2 -15
View File
@@ -28,19 +28,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
$error = optional_param('error', '', PARAM_RAW);
if ($error) {
$message = optional_param('error_description', '', PARAM_RAW);
if ($message) {
$SESSION->loginerrormsg = $message;
redirect(new moodle_url(get_login_url()));
} else {
$SESSION->loginerrormsg = $error;
redirect(new moodle_url(get_login_url()));
}
}
require_once(dirname(dirname(__FILE__)).'/config.php');
// The authorization code generated by the authorization server.
$code = required_param('code', PARAM_RAW);
@@ -54,6 +42,5 @@ if (isset($params['sesskey']) and confirm_sesskey($params['sesskey'])) {
$redirecturl->param('oauth2code', $code);
redirect($redirecturl);
} else {
$SESSION->loginerrormsg = get_string('invalidsesskey', 'error');
redirect(new moodle_url(get_login_url()));
print_error('invalidsesskey');
}
+1 -1
View File
@@ -8,7 +8,7 @@
echo $OUTPUT->header();
echo '<div class="phpinfo text-ltr">';
echo '<div class="phpinfo">';
ob_start();
phpinfo(INFO_GENERAL + INFO_CONFIGURATION + INFO_MODULES + INFO_VARIABLES);
+1 -1
View File
@@ -26,7 +26,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php');
+57 -65
View File
@@ -18,46 +18,49 @@
/**
* UI for general plugins management
*
* Supported HTTP parameters:
*
* ?fetchremote=1 - check for available updates
* ?updatesonly=1 - display plugins with available update only
* ?contribonly=1 - display non-standard add-ons only
* ?uninstall=foo_bar - uninstall the given plugin
* ?delete=foo_bar - delete the plugin folder (it must not be installed)
* &confirm=1 - confirm the uninstall or delete action
*
* @package core
* @subpackage admin
* @copyright 2011 David Mudrak <david@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../config.php');
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/filelib.php');
$fetchupdates = optional_param('fetchupdates', false, PARAM_BOOL); // Check for available plugins updates.
$updatesonly = optional_param('updatesonly', false, PARAM_BOOL); // Show updateable plugins only.
$contribonly = optional_param('contribonly', false, PARAM_BOOL); // Show additional plugins only.
$uninstall = optional_param('uninstall', '', PARAM_COMPONENT); // Uninstall the plugin.
$delete = optional_param('delete', '', PARAM_COMPONENT); // Delete the plugin folder after it is uninstalled.
$confirmed = optional_param('confirm', false, PARAM_BOOL); // Confirm the uninstall/delete action.
$return = optional_param('return', 'overview', PARAM_ALPHA); // Where to return after uninstall.
$installupdate = optional_param('installupdate', null, PARAM_COMPONENT); // Install given available update.
$installupdateversion = optional_param('installupdateversion', null, PARAM_INT); // Version of the available update to install.
$installupdatex = optional_param('installupdatex', false, PARAM_BOOL); // Install all available plugin updates.
$confirminstallupdate = optional_param('confirminstallupdate', false, PARAM_BOOL); // Available update(s) install confirmed?
$fetchremote = optional_param('fetchremote', false, PARAM_BOOL);
$updatesonly = optional_param('updatesonly', false, PARAM_BOOL);
$contribonly = optional_param('contribonly', false, PARAM_BOOL);
$uninstall = optional_param('uninstall', '', PARAM_COMPONENT);
$delete = optional_param('delete', '', PARAM_COMPONENT);
$confirmed = optional_param('confirm', false, PARAM_BOOL);
$return = optional_param('return', 'overview', PARAM_ALPHA);
// NOTE: do not use admin_externalpage_setup() here because it loads
// full admin tree which is not possible during uninstallation.
require_admin();
require_login();
$syscontext = context_system::instance();
// URL params we want to maintain on redirects.
$pageparams = array('updatesonly' => $updatesonly, 'contribonly' => $contribonly);
$pageurl = new moodle_url('/admin/plugins.php', $pageparams);
require_capability('moodle/site:config', $syscontext);
$pluginman = core_plugin_manager::instance();
if ($uninstall) {
require_sesskey();
if (!$confirmed) {
admin_externalpage_setup('pluginsoverview', '', $pageparams);
admin_externalpage_setup('pluginsoverview');
} else {
$PAGE->set_url($pageurl);
$PAGE->set_url('/admin/plugins.php');
$PAGE->set_context($syscontext);
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
@@ -91,7 +94,6 @@ if ($uninstall) {
exit();
} else {
require_sesskey();
$SESSION->pluginuninstallreturn = $pluginfo->get_return_url_after_uninstall($return);
$progress = new progress_trace_buffer(new text_progress_trace(), false);
$pluginman->uninstall_plugin($pluginfo->component, $progress);
@@ -120,7 +122,7 @@ if ($uninstall) {
if ($delete and $confirmed) {
require_sesskey();
$PAGE->set_url($pageurl);
$PAGE->set_url('/admin/plugins.php');
$PAGE->set_context($syscontext);
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
@@ -147,6 +149,13 @@ if ($delete and $confirmed) {
'core_plugin_manager::get_plugin_info() returned not-null versiondb for the plugin to be deleted');
}
// Make sure the folder is removable.
if (!$pluginman->is_plugin_folder_removable($pluginfo->component)) {
throw new moodle_exception('err_removing_unremovable_folder', 'core_plugin', '',
array('plugin' => $pluginfo->component, 'rootdir' => $pluginfo->rootdir),
'plugin root folder is not removable as expected');
}
// Make sure the folder is within Moodle installation tree.
if (strpos($pluginfo->rootdir, $CFG->dirroot) !== 0) {
throw new moodle_exception('err_unexpected_plugin_rootdir', 'core_plugin', '',
@@ -155,61 +164,44 @@ if ($delete and $confirmed) {
}
// So long, and thanks for all the bugs.
$pluginman->remove_plugin_folder($pluginfo);
fulldelete($pluginfo->rootdir);
// Reset op code caches.
if (function_exists('opcache_reset')) {
opcache_reset();
}
// We need to execute upgrade to make sure everything including caches is up to date.
redirect(new moodle_url('/admin/index.php'));
}
// Install all avilable updates.
if ($installupdatex) {
require_once($CFG->libdir.'/upgradelib.php');
require_sesskey();
$PAGE->set_url($pageurl);
$PAGE->set_context($syscontext);
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
$installable = $pluginman->filter_installable($pluginman->available_updates());
upgrade_install_plugins($installable, $confirminstallupdate,
get_string('updateavailableinstallallhead', 'core_admin'),
new moodle_url($PAGE->url, array('installupdatex' => 1, 'confirminstallupdate' => 1))
);
}
// Install single available update.
if ($installupdate and $installupdateversion) {
require_once($CFG->libdir.'/upgradelib.php');
require_sesskey();
$PAGE->set_url($pageurl);
$PAGE->set_context($syscontext);
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
if ($pluginman->is_remote_plugin_installable($installupdate, $installupdateversion)) {
$installable = array($pluginman->get_remote_plugin_info($installupdate, $installupdateversion, true));
upgrade_install_plugins($installable, $confirminstallupdate,
get_string('updateavailableinstallallhead', 'core_admin'),
new moodle_url($PAGE->url, array('installupdate' => $installupdate,
'installupdateversion' => $installupdateversion, 'confirminstallupdate' => 1)
)
);
}
}
admin_externalpage_setup('pluginsoverview', '', $pageparams);
admin_externalpage_setup('pluginsoverview');
/** @var core_admin_renderer $output */
$output = $PAGE->get_renderer('core', 'admin');
$checker = \core\update\checker::instance();
if ($fetchupdates) {
// Filtering options.
$options = array(
'updatesonly' => $updatesonly,
'contribonly' => $contribonly,
);
if ($fetchremote) {
require_sesskey();
$checker->fetch();
redirect($PAGE->url);
redirect(new moodle_url($PAGE->url, $options));
}
echo $output->plugin_management_page($pluginman, $checker, $pageparams);
$deployer = \core\update\deployer::instance();
if ($deployer->enabled()) {
$myurl = new moodle_url($PAGE->url, array('updatesonly' => $updatesonly, 'contribonly' => $contribonly));
$deployer->initialize($myurl, new moodle_url('/admin'));
$deploydata = $deployer->submitted_data();
if (!empty($deploydata)) {
echo $output->upgrade_plugin_confirm_deploy_page($deployer, $deploydata);
die();
}
}
echo $output->plugin_management_page($pluginman, $checker, $options);

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