Compare commits
676 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 97dd32edd6 | |||
| a0b2c28080 | |||
| bddf27de35 | |||
| 406a0efd37 | |||
| eb7715d16f | |||
| 4db8407d3e | |||
| 61da84e414 | |||
| a034f66e0b | |||
| 1452f1e1d3 | |||
| d59b91c6a8 | |||
| 85380c6b61 | |||
| 9aff357438 | |||
| e567d6eda3 | |||
| a51a17c846 | |||
| 5dbd593d3a | |||
| 484d8abc22 | |||
| 6e036a74b0 | |||
| 38dfee06dd | |||
| 475362630b | |||
| b643f44415 | |||
| 314d105c16 | |||
| 61ba63d516 | |||
| 16e85de11f | |||
| b46e8a7b32 | |||
| 0766509ab0 | |||
| 56a067e7c1 | |||
| c7f7b18ade | |||
| 3328dc32a7 | |||
| 783e695e00 | |||
| de60fc23ae | |||
| 04576de946 | |||
| 0c5c778ae7 | |||
| 4d2eab6932 | |||
| 7f81a8388a | |||
| 76dad4b0a2 | |||
| 857919df34 | |||
| 0b1455e93b | |||
| fba7a51461 | |||
| 7fa00f860e | |||
| 3ce4502093 | |||
| 5739b1b6b9 | |||
| 7097828ac7 | |||
| 438995ddc1 | |||
| 53c59fae82 | |||
| eb0a4127d4 | |||
| 8eaea8e878 | |||
| cb23ec3e1c | |||
| f4f44fb59d | |||
| 850a632505 | |||
| cc52eadad9 | |||
| 0b1c48f422 | |||
| d64639a987 | |||
| 50aff07c9f | |||
| 87568b0cfa | |||
| dea510bfe0 | |||
| 4fb283dea5 | |||
| b2a2dfe8ae | |||
| 62bdb2b8ec | |||
| bce722a96d | |||
| 7266f8301e | |||
| e102b4c4d9 | |||
| 4abf4d9ada | |||
| 477cad6875 | |||
| 7ce4f46db6 | |||
| 471da1eca2 | |||
| efc68f119d | |||
| b18af92a44 | |||
| 0e88a593fd | |||
| 9125eef5b4 | |||
| d2c16cde78 | |||
| 787aa4333a | |||
| a8ee2c885d | |||
| 14a0b42eec | |||
| a6a982d798 | |||
| a09f722564 | |||
| df64a2ca06 | |||
| c490457a71 | |||
| 06b13fb79f | |||
| 260c6b548c | |||
| e50cd7c14f | |||
| 66427af8b7 | |||
| 54472938c1 | |||
| 873fcd7abf | |||
| 5ea1c8027c | |||
| 6b36cd591e | |||
| c896607100 | |||
| f0944e4f7a | |||
| c82a5b3692 | |||
| a6d32ec56e | |||
| 40565791ff | |||
| 650071c3c3 | |||
| 52db4dbd91 | |||
| 1823daac03 | |||
| 7a6ba516c8 | |||
| 6ca319debc | |||
| 351fed869c | |||
| dd0af0fad5 | |||
| 6d27533ac0 | |||
| d04d763594 | |||
| 6f17dd18c8 | |||
| 560d38c251 | |||
| 1ab7bb3c6f | |||
| 2410893797 | |||
| 6c735bd4bb | |||
| 51089c2079 | |||
| 70cfad6550 | |||
| 93d9e77b73 | |||
| 9026f8aa42 | |||
| 36fd5a2e74 | |||
| 86ebfb0bb5 | |||
| a6a46d4fc3 | |||
| f64c024648 | |||
| 8d42058734 | |||
| 06ad488970 | |||
| cca7714daf | |||
| 7080a26ecc | |||
| 56b8a5c80c | |||
| 0a43324230 | |||
| b14945cc2f | |||
| c25eb5d673 | |||
| 4741ff9810 | |||
| 5dc2d2eb4e | |||
| 3bb2f388bb | |||
| 611c47c861 | |||
| 29e70c0ffa | |||
| a8615c22c8 | |||
| 5d14c00774 | |||
| 60a26ddf42 | |||
| db57772b2f | |||
| e7a4135526 | |||
| 5e86ebcd3b | |||
| 0682e95c72 | |||
| a4112f7906 | |||
| 2cc9af244b | |||
| 6ad63c6a2b | |||
| 4ff024c5ab | |||
| 0c92dc487f | |||
| 3277a55bd5 | |||
| 6f55d77ab1 | |||
| 22fcbd1f22 | |||
| b1f4f5bae8 | |||
| 15ba94e132 | |||
| 76996862ed | |||
| a900614082 | |||
| af56a3c5b8 | |||
| 76c73a9895 | |||
| c063da3610 | |||
| a027928b32 | |||
| 8fefce40e2 | |||
| 23cd87285b | |||
| 58a10b8e47 | |||
| 288f92e8bd | |||
| 87fa90f7a5 | |||
| 9a5b9c76fc | |||
| 70a52304db | |||
| e271dc1e96 | |||
| c8b4b14574 | |||
| 925c6bba13 | |||
| 60f89a0364 | |||
| 4b3f09c081 | |||
| f47289bc99 | |||
| 8d6b7362e2 | |||
| 78ede65849 | |||
| a52191b36b | |||
| 166c123bc3 | |||
| 01707afd17 | |||
| b3995066ad | |||
| 587d575de1 | |||
| d5df4d045f | |||
| 5ed3f867eb | |||
| 80e7dc9740 | |||
| d25ef0fbde | |||
| 3468942807 | |||
| 65b930fcbd | |||
| 0e1df382a5 | |||
| db80cf54a6 | |||
| be82fa5053 | |||
| 7fa20a8f2e | |||
| 87935201fe | |||
| bf60b24c82 | |||
| bed63ca74f | |||
| bf209aea14 | |||
| 27802334e2 | |||
| 4d51f843be | |||
| a40195b455 | |||
| f94c215231 | |||
| 3bfe6aa877 | |||
| 5d09708b25 | |||
| 10bf1500da | |||
| 091fc5259b | |||
| 3286622534 | |||
| fd6d42de20 | |||
| 8275f30231 | |||
| 6d425afa4f | |||
| e4e7acde8b | |||
| a80a00aa08 | |||
| 18b2d9d2f9 | |||
| c577e1af6a | |||
| b704533f0a | |||
| 117ee3a064 | |||
| c0abaa9fdf | |||
| ca86656416 | |||
| 22fa1056d7 | |||
| 628462b78d | |||
| 6944c07406 | |||
| 74e7fab22e | |||
| 6b6d2633b0 | |||
| b0f5eb7d36 | |||
| 162c33d75e | |||
| 641eab45e0 | |||
| 18ff1708e4 | |||
| 39396934da | |||
| a6a883df2d | |||
| 3e5db201a5 | |||
| 5a8f2ba046 | |||
| 3c63c2c900 | |||
| 96c7474eb0 | |||
| 20e102773f | |||
| 36719a497f | |||
| 1d1d4952b0 | |||
| faef5d14c7 | |||
| 61358a918d | |||
| 1a6dac81ed | |||
| df443f4d83 | |||
| 5677aedfd3 | |||
| 20f2e2ec6a | |||
| 6309e63d41 | |||
| fb0a1132c9 | |||
| 3b5f57029b | |||
| 859d6e470e | |||
| 8e114d80fb | |||
| f41a364e27 | |||
| 33cd0e15f1 | |||
| a6c941f063 | |||
| d0090576e1 | |||
| 2feef8ec73 | |||
| ca7c500826 | |||
| ec4dc1d0c2 | |||
| c10119a059 | |||
| 54405a604f | |||
| 00a3d0bdcf | |||
| 5b647d65f2 | |||
| 4d9adf0f60 | |||
| 59dd3269fb | |||
| 70ddb4e2c6 | |||
| d55eb769e4 | |||
| 08610c078f | |||
| 1f3f47fe97 | |||
| 15ccd59dc1 | |||
| f8f27a5013 | |||
| 42d5dcb5c3 | |||
| da3aaf3a63 | |||
| 3ab644e94e | |||
| 1d188cb1d3 | |||
| d5dd5bd085 | |||
| cb61fdd961 | |||
| 4c2746d752 | |||
| 9e065db83d | |||
| aa720a52ed | |||
| 963681fdc0 | |||
| de7454d413 | |||
| c327cc5c77 | |||
| bc77304aa5 | |||
| 7b30d1e84a | |||
| 4ffe9d1bd3 | |||
| be932909b5 | |||
| 665db4c894 | |||
| 960c5cce5c | |||
| e2baf7ed8a | |||
| 0ef9c59d09 | |||
| c3d1a15532 | |||
| e65317c3f3 | |||
| 32f27a6c69 | |||
| d3ea8cbc07 | |||
| 73f2ca5411 | |||
| 7b30789ce7 | |||
| 0de2b00a8a | |||
| f71446f628 | |||
| 26933d15b0 | |||
| f769b21680 | |||
| 0c6c844cb8 | |||
| 2940d926a5 | |||
| 4e65da4a2f | |||
| 229072cc77 | |||
| 79b58bee2b | |||
| 4b13200c2f | |||
| f70eede993 | |||
| 1414b0a7d4 | |||
| f80cf7dcf1 | |||
| c8393f44df | |||
| 63453ea129 | |||
| 974ccb5121 | |||
| 9604b3e9d8 | |||
| 3516f2b3ef | |||
| 2622aa2f9d | |||
| 31bbc4db30 | |||
| a52a2d3b26 | |||
| d4bb5da618 | |||
| 591eb7449f | |||
| a46efc23a3 | |||
| 4784153309 | |||
| d780b39188 | |||
| 9cb7b278af | |||
| 114ebc3742 | |||
| 6a01418aa1 | |||
| ce87f75cf6 | |||
| a5289915ca | |||
| 2381a9327f | |||
| 934a6d94ef | |||
| a24477c30a | |||
| cdfcaa4876 | |||
| 994ad03eb4 | |||
| e8047b8876 | |||
| ce9eec227b | |||
| 1e9de38a74 | |||
| 1db782af87 | |||
| 6e120bba12 | |||
| cad2583872 | |||
| 60d47c2170 | |||
| 572eca5748 | |||
| 03f2be3e3d | |||
| 6b6487eeed | |||
| 63265e4709 | |||
| 140b58502c | |||
| dfa680442c | |||
| 81df060697 | |||
| ac0f173e2e | |||
| 70d41bafa1 | |||
| 418a05d706 | |||
| 0761304d2f | |||
| 6b1ca71974 | |||
| 7f7b3c1b5b | |||
| 1abbe2a268 | |||
| 2086e272e8 | |||
| f2cd45004b | |||
| efee20c43b | |||
| 6ab7e0d283 | |||
| da3ca5041f | |||
| 841db8ec77 | |||
| 5d35d7b884 | |||
| ac70fb827a | |||
| 21b17fe49c | |||
| c4c0518d90 | |||
| bad5905952 | |||
| 7817f82c15 | |||
| cabf0dbd40 | |||
| ec6f81207a | |||
| 4cae8e7a30 | |||
| cd326efb57 | |||
| ab430ba5fd | |||
| 4c395d5b09 | |||
| 39f2c0f711 | |||
| 3e1089a7f1 | |||
| 02dae40716 | |||
| 408beb96d6 | |||
| c4e2c3ba9b | |||
| 48db5765ac | |||
| 4d59af4afa | |||
| f9758178c6 | |||
| 695ecfc67d | |||
| e02155048a | |||
| 0177319237 | |||
| e5f8c4d2e3 | |||
| edbb4f6e53 | |||
| 07b51eebf3 | |||
| 5240013d21 | |||
| ee687f8919 | |||
| 4c2336663a | |||
| a0984c46a1 | |||
| 4077d3e696 | |||
| d9e423dc82 | |||
| c58421208c | |||
| f361d3e20f | |||
| b238a8658f | |||
| 4513906883 | |||
| 1052567d7e | |||
| 1f43996636 | |||
| 0d18a2c74d | |||
| 3302964844 | |||
| 70d71d3af7 | |||
| 0b841c0c72 | |||
| bc66f3d7b2 | |||
| f3008d2a08 | |||
| 7de2aa1a95 | |||
| 69b2e68d27 | |||
| b7327c6c19 | |||
| f06196976a | |||
| 44f9a36089 | |||
| d92624e11f | |||
| 2264a0454c | |||
| 0944647413 | |||
| 8917f657a1 | |||
| b8b43072c2 | |||
| a85c16aea5 | |||
| aade13141c | |||
| 41d53f9bd5 | |||
| 0d3baf5f8e | |||
| 793d034c4a | |||
| 92236e4345 | |||
| c14c042aca | |||
| 45b9bcd9a0 | |||
| f45a62e469 | |||
| 650d4000cb | |||
| a411fd9ad7 | |||
| 9c35910821 | |||
| 47e5ed8e30 | |||
| b2e6bee53e | |||
| e217f4914a | |||
| 1ba350d146 | |||
| ec921c9d7b | |||
| ec3be4584c | |||
| e8f73b9edd | |||
| e9716eda2f | |||
| df8d12b685 | |||
| 1c529d9897 | |||
| 4ac2ded44b | |||
| f11ab3b3ed | |||
| 471b5b73a3 | |||
| ebc7b73150 | |||
| a06ed7e888 | |||
| 92a25cff43 | |||
| e5549f4f16 | |||
| 0d4fda7843 | |||
| f083859e96 | |||
| 29d83deae9 | |||
| 2217e2fea9 | |||
| 68927e83e5 | |||
| 819020ac57 | |||
| 1e5a066247 | |||
| 24a7fc2f07 | |||
| 03f0b4fc14 | |||
| 8c1261bd97 | |||
| 17af025b52 | |||
| ac56855bbc | |||
| 6f6ef56253 | |||
| 79d202c36d | |||
| 962aca6ad6 | |||
| 7473e54a3d | |||
| 105370c407 | |||
| 869ffde772 | |||
| 73d2934ba5 | |||
| 74a51dd48a | |||
| 9005a3bb96 | |||
| 6fccd1fe35 | |||
| ea78dbdf50 | |||
| db3cdb6d25 | |||
| ccc297f01a | |||
| 8dd7e73294 | |||
| f2087a7fcb | |||
| b1fe9348db | |||
| c3183cb6fe | |||
| d47064c4b2 | |||
| 66a28fbaa4 | |||
| d5d7d57d6d | |||
| db3bcaba14 | |||
| 145467fadf | |||
| 07021369d7 | |||
| 836172f366 | |||
| 2c3d0c3b6f | |||
| 1388dece19 | |||
| 41ec284720 | |||
| 62e799ac84 | |||
| 2945fe403b | |||
| 6af9a4e21c | |||
| 86c5e56baf | |||
| bde99c5a4b | |||
| abde041907 | |||
| bba453b9ed | |||
| 8abf3701a6 | |||
| d607b840b8 | |||
| c65d2ccb13 | |||
| 9149eaae18 | |||
| b35e24e254 | |||
| 8a0c8192c8 | |||
| f5f86a68ac | |||
| 57b1d3ea85 | |||
| 9611df0f92 | |||
| 74c19577c9 | |||
| c7231d5235 | |||
| 3cf111c8d3 | |||
| e0518a0940 | |||
| b000642c03 | |||
| aae5800486 | |||
| 9ef2475cdd | |||
| 8513fdd0ba | |||
| 19da0bad13 | |||
| ff64873ece | |||
| 7bd6de4822 | |||
| eb127e0b21 | |||
| 9797983c6f | |||
| 6767a5d631 | |||
| 1507697d9f | |||
| daf7e2a478 | |||
| 771e49de0c | |||
| c19896ff95 | |||
| 68494c8ef2 | |||
| 0a44e7d8cc | |||
| 345f365555 | |||
| 8079f3343f | |||
| 005f7c8b24 | |||
| a6f084c9c5 | |||
| 0e7a5b346f | |||
| 8640c059d8 | |||
| a3f65f8b5b | |||
| 88cece4bd7 | |||
| ddfebd633e | |||
| ac4baac8b9 | |||
| a0ef20cfe4 | |||
| e819a58b6e | |||
| 2adbbcac0a | |||
| 4e5e185f80 | |||
| 68cbd0599d | |||
| 2134746dea | |||
| 4d56fe7d60 | |||
| 1c4bc77d44 | |||
| bc91b91ab1 | |||
| 9887a4cbae | |||
| 7d8fb1962e | |||
| 07fbf4515c | |||
| e81e12cd79 | |||
| f318ef32bc | |||
| 696f3dcc83 | |||
| 804a5f59ce | |||
| 3f45d8fece | |||
| dfe989c826 | |||
| ed6277f9f7 | |||
| 48db0e02cd | |||
| 6ace0f59ae | |||
| fbf528eb95 | |||
| 220ea7cd09 | |||
| 7f1c642112 | |||
| 6530c22a11 | |||
| ab37a1c815 | |||
| 75b13bba36 | |||
| 2cebc825e9 | |||
| ffe7dd3769 | |||
| f41205a84c | |||
| 3046ae85cc | |||
| 536892fd4c | |||
| 2cae0d3b15 | |||
| bdb1cab348 | |||
| d08bcc4ded | |||
| 2f1473ac6d | |||
| 899f21fc26 | |||
| c60a3ef656 | |||
| 8262d6133a | |||
| e662941230 | |||
| 89feea07d3 | |||
| 9c2784ca30 | |||
| e18b4b0918 | |||
| 14d8971cd6 | |||
| 7c8149d6af | |||
| 096a908dbe | |||
| 68dfa89fea | |||
| e64751fb8a | |||
| 490c5cabb4 | |||
| 4269cac414 | |||
| cd319f3f2f | |||
| da14ce45dd | |||
| 818f90abd3 | |||
| 8ab3584274 | |||
| 13ce9a38a2 | |||
| d5699018b0 | |||
| fbb8579c1a | |||
| f248c81e5a | |||
| 7d05696b12 | |||
| 716c7536cb | |||
| 4cdf94a602 | |||
| c9f2b241e0 | |||
| 8dbe8449e0 | |||
| 4841169211 | |||
| 3fe4b72c34 | |||
| 3c1e7a0759 | |||
| 98ad5c6191 | |||
| 0872bf3175 | |||
| 6e8ca8a6ce | |||
| e2de9c6b6d | |||
| 59b25acd22 | |||
| af145cdac1 | |||
| bf68d558af | |||
| f3d159dea1 | |||
| 3af4f54efb | |||
| 6698b06b11 | |||
| 545d2c9290 | |||
| 7cac3f6fe9 | |||
| db198f615a | |||
| bbf7cf2c44 | |||
| 0f62dd32c7 | |||
| 67e82ebe0b | |||
| ac16eaa936 | |||
| bfe6b3cdd1 | |||
| f1bf39c2f8 | |||
| 6064114c32 | |||
| e0d74e610a | |||
| 8948d04695 | |||
| 9993c6bcc0 | |||
| 1da82165ef | |||
| cf139e224e | |||
| f8bce590ba | |||
| 715eb9438c | |||
| 9c461eae4e | |||
| fe6a3c0531 | |||
| 793c80165d | |||
| a4f457e111 | |||
| 4110561f3e | |||
| b1549e4127 | |||
| 724513e5d8 | |||
| c14fbe69f5 | |||
| 8b4e2418f6 | |||
| 8568798f76 | |||
| 66533b249e | |||
| e5baddebcd | |||
| 0efd3318b2 | |||
| 16acfc55f4 | |||
| 31328e3ede | |||
| c83c1ee838 | |||
| 95f83b70b0 | |||
| 53253aea3a | |||
| c244cd14b7 | |||
| a1b7cd7090 | |||
| e4ffce07cf | |||
| 6b4ce43d1d | |||
| 107ab59c29 | |||
| 4cd0bc7ece | |||
| 42952482c9 | |||
| 3804a59fb6 | |||
| 174faea612 | |||
| dec56ff204 | |||
| c6d3f0d107 | |||
| 8f36db0be5 | |||
| f554e04a27 | |||
| 20c532caf8 | |||
| a1b0938c16 | |||
| 3e1da76d54 | |||
| e3dcc260fb | |||
| ae50bef5e6 | |||
| 1b1e4d2670 | |||
| c31a650aad | |||
| 76943b900c | |||
| c05a3e254c | |||
| 63385ff2b5 | |||
| 42d7bc64f5 | |||
| f0aa5b7e3b | |||
| 40e33b6e75 | |||
| e06768b331 | |||
| ab58f3ee49 | |||
| 6a30312beb | |||
| 8c4dbdfd56 | |||
| e9b0443000 | |||
| fab5233096 | |||
| 2748bf5900 | |||
| 2adf914723 | |||
| 96a2e4086f | |||
| a2d94f3d20 | |||
| 33784bd64b | |||
| 4e5efb5c0c | |||
| 5cb434f62b | |||
| 6117291e6b | |||
| 4e342f5397 | |||
| 6b85e6affd | |||
| e71116f768 | |||
| a0172a28fc | |||
| 60020ccaa9 | |||
| 3987e19c3f | |||
| 2068b31847 | |||
| 9a5f3f7672 | |||
| 75aa0f73db | |||
| 2efce29560 | |||
| a4c6ffd85f | |||
| 184169cd76 | |||
| 55d5b4168e | |||
| 6ccff3ba5d | |||
| 44f23c7ec1 | |||
| 492b025f5f | |||
| 7f98e36008 | |||
| f53c016704 |
@@ -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/
|
||||
@@ -1,308 +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-parser',
|
||||
// Check AMD with some slightly stricter rules.
|
||||
rules: {
|
||||
'no-unused-vars': 'error',
|
||||
'no-implicit-globals': 'error',
|
||||
// Disable all of the rules that have babel versions.
|
||||
'new-cap': 'off',
|
||||
// Not using this rule for the time being because it isn't
|
||||
// compatible with jQuery and ES6.
|
||||
'no-invalid-this': 'off',
|
||||
'object-curly-spacing': 'off',
|
||||
'quotes': 'off',
|
||||
'semi': 'off',
|
||||
'no-unused-expressions': 'off',
|
||||
// Enable all of the babel version of these rules.
|
||||
'babel/new-cap': ['warn', { 'properties': false }],
|
||||
// Not using this rule for the time being because it isn't
|
||||
// compatible with jQuery and ES6.
|
||||
'babel/no-invalid-this': 'off',
|
||||
'babel/object-curly-spacing': 'warn',
|
||||
// This is off in the original style int.
|
||||
'babel/quotes': 'off',
|
||||
'babel/semi': 'error',
|
||||
'babel/no-unused-expressions': 'error',
|
||||
// === Promises ===
|
||||
// We have Promise now that we're using ES6.
|
||||
'promise/no-native': 'off',
|
||||
'promise/avoid-new': 'off',
|
||||
|
||||
// === JSDocs ===
|
||||
"jsdoc/check-access": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/check-alignment": 1, // Recommended.
|
||||
"jsdoc/check-param-names": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/check-property-names": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/empty-tags": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/implements-on-classes": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/multiline-blocks": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/require-jsdoc": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/require-param": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/require-param-name": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/require-param-type": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/require-property": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/require-property-name": [
|
||||
'error',
|
||||
],
|
||||
"jsdoc/require-property-type": [
|
||||
'error',
|
||||
],
|
||||
},
|
||||
parserOptions: {
|
||||
'ecmaVersion': 9,
|
||||
'sourceType': 'module',
|
||||
'requireConfigFile': false,
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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"]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
**/yui/build/** -diff
|
||||
**/amd/build/** -diff
|
||||
lib/dml/oci_native_moodle_package.sql text eol=lf
|
||||
@@ -1,2 +0,0 @@
|
||||
# Primary donations pages.
|
||||
custom: ["https://moodle.com/donations/", moodle.org]
|
||||
@@ -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');
|
||||
@@ -1,117 +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-22.04
|
||||
|
||||
steps:
|
||||
- name: Checking out code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Configuring node & npm
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
- name: Installing node stuff
|
||||
run: npm install
|
||||
|
||||
- name: Running grunt
|
||||
run: npx grunt
|
||||
|
||||
- name: Looking for uncommitted changes
|
||||
# Add all files to the git index and then run diff --cached to see all changes.
|
||||
# This ensures that we get the status of all files, including new files.
|
||||
# We ignore npm-shrinkwrap.json to make the tasks immune to npm changes.
|
||||
run: |
|
||||
git add .
|
||||
git reset -- npm-shrinkwrap.json
|
||||
git diff --cached --exit-code
|
||||
|
||||
PHPUnit:
|
||||
runs-on: ${{ matrix.os }}
|
||||
services:
|
||||
exttests:
|
||||
image: moodlehq/moodle-exttests
|
||||
ports:
|
||||
- 8080:80
|
||||
redis:
|
||||
image: redis
|
||||
ports:
|
||||
- 6379:6379
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
php: 7.3
|
||||
extensions:
|
||||
db: mysqli
|
||||
- os: ubuntu-22.04
|
||||
php: 8.0
|
||||
db: pgsql
|
||||
extensions: xmlrpc-beta
|
||||
|
||||
steps:
|
||||
- name: Setting up DB mysql
|
||||
if: ${{ matrix.db == 'mysqli' }}
|
||||
uses: moodlehq/mysql-action@v1
|
||||
with:
|
||||
collation server: utf8mb4_bin
|
||||
mysql version: 5.7
|
||||
mysql database: test
|
||||
mysql user: test
|
||||
mysql password: test
|
||||
use tmpfs: true
|
||||
tmpfs size: '1024M'
|
||||
extra conf: --skip-log-bin
|
||||
|
||||
- name: Setting up DB pgsql
|
||||
if: ${{ matrix.db == 'pgsql' }}
|
||||
uses: m4nu56/postgresql-action@v1
|
||||
with:
|
||||
postgresql version: 9.6
|
||||
postgresql db: test
|
||||
postgresql user: test
|
||||
postgresql password: test
|
||||
|
||||
- name: Configuring git vars
|
||||
uses: rlespinasse/github-slug-action@v4
|
||||
|
||||
- name: Setting up PHP ${{ matrix.php }}
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: ${{ matrix.extensions }}
|
||||
ini-values: max_input_vars=5000
|
||||
coverage: none
|
||||
|
||||
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setting up PHPUnit
|
||||
env:
|
||||
dbtype: ${{ matrix.db }}
|
||||
run: |
|
||||
echo "pathtophp=$(which php)" >> $GITHUB_ENV # Inject installed pathtophp to env. The template config needs it.
|
||||
cp .github/workflows/config-template.php config.php
|
||||
mkdir ../moodledata
|
||||
sudo locale-gen en_AU.UTF-8
|
||||
php admin/tool/phpunit/cli/init.php --no-composer-self-update
|
||||
|
||||
- name: Running PHPUnit tests
|
||||
env:
|
||||
dbtype: ${{ matrix.db }}
|
||||
phpunit_options: ${{ secrets.phpunit_options }}
|
||||
run: vendor/bin/phpunit $phpunit_options
|
||||
+2
-19
@@ -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,10 +36,3 @@ composer.phar
|
||||
/lib/yuilib/*/*/*-coverage.js
|
||||
atlassian-ide-plugin.xml
|
||||
/node_modules/
|
||||
/.vscode/
|
||||
moodle-plugin-ci.phar
|
||||
.eslintignore
|
||||
.stylelintignore
|
||||
/jsdoc
|
||||
phpcs.xml
|
||||
jsconfig.json
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -1,244 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Helper functions for working with Moodle component names, directories, and sources.
|
||||
*
|
||||
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
/* eslint-env node */
|
||||
|
||||
/** @var {Object} A list of subsystems in Moodle */
|
||||
const componentData = {};
|
||||
|
||||
/**
|
||||
* Load details of all moodle modules.
|
||||
*
|
||||
* @returns {object}
|
||||
*/
|
||||
const fetchComponentData = () => {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const glob = require('glob');
|
||||
const gruntFilePath = process.cwd();
|
||||
|
||||
if (!Object.entries(componentData).length) {
|
||||
componentData.subsystems = {};
|
||||
componentData.pathList = [];
|
||||
|
||||
// Fetch the component definiitions from the distributed JSON file.
|
||||
const components = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/components.json`));
|
||||
|
||||
// Build the list of moodle subsystems.
|
||||
componentData.subsystems.lib = 'core';
|
||||
componentData.pathList.push(process.cwd() + path.sep + 'lib');
|
||||
for (const [component, thisPath] of Object.entries(components.subsystems)) {
|
||||
if (thisPath) {
|
||||
// Prefix "core_" to the front of the subsystems.
|
||||
componentData.subsystems[thisPath] = `core_${component}`;
|
||||
componentData.pathList.push(process.cwd() + path.sep + thisPath);
|
||||
}
|
||||
}
|
||||
|
||||
// The list of components incldues the list of subsystems.
|
||||
componentData.components = componentData.subsystems;
|
||||
|
||||
// Go through each of the plugintypes.
|
||||
Object.entries(components.plugintypes).forEach(([pluginType, pluginTypePath]) => {
|
||||
// We don't allow any code in this place..?
|
||||
glob.sync(`${pluginTypePath}/*/version.php`).forEach(versionPath => {
|
||||
const componentPath = fs.realpathSync(path.dirname(versionPath));
|
||||
const componentName = path.basename(componentPath);
|
||||
const frankenstyleName = `${pluginType}_${componentName}`;
|
||||
componentData.components[`${pluginTypePath}/${componentName}`] = frankenstyleName;
|
||||
componentData.pathList.push(componentPath);
|
||||
|
||||
// Look for any subplugins.
|
||||
const subPluginConfigurationFile = `${componentPath}/db/subplugins.json`;
|
||||
if (fs.existsSync(subPluginConfigurationFile)) {
|
||||
const subpluginList = JSON.parse(fs.readFileSync(fs.realpathSync(subPluginConfigurationFile)));
|
||||
|
||||
Object.entries(subpluginList.plugintypes).forEach(([subpluginType, subpluginTypePath]) => {
|
||||
glob.sync(`${subpluginTypePath}/*/version.php`).forEach(versionPath => {
|
||||
const componentPath = fs.realpathSync(path.dirname(versionPath));
|
||||
const componentName = path.basename(componentPath);
|
||||
const frankenstyleName = `${subpluginType}_${componentName}`;
|
||||
|
||||
componentData.components[`${subpluginTypePath}/${componentName}`] = frankenstyleName;
|
||||
componentData.pathList.push(componentPath);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return componentData;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of component paths.
|
||||
*
|
||||
* @param {string} relativeTo
|
||||
* @returns {array}
|
||||
*/
|
||||
const getComponentPaths = (relativeTo = '') => fetchComponentData().pathList.map(componentPath => {
|
||||
return componentPath.replace(relativeTo, '');
|
||||
});
|
||||
|
||||
/**
|
||||
* Get the list of paths to build AMD sources.
|
||||
*
|
||||
* @returns {Array}
|
||||
*/
|
||||
const getAmdSrcGlobList = () => {
|
||||
const globList = [];
|
||||
fetchComponentData().pathList.forEach(componentPath => {
|
||||
globList.push(`${componentPath}/amd/src/*.js`);
|
||||
globList.push(`${componentPath}/amd/src/**/*.js`);
|
||||
});
|
||||
|
||||
return globList;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of paths to build YUI sources.
|
||||
*
|
||||
* @param {String} relativeTo
|
||||
* @returns {Array}
|
||||
*/
|
||||
const getYuiSrcGlobList = relativeTo => {
|
||||
const globList = [];
|
||||
fetchComponentData().pathList.forEach(componentPath => {
|
||||
const relativeComponentPath = componentPath.replace(relativeTo, '');
|
||||
globList.push(`${relativeComponentPath}/yui/src/**/*.js`);
|
||||
});
|
||||
|
||||
return globList;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of paths to thirdpartylibs.xml.
|
||||
*
|
||||
* @param {String} relativeTo
|
||||
* @returns {Array}
|
||||
*/
|
||||
const getThirdPartyLibsList = relativeTo => {
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
return fetchComponentData().pathList
|
||||
.map(componentPath => path.relative(relativeTo, componentPath) + '/thirdpartylibs.xml')
|
||||
.map(componentPath => componentPath.replace(/\\/g, '/'))
|
||||
.filter(path => fs.existsSync(path))
|
||||
.sort();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the list of thirdparty library paths.
|
||||
*
|
||||
* @returns {array}
|
||||
*/
|
||||
const getThirdPartyPaths = () => {
|
||||
const DOMParser = require('@xmldom/xmldom').DOMParser;
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const xpath = require('xpath');
|
||||
|
||||
const thirdpartyfiles = getThirdPartyLibsList(fs.realpathSync('./'));
|
||||
const libs = ['node_modules/', 'vendor/'];
|
||||
|
||||
const addLibToList = lib => {
|
||||
if (!lib.match('\\*') && fs.statSync(lib).isDirectory()) {
|
||||
// Ensure trailing slash on dirs.
|
||||
lib = lib.replace(/\/?$/, '/');
|
||||
}
|
||||
|
||||
// Look for duplicate paths before adding to array.
|
||||
if (libs.indexOf(lib) === -1) {
|
||||
libs.push(lib);
|
||||
}
|
||||
};
|
||||
|
||||
thirdpartyfiles.forEach(function(file) {
|
||||
const dirname = path.dirname(file);
|
||||
|
||||
const xmlContent = fs.readFileSync(file, 'utf8');
|
||||
const doc = new DOMParser().parseFromString(xmlContent);
|
||||
const nodes = xpath.select("/libraries/library/location/text()", doc);
|
||||
|
||||
nodes.forEach(function(node) {
|
||||
let lib = path.posix.join(dirname, node.toString());
|
||||
addLibToList(lib);
|
||||
});
|
||||
});
|
||||
|
||||
return libs;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the name of the component matching the specified path.
|
||||
*
|
||||
* @param {String} path
|
||||
* @returns {String|null} Name of matching component.
|
||||
*/
|
||||
const getComponentFromPath = path => {
|
||||
const componentList = fetchComponentData().components;
|
||||
|
||||
if (componentList.hasOwnProperty(path)) {
|
||||
return componentList[path];
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether the supplied path, relative to the Gruntfile.js, is in a known component.
|
||||
*
|
||||
* @param {String} checkPath The path to check. This can be with either Windows, or Linux directory separators.
|
||||
* @returns {String|null}
|
||||
*/
|
||||
const getOwningComponentDirectory = checkPath => {
|
||||
const path = require('path');
|
||||
|
||||
// Fetch all components into a reverse sorted array.
|
||||
// This ensures that components which are within the directory of another component match first.
|
||||
const pathList = Object.keys(fetchComponentData().components).sort().reverse();
|
||||
for (const componentPath of pathList) {
|
||||
// If the componentPath is the directory being checked, it will be empty.
|
||||
// If the componentPath is a parent of the directory being checked, the relative directory will not start with ..
|
||||
if (!path.relative(componentPath, checkPath).startsWith('..')) {
|
||||
return componentPath;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
fetchComponentData,
|
||||
getAmdSrcGlobList,
|
||||
getComponentFromPath,
|
||||
getComponentPaths,
|
||||
getOwningComponentDirectory,
|
||||
getYuiSrcGlobList,
|
||||
getThirdPartyLibsList,
|
||||
getThirdPartyPaths,
|
||||
};
|
||||
@@ -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.
|
||||
@@ -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,
|
||||
},
|
||||
};
|
||||
@@ -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();
|
||||
});
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -1,99 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/* jshint node: true, browser: false */
|
||||
/* eslint-env node */
|
||||
|
||||
/**
|
||||
* @copyright 2021 Andrew Nicols
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
module.exports = grunt => {
|
||||
|
||||
/**
|
||||
* Generate the PHPCS configuration.
|
||||
*
|
||||
* @param {Object} thirdPartyPaths
|
||||
*/
|
||||
const phpcsIgnore = (thirdPartyPaths) => {
|
||||
const {toXML} = require('jstoxml');
|
||||
|
||||
const config = {
|
||||
_name: 'ruleset',
|
||||
_attrs: {
|
||||
name: "MoodleCore",
|
||||
},
|
||||
_content: [
|
||||
{
|
||||
rule: {
|
||||
_attrs: {
|
||||
ref: './phpcs.xml.dist',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
thirdPartyPaths.forEach(library => {
|
||||
config._content.push({
|
||||
'exclude-pattern': library,
|
||||
});
|
||||
});
|
||||
|
||||
grunt.file.write('phpcs.xml', toXML(config, {
|
||||
header: true,
|
||||
indent: ' ',
|
||||
}) + "\n");
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate ignore files (utilising thirdpartylibs.xml data)
|
||||
*/
|
||||
const handler = function() {
|
||||
const path = require('path');
|
||||
const ComponentList = require(path.join(process.cwd(), '.grunt', 'components.js'));
|
||||
|
||||
// An array of paths to third party directories.
|
||||
const thirdPartyPaths = ComponentList.getThirdPartyPaths();
|
||||
|
||||
// Generate .eslintignore.
|
||||
const eslintIgnores = [
|
||||
'# Generated by "grunt ignorefiles"',
|
||||
// Do not ignore the .grunt directory.
|
||||
'!/.grunt',
|
||||
|
||||
// Ignore all yui/src meta directories and build directories.
|
||||
'*/**/yui/src/*/meta/',
|
||||
'*/**/build/',
|
||||
].concat(thirdPartyPaths);
|
||||
grunt.file.write('.eslintignore', eslintIgnores.join('\n') + '\n');
|
||||
|
||||
// Generate .stylelintignore.
|
||||
const stylelintIgnores = [
|
||||
'# Generated by "grunt ignorefiles"',
|
||||
'**/yui/build/*',
|
||||
'theme/boost/style/moodle.css',
|
||||
'theme/classic/style/moodle.css',
|
||||
'jsdoc/styles/*.css',
|
||||
].concat(thirdPartyPaths);
|
||||
grunt.file.write('.stylelintignore', stylelintIgnores.join('\n') + '\n');
|
||||
|
||||
phpcsIgnore(thirdPartyPaths);
|
||||
};
|
||||
|
||||
grunt.registerTask('ignorefiles', 'Generate ignore files for linters', handler);
|
||||
|
||||
return handler;
|
||||
};
|
||||
@@ -1,224 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/* jshint node: true, browser: false */
|
||||
/* eslint-env node */
|
||||
|
||||
/**
|
||||
* @copyright 2021 Andrew Nicols
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function to generate the destination for the uglify task
|
||||
* (e.g. build/file.min.js). This function will be passed to
|
||||
* the rename property of files array when building dynamically:
|
||||
* http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically
|
||||
*
|
||||
* @param {String} destPath the current destination
|
||||
* @param {String} srcPath the matched src path
|
||||
* @return {String} The rewritten destination path.
|
||||
*/
|
||||
const babelRename = function(destPath, srcPath) {
|
||||
destPath = srcPath.replace(`amd/src`, `amd/build`);
|
||||
destPath = destPath.replace(/\.js$/, '.min.js');
|
||||
return destPath;
|
||||
};
|
||||
|
||||
module.exports = grunt => {
|
||||
// Load the Ignorefiles tasks.
|
||||
require('./ignorefiles')(grunt);
|
||||
|
||||
// Load the Shifter tasks.
|
||||
require('./shifter')(grunt);
|
||||
|
||||
// Load ESLint.
|
||||
require('./eslint')(grunt);
|
||||
|
||||
// Load jsconfig.
|
||||
require('./jsconfig')(grunt);
|
||||
|
||||
// Load JSDoc.
|
||||
require('./jsdoc')(grunt);
|
||||
|
||||
const path = require('path');
|
||||
|
||||
// Register JS tasks.
|
||||
grunt.registerTask('yui', ['eslint:yui', 'shifter']);
|
||||
grunt.registerTask('amd', ['ignorefiles', 'eslint:amd', 'rollup']);
|
||||
grunt.registerTask('js', ['amd', 'yui']);
|
||||
|
||||
// Register NPM tasks.
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-rollup');
|
||||
|
||||
const babelTransform = require('@babel/core').transform;
|
||||
const babel = (options = {}) => {
|
||||
return {
|
||||
name: 'babel',
|
||||
|
||||
transform: (code, id) => {
|
||||
grunt.log.debug(`Transforming ${id}`);
|
||||
options.filename = id;
|
||||
const transformed = babelTransform(code, options);
|
||||
|
||||
return {
|
||||
code: transformed.code,
|
||||
map: transformed.map
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// Note: We have to use a rate limit plugin here because rollup runs all tasks asynchronously and in parallel.
|
||||
// When we kick off a full run, if we kick off a rollup of every file this will fork-bomb the machine.
|
||||
// To work around this we use a concurrent Promise queue based on the number of available processors.
|
||||
const rateLimit = () => {
|
||||
const queue = [];
|
||||
let queueRunner;
|
||||
|
||||
const startQueue = () => {
|
||||
if (queueRunner) {
|
||||
return;
|
||||
}
|
||||
|
||||
queueRunner = setTimeout(() => {
|
||||
const limit = Math.max(1, require('os').cpus().length / 2);
|
||||
grunt.log.debug(`Starting rollup with queue size of ${limit}`);
|
||||
runQueue(limit);
|
||||
}, 100);
|
||||
};
|
||||
|
||||
// The queue runner will run the next `size` items in the queue.
|
||||
const runQueue = (size = 1) => {
|
||||
queue.splice(0, size).forEach(resolve => {
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
name: 'ratelimit',
|
||||
|
||||
// The options hook is run in parallel.
|
||||
// We can return an unresolved Promise which is queued for later resolution.
|
||||
options: async() => {
|
||||
return new Promise(resolve => {
|
||||
queue.push(resolve);
|
||||
startQueue();
|
||||
});
|
||||
},
|
||||
|
||||
// When an item in the queue completes, start the next item in the queue.
|
||||
buildEnd: () => {
|
||||
runQueue();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const terser = require('rollup-plugin-terser').terser;
|
||||
grunt.config.merge({
|
||||
rollup: {
|
||||
options: {
|
||||
format: 'esm',
|
||||
dir: 'output',
|
||||
sourcemap: true,
|
||||
treeshake: false,
|
||||
context: 'window',
|
||||
plugins: [
|
||||
rateLimit(),
|
||||
babel({
|
||||
sourceMaps: true,
|
||||
comments: false,
|
||||
compact: false,
|
||||
plugins: [
|
||||
'transform-es2015-modules-amd-lazy',
|
||||
'system-import-transformer',
|
||||
// This plugin modifies the Babel transpiling for "export default"
|
||||
// so that if it's used then only the exported value is returned
|
||||
// by the generated AMD module.
|
||||
//
|
||||
// It also adds the Moodle plugin name to the AMD module definition
|
||||
// so that it can be imported as expected in other modules.
|
||||
path.resolve('.grunt/babel-plugin-add-module-to-define.js'),
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
'@babel/plugin-syntax-import-meta',
|
||||
['@babel/plugin-proposal-class-properties', {'loose': false}],
|
||||
'@babel/plugin-proposal-json-strings'
|
||||
],
|
||||
presets: [
|
||||
['@babel/preset-env', {
|
||||
targets: {
|
||||
browsers: [
|
||||
">0.25%",
|
||||
"last 2 versions",
|
||||
"not ie <= 10",
|
||||
"not op_mini all",
|
||||
"not Opera > 0",
|
||||
"not dead"
|
||||
]
|
||||
},
|
||||
modules: false,
|
||||
useBuiltIns: false
|
||||
}]
|
||||
]
|
||||
}),
|
||||
|
||||
terser({
|
||||
// Do not mangle variables.
|
||||
// Makes debugging easier.
|
||||
mangle: false,
|
||||
}),
|
||||
],
|
||||
},
|
||||
dist: {
|
||||
files: [{
|
||||
expand: true,
|
||||
src: grunt.moodleEnv.files ? grunt.moodleEnv.files : grunt.moodleEnv.amdSrc,
|
||||
rename: babelRename
|
||||
}],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
grunt.config.merge({
|
||||
watch: {
|
||||
amd: {
|
||||
files: grunt.moodleEnv.inComponent
|
||||
? ['amd/src/*.js', 'amd/src/**/*.js']
|
||||
: ['**/amd/src/**/*.js'],
|
||||
tasks: ['amd']
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// On watch, we dynamically modify config to build only affected files. This
|
||||
// method is slightly complicated to deal with multiple changed files at once (copied
|
||||
// from the grunt-contrib-watch readme).
|
||||
let changedFiles = Object.create(null);
|
||||
const onChange = grunt.util._.debounce(function() {
|
||||
const files = Object.keys(changedFiles);
|
||||
grunt.config('rollup.dist.files', [{expand: true, src: files, rename: babelRename}]);
|
||||
changedFiles = Object.create(null);
|
||||
}, 200);
|
||||
|
||||
grunt.event.on('watch', function(action, filepath) {
|
||||
changedFiles[filepath] = action;
|
||||
onChange();
|
||||
});
|
||||
|
||||
return {
|
||||
babelRename,
|
||||
};
|
||||
};
|
||||
@@ -1,53 +0,0 @@
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/* jshint node: true, browser: false */
|
||||
/* eslint-env node */
|
||||
|
||||
/**
|
||||
* @copyright 2022 Andrew Lyons <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
const configuration = {
|
||||
compilerOptions: {
|
||||
baseUrl: ".",
|
||||
paths: {
|
||||
},
|
||||
target: "es2015",
|
||||
allowSyntheticDefaultImports: false,
|
||||
},
|
||||
exclude: [
|
||||
"node_modules",
|
||||
],
|
||||
include: [],
|
||||
};
|
||||
|
||||
module.exports = (grunt) => {
|
||||
const handler = () => {
|
||||
const jsconfigData = Object.assign({}, configuration);
|
||||
|
||||
const path = require('path');
|
||||
const {fetchComponentData} = require(path.join(process.cwd(), '.grunt', 'components.js'));
|
||||
|
||||
const componentData = fetchComponentData().components;
|
||||
for (const [thisPath, component] of Object.entries(componentData)) {
|
||||
jsconfigData.compilerOptions.paths[`${component}/*`] = [`${thisPath}/amd/src/*`];
|
||||
jsconfigData.include.push(`${thisPath}/amd/src/**/*`);
|
||||
}
|
||||
|
||||
grunt.file.write('jsconfig.json', JSON.stringify(jsconfigData, null, " ") + "\n");
|
||||
};
|
||||
grunt.registerTask('jsconfig', 'Generate a jsconfig configuration compatible with the LSP', handler);
|
||||
};
|
||||
@@ -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');
|
||||
};
|
||||
@@ -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/"]
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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']
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
@@ -1,2 +0,0 @@
|
||||
**/amd/**
|
||||
/*.js
|
||||
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
}
|
||||
+71
-164
@@ -2,129 +2,76 @@
|
||||
# process (which uses our internal CI system) this file is here for the benefit
|
||||
# of community developers git clones - see MDL-51458.
|
||||
|
||||
sudo: false
|
||||
|
||||
# We currently disable Travis notifications entirely until https://github.com/travis-ci/travis-ci/issues/4976
|
||||
# is fixed.
|
||||
notifications:
|
||||
email:
|
||||
if: env(MOODLE_EMAIL) != no
|
||||
email: false
|
||||
|
||||
language: php
|
||||
|
||||
os: linux
|
||||
php:
|
||||
# We only run the highest and lowest supported versions to reduce the load on travis-ci.org.
|
||||
- 7.0
|
||||
# - 5.6
|
||||
# - 5.5
|
||||
- 5.4
|
||||
|
||||
dist: bionic
|
||||
env:
|
||||
# Although we want to run these jobs and see failures as quickly as possible, we also want to get the slowest job to
|
||||
# start first so that the total run time is not too high.
|
||||
#
|
||||
# We only run MySQL on PHP 5.6, so run that first.
|
||||
# CI Tests should be second-highest in priority as these only take <= 60 seconds to run under normal circumstances.
|
||||
# Postgres is significantly is pretty reasonable in its run-time.
|
||||
|
||||
services:
|
||||
- mysql
|
||||
- docker
|
||||
# Run unit tests on MySQL
|
||||
- DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
|
||||
|
||||
addons:
|
||||
postgresql: "9.6"
|
||||
# Run CI Tests without running PHPUnit.
|
||||
- DB=none PHPUNIT=false INSTALL=false CITEST=true
|
||||
|
||||
branches:
|
||||
except:
|
||||
- master
|
||||
- /MOODLE_[0-9]+_STABLE/
|
||||
- /^v[0-9]+\.[0-9]+\.[0-9]+.*/
|
||||
# Run unit tests on Postgres
|
||||
- DB=pgsql PHPUNIT=true INSTALL=false CITEST=false
|
||||
|
||||
jobs:
|
||||
matrix:
|
||||
# Enable fast finish.
|
||||
# This will fail the build if a single job fails (except those in allow_failures).
|
||||
# It will not stop the jobs from running.
|
||||
fast_finish: true
|
||||
|
||||
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/gallium'
|
||||
exclude:
|
||||
# MySQL - it's just too slow.
|
||||
# Exclude it on all versions except for 7.0
|
||||
# - env: DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
|
||||
# php: 5.6
|
||||
#
|
||||
# - env: DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
|
||||
# php: 5.5
|
||||
|
||||
- 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/gallium'
|
||||
|
||||
- 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
|
||||
- env: DB=mysqli PHPUNIT=true INSTALL=false CITEST=false
|
||||
php: 5.4
|
||||
|
||||
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
|
||||
echo -e "[mysqld]\nskip-log-bin" | sudo tee -a /etc/mysql/my.cnf
|
||||
sudo service mysql start
|
||||
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
|
||||
sh -c 'until pg_isready -p 5432; do echo "Waiting for the DB to be up..."; sleep 2; done'
|
||||
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
|
||||
# Disable xdebug. We aren't generating code coverage, and it has a huge impact upon test performance.
|
||||
- rm /home/travis/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini
|
||||
|
||||
echo 'extension="redis.so"' > /tmp/redis.ini
|
||||
phpenv config-add /tmp/redis.ini
|
||||
# Set the encrypted GITHUB_TOKEN if it's available to raise the API limit.
|
||||
- if [ -n "$GITHUB_APITOKEN" ]; then composer config github-oauth.github.com $GITHUB_APITOKEN; fi
|
||||
|
||||
# Install composer dependencies.
|
||||
# We need --no-interaction in case we hit API limits for composer. This causes it to fall back to a standard clone.
|
||||
# Typically it should be able to use the Composer cache if any other job has already completed before we started here.
|
||||
travis_retry composer install --prefer-dist --no-interaction;
|
||||
fi
|
||||
|
||||
- >
|
||||
if [ "$TASK" = 'GRUNT' ];
|
||||
then
|
||||
nvm install $NVM_VERSION ;
|
||||
nvm use $NVM_VERSION ;
|
||||
fi
|
||||
# Install composer dependencies.
|
||||
# We need --no-interaction in case we hit API limits for composer. This causes it to fall back to a standard clone.
|
||||
# Typically it should be able to use the Composer cache if any other job has already completed before we started here.
|
||||
- travis_retry composer install --prefer-dist --no-interaction
|
||||
|
||||
before_script:
|
||||
- if [[ ${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' ];
|
||||
if [ "$INSTALL" = 'true' -o "$PHPUNIT" = 'true' ];
|
||||
then
|
||||
# Copy generic configuration in place.
|
||||
cp config-dist.php config.php ;
|
||||
@@ -140,7 +87,7 @@ before_script:
|
||||
|
||||
# The wwwroot and dataroot.
|
||||
sed -i \
|
||||
-e "s%http://example.com/moodle%https://localhost%" \
|
||||
-e "s%http://example.com/moodle%http://localhost%" \
|
||||
-e "s%/home/example/moodledata%/home/travis/roots/base%" \
|
||||
config.php ;
|
||||
|
||||
@@ -160,58 +107,44 @@ before_script:
|
||||
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;' ;
|
||||
mysql -e 'CREATE DATABASE travis_ci_test DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_bin;' ;
|
||||
fi
|
||||
|
||||
if [ "$PHPUNIT" = 'true' ];
|
||||
then
|
||||
# Create a directory for the phpunit dataroot.
|
||||
mkdir -p "$HOME"/roots/phpunit
|
||||
|
||||
# The phpunit dataroot and prefix..
|
||||
sed -i \
|
||||
-e "/require_once/i \\\$CFG->phpunit_dataroot = '\/home\/travis\/roots\/phpunit';" \
|
||||
-e "/require_once/i \\\$CFG->phpunit_prefix = 'p_';" \
|
||||
config.php ;
|
||||
|
||||
# Initialise PHPUnit for Moodle.
|
||||
php admin/tool/phpunit/cli/init.php
|
||||
fi
|
||||
fi
|
||||
|
||||
script:
|
||||
########################################################################
|
||||
# PHPUnit
|
||||
########################################################################
|
||||
- >
|
||||
if [ "$TASK" = 'PHPUNIT' ];
|
||||
if [ "$PHPUNIT" = 'true' ];
|
||||
then
|
||||
# Create a directory for the phpunit dataroot.
|
||||
mkdir -p "$HOME"/roots/phpunit
|
||||
|
||||
# The phpunit dataroot and prefix..
|
||||
sed -i \
|
||||
-e "/require_once/i \\\$CFG->phpunit_dataroot = '\/home\/travis\/roots\/phpunit';" \
|
||||
-e "/require_once/i \\\$CFG->phpunit_prefix = 'p_';" \
|
||||
config.php ;
|
||||
# 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 ;
|
||||
vendor/bin/phpunit;
|
||||
fi
|
||||
|
||||
########################################################################
|
||||
# CI Tests
|
||||
########################################################################
|
||||
- >
|
||||
if [ "$TASK" = 'CITEST' ];
|
||||
if [ "$CITEST" = 'true' ];
|
||||
then
|
||||
# Note - this is deliberately placed in the script section as we
|
||||
# should not add any code until after phpunit has run.
|
||||
@@ -223,7 +156,7 @@ before_script:
|
||||
# We need the official upstream for comparison
|
||||
git remote add upstream https://github.com/moodle/moodle.git;
|
||||
|
||||
git fetch upstream MOODLE_311_STABLE;
|
||||
git fetch upstream MOODLE_30_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`
|
||||
@@ -234,35 +167,9 @@ before_script:
|
||||
export phpcmd=`which php`;
|
||||
fi
|
||||
|
||||
script:
|
||||
# Actually run the CI Tests - do this outside of the main test to make output clearer.
|
||||
- >
|
||||
if [ "$TASK" = 'PHPUNIT' ];
|
||||
then
|
||||
vendor/bin/phpunit --fail-on-risky --disallow-test-output --verbose;
|
||||
fi
|
||||
|
||||
- >
|
||||
if [ "$TASK" = 'CITEST' ];
|
||||
if [ "$CITEST" = 'true' ];
|
||||
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
|
||||
|
||||
@@ -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>.
|
||||
+216
-223
@@ -13,249 +13,242 @@
|
||||
// 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);
|
||||
// Windows users can't run grunt in a subdirectory, so allow them to set
|
||||
// the root by passing --root=path/to/dir.
|
||||
if (grunt.option('root')) {
|
||||
var root = grunt.option('root');
|
||||
if (grunt.file.exists(__dirname, root)) {
|
||||
cwd = path.join(__dirname, root);
|
||||
grunt.log.ok('Setting root to '+cwd);
|
||||
} else {
|
||||
grunt.fail.fatal('Setting root to '+root+' failed - path does not exist');
|
||||
}
|
||||
}
|
||||
|
||||
var inAMD = path.basename(cwd) == 'amd';
|
||||
|
||||
// Globbing pattern for matching all AMD JS source files.
|
||||
var amdSrc = [inAMD ? cwd + '/src/*.js' : '**/amd/src/*.js'];
|
||||
|
||||
/**
|
||||
* Add the named task.
|
||||
* 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} name
|
||||
* @param {Grunt} grunt
|
||||
* @param {String} destPath the current destination
|
||||
* @param {String} srcPath the matched src path
|
||||
* @return {String} The rewritten destination path.
|
||||
*/
|
||||
const addTask = (name, grunt) => {
|
||||
const path = require('path');
|
||||
const taskPath = path.resolve(`./.grunt/tasks/${name}.js`);
|
||||
|
||||
grunt.log.debug(`Including tasks for ${name} from ${taskPath}`);
|
||||
|
||||
require(path.resolve(`./.grunt/tasks/${name}.js`))(grunt);
|
||||
var uglify_rename = function (destPath, srcPath) {
|
||||
destPath = srcPath.replace('src', 'build');
|
||||
destPath = destPath.replace('.js', '.min.js');
|
||||
destPath = path.resolve(cwd, destPath);
|
||||
return destPath;
|
||||
};
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
jshint: {
|
||||
options: {jshintrc: '.jshintrc'},
|
||||
amd: { src: amdSrc }
|
||||
},
|
||||
uglify: {
|
||||
amd: {
|
||||
files: [{
|
||||
expand: true,
|
||||
src: amdSrc,
|
||||
rename: uglify_rename
|
||||
}]
|
||||
}
|
||||
},
|
||||
less: {
|
||||
bootstrapbase: {
|
||||
files: {
|
||||
"theme/bootstrapbase/style/moodle.css": "theme/bootstrapbase/less/moodle.less",
|
||||
"theme/bootstrapbase/style/editor.css": "theme/bootstrapbase/less/editor.less",
|
||||
},
|
||||
options: {
|
||||
compress: true
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
options: {
|
||||
nospawn: true // We need not to spawn so config can be changed dynamically.
|
||||
},
|
||||
amd: {
|
||||
files: ['**/amd/src/**/*.js'],
|
||||
tasks: ['amd']
|
||||
},
|
||||
bootstrapbase: {
|
||||
files: ["theme/bootstrapbase/less/**/*.less"],
|
||||
tasks: ["less:bootstrapbase"]
|
||||
},
|
||||
yui: {
|
||||
files: ['**/yui/src/**/*.js'],
|
||||
tasks: ['shifter']
|
||||
},
|
||||
},
|
||||
shifter: {
|
||||
options: {
|
||||
recursive: true,
|
||||
paths: [cwd]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Add Moodle task configuration.
|
||||
addTask('gherkinlint', grunt);
|
||||
addTask('ignorefiles', 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().
|
||||
*/
|
||||
tasks.shifter = function() {
|
||||
var async = require('async'),
|
||||
done = this.async(),
|
||||
options = grunt.config('shifter.options');
|
||||
|
||||
addTask('javascript', grunt);
|
||||
addTask('style', grunt);
|
||||
// Run the shifter processes one at a time to avoid confusing output.
|
||||
async.eachSeries(options.paths, function (src, filedone) {
|
||||
var args = [];
|
||||
args.push( path.normalize(__dirname + '/node_modules/shifter/bin/shifter'));
|
||||
|
||||
addTask('watch', grunt);
|
||||
addTask('startup', grunt);
|
||||
// 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);
|
||||
};
|
||||
|
||||
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 (inAMD) {
|
||||
grunt.task.run('amd');
|
||||
} else {
|
||||
// Run them all!.
|
||||
grunt.task.run('css');
|
||||
grunt.task.run('js');
|
||||
}
|
||||
};
|
||||
|
||||
// On watch, we dynamically modify config to build only affected files. This
|
||||
// method is slightly complicated to deal with multiple changed files at once (copied
|
||||
// from the grunt-contrib-watch readme).
|
||||
var changedFiles = Object.create(null);
|
||||
var onChange = grunt.util._.debounce(function() {
|
||||
var files = Object.keys(changedFiles);
|
||||
grunt.config('jshint.amd.src', files);
|
||||
grunt.config('uglify.amd.files', [{ expand: true, src: files, rename: uglify_rename }]);
|
||||
grunt.config('shifter.options.paths', files);
|
||||
changedFiles = Object.create(null);
|
||||
}, 200);
|
||||
|
||||
grunt.event.on('watch', function(action, filepath) {
|
||||
changedFiles[filepath] = action;
|
||||
onChange();
|
||||
});
|
||||
|
||||
// Register NPM tasks.
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-less');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
|
||||
// Register JS tasks.
|
||||
grunt.registerTask('shifter', 'Run Shifter against the current directory', tasks.shifter);
|
||||
grunt.registerTask('amd', ['jshint', 'uglify']);
|
||||
grunt.registerTask('js', ['amd', 'shifter']);
|
||||
|
||||
// Register CSS taks.
|
||||
grunt.registerTask('css', ['less:bootstrapbase']);
|
||||
|
||||
// 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
@@ -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!
|
||||
@@ -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
@@ -1,28 +1,29 @@
|
||||
.-..-.
|
||||
_____ | || |
|
||||
/____/-.---_ .---. .---. .-.| || | .---.
|
||||
| | _ _ |/ _ \/ _ \/ _ || |/ __ \
|
||||
* | | | | | || |_| || |_| || |_| || || |___/
|
||||
|_| |_| |_|\_____/\_____/\_____||_|\_____)
|
||||
QUICK INSTALL
|
||||
=============
|
||||
|
||||
Moodle - the world's open source learning platform
|
||||
For the impatient, here is a basic outline of the
|
||||
installation process, which normally takes me only
|
||||
a few minutes:
|
||||
|
||||
Moodle <https://moodle.org> is a learning platform designed to provide
|
||||
educators, administrators and learners with a single robust, secure and
|
||||
integrated system to create personalised learning environments.
|
||||
1) Move the Moodle files into your web directory.
|
||||
|
||||
You can download Moodle <https://download.moodle.org> and run it on your own
|
||||
web server, ask one of our Moodle Partners <https://moodle.com/partners/> to
|
||||
assist you, or have a MoodleCloud site <https://moodle.com/cloud/> set up for
|
||||
you.
|
||||
2) Create a single database for Moodle to store all
|
||||
its tables in (or choose an existing database).
|
||||
|
||||
Moodle is widely used around the world by universities, schools, companies and
|
||||
all manner of organisations and individuals.
|
||||
3) Visit your Moodle site with a browser, you should
|
||||
be taken to the install.php script, which will lead
|
||||
you through creating a config.php file and then
|
||||
setting up Moodle, creating an admin account etc.
|
||||
|
||||
Moodle is provided freely as open source software, under the GNU General Public
|
||||
License <https://docs.moodle.org/dev/License>.
|
||||
4) Set up a cron task to call the file admin/cron.php
|
||||
every five minutes or so.
|
||||
|
||||
Moodle is written in PHP and JavaScript and uses an SQL database for storing
|
||||
the data.
|
||||
|
||||
See <https://docs.moodle.org> for details of Moodle's many features.
|
||||
For more information, see the INSTALL DOCUMENTATION:
|
||||
|
||||
http://docs.moodle.org/en/Installing_Moodle
|
||||
|
||||
|
||||
Good luck and have fun!
|
||||
Martin Dougiamas, Lead Developer
|
||||
|
||||
|
||||
+28
-60
@@ -1,66 +1,34 @@
|
||||
MOODLE TRADEMARKS POLICY
|
||||
========================
|
||||
|
||||
The Moodle Trademark
|
||||
--------------------
|
||||
|
||||
The brand and word "Moodle" has trade mark protection in many countries around
|
||||
the world. Various Moodle™ trade marks are owned by either Moodle Pty Ltd or
|
||||
one of its associated entities. The law obligates trade mark owners to police
|
||||
their trade marks and prevent the use of confusingly similar names by
|
||||
third parties.
|
||||
|
||||
We have created a more concise and thorough set of Trademark Guidelines
|
||||
(https://moodle.com/wp-content/uploads/2023/02/Moodle-Trademark-Guidelines-2023-4.pdf)
|
||||
to help you understand how to comply with Moodle's trade mark requirements.
|
||||
The Trademark Guidelines will also assist our Moodle Certified Partners and the
|
||||
community to understand some of the principles that inform Moodle's stance
|
||||
whenever potential infringement has been detected by us or our community.
|
||||
|
||||
We need to be clear about use of the word "Moodle" and how we restrict its use
|
||||
when promoting commercial Moodle™ branded services. The proper use of
|
||||
trade marks reliably assures consumers about the quality of the associated
|
||||
products or services and where they have been derived from. Because the
|
||||
Moodle LMS is made available under the open source ‘GNU General Public License'
|
||||
that permits you to modify the copyrighted software, the distribution of such
|
||||
modified software in combination with Moodle trade marks can potentially
|
||||
mislead others in the community. To be clear, the GNU GPL does not include an
|
||||
implied right or licence to use Moodle's trade marks.
|
||||
|
||||
We do all this to protect the very business model that allows us to continue
|
||||
developing various Moodle software solutions for you.
|
||||
|
||||
Allowed uses of "Moodle"
|
||||
------------------------
|
||||
Moodle Trademark License
|
||||
------------------------
|
||||
|
||||
The following uses don't require any permission at all:
|
||||
The name Moodle™ is a registered trademark of the Moodle Trust.
|
||||
|
||||
* Referring to the software or the Moodle project as the "Moodle™ software"
|
||||
or the "Moodle™ project"
|
||||
* Describing your own implementation of the Moodle™ software platform
|
||||
(including within corporate settings).
|
||||
* Describing a Moodle-based community hub.
|
||||
* Describing certain software you've made that integrates with Moodle™
|
||||
branded software (e.g. a Moodle™ integration feature on another system).
|
||||
A key part of the business model that allows us to produce and
|
||||
distribute Moodle as completely Free open source software is that
|
||||
we restrict the commercial use of the Moodle trademark to those
|
||||
who have contracted to support Moodle development (Moodle Partners).
|
||||
|
||||
Restricted uses of "Moodle"
|
||||
---------------------------
|
||||
If you are intending to use the name (and/or logo) to advertise
|
||||
generic Moodle™ services (eg Moodle Hosting, Moodle Support,
|
||||
Moodle Certification, Moodle Training, Moodle Consulting,
|
||||
Moodle Customisation, Moodle Courseware Development, Moodle
|
||||
Theme design, Moodle Integrations, Moodle Installations, etc)
|
||||
or as the name of a software package, then you must seek
|
||||
direct permission in writing from the Moodle Trust via the
|
||||
moodle.com helpdesk, in accordance with normal trademark
|
||||
restrictions.
|
||||
|
||||
The following uses are generally prohibited without explicit and direct
|
||||
permission being granted to you by Moodle Pty Ltd. We do this to protect the
|
||||
Moodle™ project from software and sites which could confuse people. If in
|
||||
doubt, reach out for clarification at <trademarks@moodle.com>
|
||||
There are no restrictions on how you use the name in other
|
||||
contexts (for example, if you use Moodle just to provide
|
||||
courses then you can use the name freely to refer to it.)
|
||||
|
||||
* You can't use the word "Moodle" or any Moodle logos for commercial purposes
|
||||
without prior written permission from Moodle HQ.
|
||||
* You can't use "Moodle" in the name of your software (including Mobile apps).
|
||||
* You can't use "Moodle" in your company name.
|
||||
* You can't use "Moodle" in your domain name.
|
||||
* You can't use "Moodle" in advertising-related keywords (such as Adsense).
|
||||
* You can't use "Moodle" to describe services around Moodle
|
||||
(such as hosting, training, support, consulting, course creation services,
|
||||
theme development, customisation, installation, integration, analytics
|
||||
and certification) that cause consumers to be confused that you are
|
||||
associated with Moodle HQ if you are not.
|
||||
This applies even if you do not charge for the services.
|
||||
Note that usually only Moodle Partners have this permission.
|
||||
If you aren't sure of a particular case, please ask us via
|
||||
http://moodle.com/helpdesk: we'll be happy to either provide
|
||||
you with official permission in writing or help you fix
|
||||
your wording.
|
||||
|
||||
Martin Dougiamas
|
||||
Executive Director
|
||||
Moodle Trust
|
||||
http://moodle.com
|
||||
|
||||
@@ -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
@@ -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
@@ -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()) {
|
||||
|
||||
@@ -67,6 +64,8 @@ echo "<form id=\"authmenu\" method=\"post\" action=\"auth_config.php\">\n";
|
||||
echo "<div>\n";
|
||||
echo "<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\" />\n";
|
||||
echo "<input type=\"hidden\" name=\"auth\" value=\"".$auth."\" />\n";
|
||||
// HACK to prevent browsers from automatically inserting the user's password into the wrong fields.
|
||||
echo prevent_form_autofill_password();
|
||||
|
||||
// auth plugin description
|
||||
echo $OUTPUT->box_start();
|
||||
@@ -89,28 +88,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 +148,8 @@ 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 ($fieldname == 'url') {
|
||||
$fieldname = get_string('webpage');
|
||||
} else {
|
||||
$fieldname = get_string($fieldname);
|
||||
}
|
||||
|
||||
+27
-15
@@ -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,10 +154,7 @@
|
||||
$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.
|
||||
} else {
|
||||
debugging('Warning: block_'.$block->name.' returns true in has_config() but does not provide a settings.php file',
|
||||
DEBUG_DEVELOPER);
|
||||
}
|
||||
@@ -168,10 +180,10 @@
|
||||
$visible = '';
|
||||
} else if ($blocks[$blockid]->visible) {
|
||||
$visible = '<a href="blocks.php?hide='.$blockid.'&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.'&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 +198,10 @@
|
||||
$undeletable = '';
|
||||
} else if (in_array($blockname, $undeletableblocktypes)) {
|
||||
$undeletable = '<a href="blocks.php?unprotect='.$blockid.'&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.'&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
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* Privacy Subsystem implementation for core_admin.
|
||||
*
|
||||
* @package core_admin
|
||||
* @copyright 2018 Carlos Escobedo <carlos@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace core_admin\privacy;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
/**
|
||||
* Privacy Subsystem for core_admin implementing null_provider.
|
||||
*
|
||||
* @copyright 2018 Carlos Escobedo <carlos@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider implements \core_privacy\local\metadata\null_provider {
|
||||
/**
|
||||
* Get the language string identifier with the component's language
|
||||
* file to explain why this plugin stores no data.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_reason() : string {
|
||||
return 'privacy:metadata';
|
||||
}
|
||||
}
|
||||
@@ -1,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(' ', $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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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');
|
||||
|
||||
|
||||
@@ -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');
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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');
|
||||
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Fix orphaned calendar events that were broken by MDL-67494.
|
||||
*
|
||||
* This script will look for all the calendar events which userids
|
||||
* where broken by a wrong upgrade step, affecting to Moodle 3.9.5
|
||||
* and up.
|
||||
*
|
||||
* It performs checks to both:
|
||||
* a) Detect if the site was affected (ran the wrong upgrade step).
|
||||
* b) Look for orphaned calendar events, categorising them as:
|
||||
* - standard: site / category / course / group / user events
|
||||
* - subscription: events created via subscriptions.
|
||||
* - action: normal action events, created to show common important dates.
|
||||
* - override: user and group override events, particular, that some activities support.
|
||||
* - custom: other events, not being any of the above, common or particular.
|
||||
* By specifying it (--fix) try to recover as many broken events (missing userid) as
|
||||
* possible. Standard, subscription, action, override events in core are fully supported but
|
||||
* override or custom events should be fixed by each plugin as far as there isn't any standard
|
||||
* API (plugin-wise) to launch a rebuild of the calendar events.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2021 onwards Simey Lameze <simey@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('CLI_SCRIPT', true);
|
||||
|
||||
require_once(__DIR__ . '/../../config.php');
|
||||
require_once($CFG->libdir . "/clilib.php");
|
||||
require_once($CFG->libdir . '/db/upgradelib.php');
|
||||
|
||||
// Supported options.
|
||||
$long = ['fix' => false, 'help' => false];
|
||||
$short = ['f' => 'fix', 'h' => 'help'];
|
||||
|
||||
// CLI options.
|
||||
[$options, $unrecognized] = cli_get_params($long, $short);
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
|
||||
}
|
||||
|
||||
if ($options['help']) {
|
||||
$help = <<<EOT
|
||||
Fix orphaned calendar events.
|
||||
|
||||
This script detects calendar events that have had their
|
||||
userid lost. By default it will perform various checks
|
||||
and report them, showing the site status in an easy way.
|
||||
|
||||
Also, optionally (--fix), it wil try to recover as many
|
||||
lost userids as possible from different sources. Note that
|
||||
this script aims to process well-know events in core,
|
||||
leaving custom events in 3rd part plugins mostly unmodified
|
||||
because there isn't any consistent way to regenerate them.
|
||||
|
||||
For more details: https://tracker.moodle.org/browse/MDL-71156
|
||||
|
||||
Options:
|
||||
-h, --help Print out this help.
|
||||
-f, --fix Fix the orphaned calendar events in the DB.
|
||||
If not specified only check and report problems to STDERR.
|
||||
|
||||
Usage:
|
||||
- Only report: \$ sudo -u www-data /usr/bin/php admin/cli/fix_orphaned_calendar_events.php
|
||||
- Report and fix: \$ sudo -u www-data /usr/bin/php admin/cli/fix_orphaned_calendar_events.php -f
|
||||
EOT;
|
||||
|
||||
cli_writeln($help);
|
||||
die;
|
||||
}
|
||||
|
||||
// Check various usual pre-requisites.
|
||||
if (empty($CFG->version)) {
|
||||
cli_error('Database is not yet installed.');
|
||||
}
|
||||
|
||||
$admin = get_admin();
|
||||
if (!$admin) {
|
||||
cli_error('Error: No admin account was found.');
|
||||
}
|
||||
|
||||
if (moodle_needs_upgrading()) {
|
||||
cli_error('Moodle upgrade pending, script execution suspended.');
|
||||
}
|
||||
|
||||
// Do everything as admin by default.
|
||||
\core\session\manager::set_user($admin);
|
||||
|
||||
// Report current site status.
|
||||
cli_heading('Checking the site status');
|
||||
$needsfix = upgrade_calendar_site_status();
|
||||
|
||||
// Report current calendar events status.
|
||||
cli_heading('Checking the calendar events status');
|
||||
$info = upgrade_calendar_events_status();
|
||||
$hasbadevents = $info['total']->bad > 0 || $info['total']->bad != $info['other']->bad;
|
||||
$needsfix = $needsfix || $hasbadevents;
|
||||
|
||||
// If, selected, fix as many calendar events as possible.
|
||||
if ($options['fix']) {
|
||||
|
||||
// If the report has told us that the fix was not needed... ask for confirmation!
|
||||
if (!$needsfix) {
|
||||
cli_writeln("This site DOES NOT NEED to run the calendar events fix.");
|
||||
$input = cli_input('Are you completely sure that you want to run the fix? (y/N)', 'N', ['y', 'Y', 'n', 'N']);
|
||||
if (strtolower($input) != 'y') {
|
||||
exit(0);
|
||||
}
|
||||
cli_writeln("");
|
||||
}
|
||||
cli_heading('Fixing as many as possible calendar events');
|
||||
upgrade_calendar_events_fix_remaining($info);
|
||||
// Report current (after fix) calendar events status.
|
||||
cli_heading('Checking the calendar events status (after fix)');
|
||||
upgrade_calendar_events_status();
|
||||
} else if ($needsfix) {
|
||||
// Fix option was not provided but problem events have been found. Notify the user and provide info how to fix these events.
|
||||
cli_writeln("This site NEEDS to run the calendar events fix!");
|
||||
cli_writeln("To fix the calendar events, re-run this script with the --fix option.");
|
||||
}
|
||||
@@ -1,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
-219
@@ -90,7 +90,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 +100,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 +146,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 +172,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 +220,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 +244,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',
|
||||
@@ -267,7 +272,6 @@ 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);
|
||||
@@ -393,6 +397,7 @@ if ($interactive) {
|
||||
$CFG->wwwroot = $wwwroot;
|
||||
$CFG->httpswwwroot = $CFG->wwwroot;
|
||||
|
||||
|
||||
//We need dataroot before lang download
|
||||
$CFG->dataroot = $options['dataroot'];
|
||||
if ($interactive) {
|
||||
@@ -443,7 +448,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 +519,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,118 +620,110 @@ 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 shortname
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('shortsitename', 'moodle'));
|
||||
|
||||
if ($options['shortname'] !== '') {
|
||||
$prompt = get_string('clitypevaluedefault', 'admin', $options['shortname']);
|
||||
} else {
|
||||
$prompt = get_string('clitypevalue', 'admin');
|
||||
}
|
||||
|
||||
do {
|
||||
$options['shortname'] = cli_input($prompt, $options['shortname']);
|
||||
} while (empty($options['shortname']));
|
||||
} else {
|
||||
if (empty($options['shortname'])) {
|
||||
$a = (object)array('option'=>'shortname', 'value'=>$options['shortname']);
|
||||
cli_error(get_string('cliincorrectvalueerror', 'admin', $a));
|
||||
}
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
// Ask for the upgrade key.
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
@@ -751,27 +742,23 @@ if ($options['upgradekey'] !== '') {
|
||||
$CFG->upgradekey = $options['upgradekey'];
|
||||
}
|
||||
|
||||
// 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'));
|
||||
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,14 +806,8 @@ if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
|
||||
cli_error(get_string('pluginschecktodo', 'admin'));
|
||||
}
|
||||
|
||||
if (!$skipdatabase) {
|
||||
if (!$options['skip-database']) {
|
||||
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";
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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') {
|
||||
|
||||
@@ -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);
|
||||
@@ -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
|
||||
@@ -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);
|
||||
@@ -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'] || !empty($CFG->showcrondebugging)) {
|
||||
set_debugging(DEBUG_DEVELOPER, true);
|
||||
}
|
||||
|
||||
if ($options['showsql'] || !empty($CFG->showcronsql)) {
|
||||
$DB->set_debug(true);
|
||||
}
|
||||
if ($options['list']) {
|
||||
cli_heading("List of scheduled tasks ($CFG->wwwroot)");
|
||||
|
||||
$shorttime = get_string('strftimedatetimeshort');
|
||||
|
||||
$tasks = \core\task\manager::get_all_scheduled_tasks();
|
||||
echo str_pad(get_string('scheduledtasks', 'tool_task'), 50, ' ') . ' ' . str_pad(get_string('runpattern', 'tool_task'), 17, ' ')
|
||||
. ' ' . str_pad(get_string('lastruntime', 'tool_task'), 40, ' ') . get_string('nextruntime', 'tool_task') . "\n";
|
||||
foreach ($tasks as $task) {
|
||||
$class = '\\' . get_class($task);
|
||||
$schedule = $task->get_minute() . ' '
|
||||
. $task->get_hour() . ' '
|
||||
. $task->get_day() . ' '
|
||||
. $task->get_day_of_week() . ' '
|
||||
. $task->get_month() . ' '
|
||||
. $task->get_day_of_week();
|
||||
$nextrun = $task->get_next_run_time();
|
||||
$lastrun = $task->get_last_run_time();
|
||||
|
||||
$plugininfo = core_plugin_manager::instance()->get_plugin_info($task->get_component());
|
||||
$plugindisabled = $plugininfo && $plugininfo->is_enabled() === false && !$task->get_run_if_component_disabled();
|
||||
|
||||
if ($plugindisabled) {
|
||||
$nextrun = get_string('plugindisabled', 'tool_task');
|
||||
} else if ($task->get_disabled()) {
|
||||
$nextrun = get_string('taskdisabled', 'tool_task');
|
||||
} else if ($nextrun > time()) {
|
||||
$nextrun = userdate($nextrun);
|
||||
} else {
|
||||
$nextrun = get_string('asap', 'tool_task');
|
||||
}
|
||||
|
||||
if ($lastrun) {
|
||||
$lastrun = userdate($lastrun);
|
||||
} else {
|
||||
$lastrun = get_string('never');
|
||||
}
|
||||
|
||||
echo str_pad($class, 50, ' ') . ' ' . str_pad($schedule, 17, ' ') .
|
||||
' ' . str_pad($lastrun, 40, ' ') . ' ' . $nextrun . "\n";
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($execute = $options['execute']) {
|
||||
if (!$task = \core\task\manager::get_scheduled_task($execute)) {
|
||||
mtrace("Task '$execute' not found");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (moodle_needs_upgrading()) {
|
||||
mtrace("Moodle upgrade pending, cannot execute tasks.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!get_config('core', 'cron_enabled') && !$options['force']) {
|
||||
mtrace('Cron is disabled. Use --force to override.');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
\core\task\manager::scheduled_task_starting($task);
|
||||
|
||||
// Increase memory limit.
|
||||
raise_memory_limit(MEMORY_EXTRA);
|
||||
|
||||
// Emulate normal session - we use admin account by default.
|
||||
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);
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
@@ -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'));
|
||||
|
||||
@@ -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);
|
||||
@@ -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
@@ -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
@@ -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
@@ -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')));
|
||||
|
||||
+25
-90
@@ -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,12 +52,6 @@ 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'])) {
|
||||
@@ -96,12 +95,6 @@ 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
|
||||
|
||||
@@ -226,7 +219,7 @@ if (!core_tables_exist()) {
|
||||
}
|
||||
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);
|
||||
@@ -235,13 +228,13 @@ if (!core_tables_exist()) {
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
$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);
|
||||
@@ -316,11 +309,6 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
$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 +318,6 @@ 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);
|
||||
}
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
|
||||
if (upgrade_stale_php_files_present()) {
|
||||
@@ -358,9 +341,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 +351,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)) {
|
||||
@@ -508,9 +491,8 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
} 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)) {
|
||||
echo $output->unsatisfied_dependencies_page($version, $failed, $PAGE->url);
|
||||
die();
|
||||
}
|
||||
unset($failed);
|
||||
@@ -534,10 +516,7 @@ 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,
|
||||
)));
|
||||
$PAGE->set_url(new moodle_url($PAGE->url, array('confirmplugincheck' => $confirmplugins)));
|
||||
|
||||
check_upgrade_key($upgradekeyhash);
|
||||
|
||||
@@ -547,21 +526,7 @@ if (!$cache and moodle_needs_upgrading()) {
|
||||
$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);
|
||||
@@ -700,10 +665,9 @@ if (!$cache and moodle_needs_upgrading()) {
|
||||
|
||||
// Make sure plugin dependencies are always checked.
|
||||
$failed = array();
|
||||
if (!$pluginman->all_plugins_ok($version, $failed, $CFG->branch)) {
|
||||
if (!$pluginman->all_plugins_ok($version, $failed)) {
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->unsatisfied_dependencies_page($version, $failed, new moodle_url($PAGE->url,
|
||||
array('confirmplugincheck' => 0)));
|
||||
echo $output->unsatisfied_dependencies_page($version, $failed, $PAGE->url);
|
||||
die();
|
||||
}
|
||||
unset($failed);
|
||||
@@ -718,7 +682,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&lang=$CFG->lang");
|
||||
}
|
||||
@@ -821,7 +784,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 +797,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);
|
||||
|
||||
@@ -883,29 +840,9 @@ 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');
|
||||
|
||||
@@ -913,6 +850,4 @@ $output = $PAGE->get_renderer('core', 'admin');
|
||||
|
||||
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed, $cronoverdue, $dbproblems,
|
||||
$maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
|
||||
$registered, $cachewarnings, $eventshandlers, $themedesignermode, $devlibdir,
|
||||
$mobileconfigured, $overridetossl, $invalidforgottenpasswordurl, $croninfrequent,
|
||||
$showcampaigncontent, $showfeedbackencouragement);
|
||||
$registered, $cachewarnings);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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');
|
||||
|
||||
|
||||
@@ -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();
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -2,16 +2,18 @@
|
||||
|
||||
// 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');
|
||||
|
||||
$sort = optional_param('sort', 'username', PARAM_ALPHAEXT);
|
||||
$sort = optional_param('sort', 'username', PARAM_ALPHA);
|
||||
$dir = optional_param('dir', 'ASC', PARAM_ALPHA);
|
||||
$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,20 +150,12 @@ 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&dir=$columndir&\">".$string[$column]."</a>$columnicon";
|
||||
}
|
||||
$headings['delete'] = '';
|
||||
|
||||
$sortorder = get_safe_orderby([
|
||||
'username' => 'username',
|
||||
'mnet_host_id' => 'mnet_host_id',
|
||||
'access' => 'accessctrl',
|
||||
'default' => 'username',
|
||||
], $sort, $dir, false);
|
||||
|
||||
$acl = $DB->get_records('mnet_sso_access_control', null, $sortorder);
|
||||
$acl = $DB->get_records('mnet_sso_access_control', null, "$sort $dir", '*'); //, $page * $perpage, $perpage);
|
||||
$aclcount = $DB->count_records('mnet_sso_access_control');
|
||||
|
||||
if (!$acl) {
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -59,8 +59,8 @@ class mnet_simple_host_form extends moodleform {
|
||||
$wwwroot = 'http://'.$wwwroot;
|
||||
}
|
||||
if ($host = $DB->get_record('mnet_host', array('wwwroot' => $wwwroot))) {
|
||||
$str = get_string('hostexists', 'mnet', (new moodle_url('/admin/mnet/peers.php', ['hostid' => $host->id]))->out());
|
||||
return array('wwwroot' => $str);
|
||||
global $CFG;
|
||||
return array('wwwroot' => get_string('hostexists', 'mnet', $CFG->wwwroot . '/admin/mnet/peers.php?hostid=' . $host->id));
|
||||
}
|
||||
return array();
|
||||
}
|
||||
@@ -155,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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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" .
|
||||
"&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&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&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") {
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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');
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user