Compare commits
914 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25c9c6336b | |||
| a88baa553a | |||
| 2b0e7a4ea9 | |||
| 46cb3afcfe | |||
| b7bb837d2b | |||
| bf1e1b917f | |||
| 35c54f8ea8 | |||
| ffc5dc3245 | |||
| 64f1c9d901 | |||
| b7ee5cb2ea | |||
| 0581a99241 | |||
| d084e4194c | |||
| 56f3b3f412 | |||
| 0ecc1a8eab | |||
| 6cb4bd65d3 | |||
| 034729a5ce | |||
| 4676d5ad35 | |||
| a722b44a09 | |||
| 8d111d5136 | |||
| a423038589 | |||
| cff7de72ed | |||
| 18b60b3d2b | |||
| fb9553cac0 | |||
| 2b746fc34a | |||
| 87c1819e2f | |||
| 2e4684f51c | |||
| f68e327afa | |||
| 7471e92601 | |||
| 5dbf43b0de | |||
| 98c155a433 | |||
| 7c2d448bf8 | |||
| fb5ed6a5ca | |||
| beed18a8e9 | |||
| 79d23bb46b | |||
| 145c57f2f9 | |||
| 385e7e0c26 | |||
| e848d21f9e | |||
| e8014f4833 | |||
| 66b2dcd7be | |||
| f41a30229e | |||
| d8a7f2aeb7 | |||
| e7cdd0e77c | |||
| cf889e4fbd | |||
| bb519b05b1 | |||
| ad796334cb | |||
| 0e903c3f7f | |||
| 63c0acc5e9 | |||
| 307600962c | |||
| d0cf886bf8 | |||
| 0c8ad6a113 | |||
| bff4d30a79 | |||
| 3d9b0a9b1b | |||
| 5570436ef3 | |||
| 96d6f625f3 | |||
| 9c8a6c45f9 | |||
| be328441a2 | |||
| e282b1f1fc | |||
| 28ccb81e87 | |||
| bf84c3f075 | |||
| 429de834fa | |||
| 77c0308e74 | |||
| 991ac49b61 | |||
| 56a0e6ed87 | |||
| 710bfa00e7 | |||
| 5d70a8d5ad | |||
| 39a390f1f5 | |||
| 978ed33fb1 | |||
| 666d420194 | |||
| bdf64b7eec | |||
| 413b321344 | |||
| 4497ed3938 | |||
| fc992c94af | |||
| 7b04b19e06 | |||
| 7dfa4d625b | |||
| 648ec6857b | |||
| f6f931728a | |||
| de254adfd3 | |||
| bf0a0ed189 | |||
| 76ebea9add | |||
| 4fef7d1c87 | |||
| 582a3baf70 | |||
| 9961411a12 | |||
| ace0fcf5b4 | |||
| d3750e40ae | |||
| 8e506aa53c | |||
| 687e3b53c0 | |||
| 285bc3e242 | |||
| 8dc826354d | |||
| d5409002be | |||
| 3e1e159efa | |||
| a4ed555b2f | |||
| 07b3e80ed1 | |||
| 023ebdb1af | |||
| b09d19d5bd | |||
| 3acc7fba61 | |||
| 66039dbc91 | |||
| 90766fb12b | |||
| 3984d03fda | |||
| 0a9eae8b7a | |||
| aac11a3c4b | |||
| 84801cd656 | |||
| 542e7b52f2 | |||
| cbc680eb33 | |||
| 9a9542a238 | |||
| 5b3308939d | |||
| da348e315a | |||
| ba8bc23906 | |||
| 9c1f81775e | |||
| c6e6c935af | |||
| 474159da70 | |||
| 9ccc9ec175 | |||
| 2903b1ae22 | |||
| 5316b73d41 | |||
| 2669dd7963 | |||
| 4705bff0e1 | |||
| 19bd02eabd | |||
| 0701f2f08c | |||
| d18f809ec4 | |||
| 87252eae2c | |||
| df143c2923 | |||
| 621e8888e5 | |||
| ff76a9d590 | |||
| a9a9fd455a | |||
| 81bbf95756 | |||
| 30702cc0bd | |||
| 5eb80c4af6 | |||
| 1f19dc8237 | |||
| ca42dbc0dd | |||
| 04ed69e387 | |||
| b30c16ec86 | |||
| 532b7c9462 | |||
| d09616d194 | |||
| 6c06678c34 | |||
| b089becae9 | |||
| 703d8c2784 | |||
| 2a7ae663c5 | |||
| b303604bf1 | |||
| 9f0a5cf2f5 | |||
| 75232c7d34 | |||
| 0e57a3dede | |||
| d9dc216897 | |||
| 814f15a05d | |||
| 50cd119caa | |||
| caaf2427a7 | |||
| 88c69c2dcf | |||
| 4398cdace0 | |||
| 519142291c | |||
| 20b96798d7 | |||
| 3816bd8776 | |||
| 760ffcd6bf | |||
| 76bd81c69c | |||
| 4a8e6db894 | |||
| f5fbfb4d6b | |||
| 621f04de6a | |||
| 93d309cce2 | |||
| 53cc513636 | |||
| bf4f5df33e | |||
| d784d3751c | |||
| 7ef7de84a2 | |||
| 259bbd1960 | |||
| 765579d021 | |||
| a7e0f274f5 | |||
| bdef5416c3 | |||
| ad35c1ca2f | |||
| 958b331ada | |||
| 470ba08790 | |||
| 7ac967501b | |||
| 4bb12ff74d | |||
| 0ffb67352b | |||
| 713a5cdb97 | |||
| bf61d3f2b7 | |||
| f7ea6feec7 | |||
| b46eb4266d | |||
| e8bc91383d | |||
| 75bb4372ca | |||
| 1d0dc3102a | |||
| 8b89ab5798 | |||
| 67ccb85794 | |||
| 60e2e906f1 | |||
| aeccf1b188 | |||
| 512320cd6c | |||
| aefc7f7f70 | |||
| 2ab788bcf8 | |||
| 2ecdf811f3 | |||
| 8a6d5c8c88 | |||
| 765ef31f00 | |||
| e011fc3dfb | |||
| b08e192757 | |||
| a4ec901a4d | |||
| a99105cc33 | |||
| 8278f79219 | |||
| 5fa3dccf4b | |||
| b306a159de | |||
| 14d1be23c1 | |||
| 3f4935dfda | |||
| 3958f4a302 | |||
| 3c7f5e8472 | |||
| 7db4bf3b34 | |||
| baa5130e0a | |||
| 01d1ae9a5b | |||
| 1fa5fe2104 | |||
| c91312545d | |||
| 68e8070295 | |||
| c2ba01fe9e | |||
| 6714c137c8 | |||
| 31f8f75672 | |||
| 8d268a8d04 | |||
| ac210ad583 | |||
| 29d555ab48 | |||
| 86fa1ca83d | |||
| 8a5783c2be | |||
| fc71bf1e4a | |||
| 0845113531 | |||
| c131927ae5 | |||
| f1b71b0199 | |||
| 952b0caf57 | |||
| 2366f12757 | |||
| 3135b6f694 | |||
| 4be324b42a | |||
| 2d887636e6 | |||
| 4e0b890955 | |||
| ee1fac1fd8 | |||
| 0a397e3fd2 | |||
| f4397e3098 | |||
| cc2932aefa | |||
| ce20bd7a73 | |||
| f5f5bfbdf7 | |||
| e3e8ee312b | |||
| 5f2dd1bd50 | |||
| 26c79027ff | |||
| cfbcdc97e5 | |||
| 6bdfddc463 | |||
| 481d6f6387 | |||
| a174ed3736 | |||
| eb77088991 | |||
| a9c3e2f95e | |||
| 9cab0bb465 | |||
| 53c04bafc2 | |||
| 409b3bbd81 | |||
| fcad36339a | |||
| 10892d50d2 | |||
| 69aca65995 | |||
| ec5aca167c | |||
| 59cf70e977 | |||
| 1c8d4b0bce | |||
| ed401f9445 | |||
| a80c888892 | |||
| 6354c24aed | |||
| 5d21bf1b16 | |||
| 4a3f3ee3e4 | |||
| b2d9aaa126 | |||
| 5e17f2faeb | |||
| 92e745c293 | |||
| f4670d9e85 | |||
| cc1968a042 | |||
| 7e107b3a98 | |||
| 6c15dc2f3c | |||
| 072c1ad68e | |||
| 0590e71eeb | |||
| 3536e97dc8 | |||
| f5cb0ec042 | |||
| 40ed8aa97a | |||
| 309550be69 | |||
| 535caf12c6 | |||
| e4bb1b0d75 | |||
| bd3ce90c13 | |||
| 1542213b00 | |||
| 6a838cd4a0 | |||
| c0858f7068 | |||
| 1128545ebf | |||
| 484606eb08 | |||
| 2d28f15a3a | |||
| e6f2757f3c | |||
| f525ed2bdc | |||
| df991a4d53 | |||
| d72a6fc04c | |||
| 83ecf18e34 | |||
| 49b92a4a70 | |||
| d540a0ae0b | |||
| a2f1de61a0 | |||
| ae89df663a | |||
| ee8d64f6ef | |||
| 11ac4acdb1 | |||
| c3fbb0278b | |||
| 375c1b8e20 | |||
| 868cd1eacb | |||
| 4996652352 | |||
| 3857644a5c | |||
| eb8ecb04b6 | |||
| 8e6fdc1cdb | |||
| 733a5b75e9 | |||
| af58905893 | |||
| af0fd8128f | |||
| b559117706 | |||
| 4e6831d51c | |||
| e60183e163 | |||
| 59b30e3dae | |||
| 87cc8008f4 | |||
| 35a8f83e2c | |||
| a31372df3f | |||
| 252cc45466 | |||
| b652d2afc7 | |||
| 070453243b | |||
| 991a4c0fd1 | |||
| 6a30269d98 | |||
| 8faaa5da65 | |||
| f6dd23d9a2 | |||
| b82faf7eda | |||
| 191c5c293a | |||
| 8d2bae85ed | |||
| e064cef324 | |||
| eca36ffd7c | |||
| 4f32de51a9 | |||
| 5f115af823 | |||
| 474a338a97 | |||
| 7bbc73ce0c | |||
| cb5145334d | |||
| 5a552ad6f3 | |||
| 5c1115ba0b | |||
| 7ec6835728 | |||
| e567e64d12 | |||
| bade4a18e5 | |||
| 49ab08f771 | |||
| 3923a219bd | |||
| 750ec445bd | |||
| 1dfd080f54 | |||
| 3c239a6a11 | |||
| 4da24e858c | |||
| 4d4a8423b0 | |||
| b937159eed | |||
| 0c4d9eff86 | |||
| 25f23432f3 | |||
| 3a0efca438 | |||
| 1124ceea9a | |||
| e5cddc8c7e | |||
| 1f6ca1e497 | |||
| 332da1d527 | |||
| 645beae25f | |||
| 1831e2b2fc | |||
| ca88210f3f | |||
| 05582654f2 | |||
| c5f693dede | |||
| 7f9d364fd2 | |||
| b1f0f049d0 | |||
| 0ac06b7216 | |||
| 499dfeff2a | |||
| 59d7f7f2cb | |||
| 57e38ad969 | |||
| 54a8fef92f | |||
| cdbe521e62 | |||
| 8571a061e7 | |||
| 19069c7f28 | |||
| 18b42d9835 | |||
| ebd3da32b5 | |||
| b70e27f531 | |||
| bd7217b3d8 | |||
| d99d036b44 | |||
| 858f188c0f | |||
| d31f12bcbd | |||
| b7f8d08706 | |||
| ee4a93267f | |||
| da7d965e01 | |||
| 5e52542b1e | |||
| 767b4df9c3 | |||
| 10539bfad8 | |||
| 69f5ad8f36 | |||
| 8d650c02c4 | |||
| e971f11251 | |||
| 1ca2f014bb | |||
| f3c2624fbc | |||
| 543191e0dc | |||
| 341c68c779 | |||
| ecf1a221dc | |||
| 2a1ef8b3a7 | |||
| 77399dd147 | |||
| 48aad65284 | |||
| a5eac2bf95 | |||
| 15ebf11b5e | |||
| f0c559d33b | |||
| 8da3995f30 | |||
| 903f4721c9 | |||
| 810e115d6f | |||
| 3b7968954c | |||
| 15847cecbf | |||
| 4e41fc8b18 | |||
| c4e65af6f3 | |||
| 5ab6beeb50 | |||
| 684d142401 | |||
| 78d57d0ae7 | |||
| df8633b8d0 | |||
| a22c821033 | |||
| e3bd18d3d7 | |||
| 9856202e71 | |||
| c5892e5e37 | |||
| 9c0aa6e6d0 | |||
| 97a6abc12f | |||
| 7cea622409 | |||
| 085d6e79e1 | |||
| ddc3699107 | |||
| a0d8aefacf | |||
| 3017d2bab8 | |||
| 93c5807711 | |||
| 5bc2cb3c0e | |||
| caca47f50a | |||
| cf24975d2e | |||
| da048e60db | |||
| fc0bb48542 | |||
| 9234d79fd1 | |||
| 7971d7270c | |||
| 5ca6cce026 | |||
| 8b0bf17160 | |||
| e65777fd22 | |||
| f6735cb3e0 | |||
| 3c3a806f6b | |||
| bf52d11f1e | |||
| 1a11bf4706 | |||
| da428650cd | |||
| de186ff27f | |||
| 3aa7b0df78 | |||
| d329ada4b9 | |||
| 77d0435c3e | |||
| d64f8235fe | |||
| 3ebe724736 | |||
| 4f41f8407d | |||
| a95b434f3e | |||
| 827473833d | |||
| 84720307c3 | |||
| d70fb8fefe | |||
| 559b686e5b | |||
| dda635074d | |||
| 0ada61fdcf | |||
| dbc5a45cc6 | |||
| 8356ee9462 | |||
| 710ec0e546 | |||
| 3c3f5965d3 | |||
| 6f2760071c | |||
| 9c3d4683a4 | |||
| dcb7cfd384 | |||
| 0fbabd85c6 | |||
| 96482ded5e | |||
| 1cb4d36126 | |||
| 7ae0f78bf2 | |||
| f214adb270 | |||
| 613e3038f8 | |||
| d2154bafdb | |||
| 7f45491d4d | |||
| 2f39bfc7d8 | |||
| 09979fde33 | |||
| 4fbeed480a | |||
| 39f22c5f7d | |||
| 5a0c850e50 | |||
| a408e168cc | |||
| bb5b12d936 | |||
| 091faeeb09 | |||
| 6c00f683db | |||
| 30f719c44c | |||
| 1893b39bfc | |||
| 102579cf75 | |||
| 38629d7f32 | |||
| df5bca4acc | |||
| 7db7c8e953 | |||
| a77c92bb9c | |||
| 2850311ace | |||
| 8e09ae50b0 | |||
| 6ac4aa49aa | |||
| a639cddc39 | |||
| 4f910adaea | |||
| 9cb87ef480 | |||
| 7cdba7e644 | |||
| 5e0c8cfd32 | |||
| 0566565254 | |||
| 5068a6ccef | |||
| c98cd8ccc8 | |||
| 21010ab799 | |||
| 91c036db6f | |||
| e3d9c87993 | |||
| 02afdd58e8 | |||
| 59d22708dc | |||
| 79bd60bff7 | |||
| 03667bad20 | |||
| d92b3f2abb | |||
| d798b75928 | |||
| 1e364a4f9a | |||
| f3732b7838 | |||
| 5d85b4a272 | |||
| 12bd0d77d1 | |||
| 01f6eaed9b | |||
| 87fa24daaf | |||
| db51a593bb | |||
| 3ba7f31c15 | |||
| 2666fb1069 | |||
| d3ca2c25e5 | |||
| 4b530e5af8 | |||
| e3bf98b8ed | |||
| c316d854e9 | |||
| ea72ffc95c | |||
| b0d81fce7b | |||
| 2fb82c256c | |||
| d62afa7ae7 | |||
| 2bf3ee078b | |||
| b0781430e4 | |||
| 87eb1e7205 | |||
| ff03600ad0 | |||
| 8d4f41b473 | |||
| ee5b530ae6 | |||
| 0853ab5730 | |||
| 23e8249b36 | |||
| 3876b68dd0 | |||
| 4935c347cf | |||
| cd1a80769f | |||
| 0f13016a50 | |||
| 141d8cbe64 | |||
| ec564a7b32 | |||
| 90528c757d | |||
| c76f2e8095 | |||
| 4999558ed4 | |||
| 0101cefdca | |||
| 0a39c68105 | |||
| 5f9afeb734 | |||
| a193f2a1e3 | |||
| 148d163013 | |||
| c8c11974f2 | |||
| ecc9069384 | |||
| 0960745ecb | |||
| c5437625e1 | |||
| 941b5cc782 | |||
| 02bcfb3631 | |||
| a02b319727 | |||
| 328f918372 | |||
| 2f980fec47 | |||
| ad5c8a8954 | |||
| ebe574ff58 | |||
| 1a89704b05 | |||
| f082899085 | |||
| 0fbdc6705a | |||
| f4da3acc61 | |||
| ef24084985 | |||
| 8b44b91c15 | |||
| bfdc0244a1 | |||
| f7ade2220a | |||
| 5aa0106bc1 | |||
| 2b4ff27983 | |||
| 78ade565c6 | |||
| e222b1ed8d | |||
| 9bfa3e8f56 | |||
| bed95cdef1 | |||
| 1c97c77cb9 | |||
| 0c73410e6c | |||
| ebe8a6726a | |||
| cb9494ddcc | |||
| 8ac0f287ee | |||
| 6fad97a975 | |||
| 07b75d56ed | |||
| d959768051 | |||
| 62566af752 | |||
| f910e87c12 | |||
| 8960fa5c1f | |||
| 5eb95aca21 | |||
| f417dab602 | |||
| 334e44fb2c | |||
| ccc7e00cc0 | |||
| c4e1a1518c | |||
| 12f7d66baf | |||
| 0d7ff46e11 | |||
| 91a59718cd | |||
| bd5f26b20b | |||
| 4ffedd3797 | |||
| c923621ec0 | |||
| efc45c2976 | |||
| 916c50484c | |||
| 191bcca9e2 | |||
| 4afc6a5711 | |||
| b32637b7e2 | |||
| 6d6322985d | |||
| a84e91d7f3 | |||
| 629741d93f | |||
| 727a0a97fe | |||
| 8340f83ddc | |||
| 8a3a133319 | |||
| e9822e8851 | |||
| 559a99c793 | |||
| bcdb7e3031 | |||
| 7f0d1164f5 | |||
| aa01e0e574 | |||
| 8070c74ebc | |||
| 93ade38caa | |||
| 39ef515a64 | |||
| 65462b439d | |||
| 481b001f25 | |||
| 3098122ac1 | |||
| f7a92e6a98 | |||
| 00906c109e | |||
| 177f92e74b | |||
| ae464fd7b2 | |||
| 909d02196f | |||
| 56d381cba3 | |||
| 49c2095b74 | |||
| 64b39b7f60 | |||
| b0e82e7359 | |||
| 520d73b0d6 | |||
| 56b3bec2ff | |||
| f87569ac6a | |||
| 7804b75021 | |||
| 571d588002 | |||
| c5fb5d69b1 | |||
| 54b4d6726b | |||
| af281ecdd6 | |||
| d92119979c | |||
| d6301a6dd3 | |||
| 2308148e23 | |||
| 41fc9f1937 | |||
| 96c24a1912 | |||
| f14bcafc5a | |||
| fdd756f779 | |||
| b198428e41 | |||
| b9cd69b372 | |||
| a5f09bca98 | |||
| 22124a36ca | |||
| 50794f5278 | |||
| 6d4e4bb8ef | |||
| e1cad3f07b | |||
| 2e4856a81f | |||
| 211f6809b9 | |||
| ad75599c7b | |||
| ca908dd42c | |||
| 76129617e5 | |||
| 56f92fa069 | |||
| d7815b0a79 | |||
| 376a2f64f2 | |||
| 634da01c65 | |||
| 8b0bb2389c | |||
| 83b311dcb3 | |||
| 79ec71c87b | |||
| 79a6ef4c9b | |||
| 299cdee4bf | |||
| 34b451dac4 | |||
| e2ac9903d9 | |||
| ee22b6faba | |||
| a6c6690e79 | |||
| acb0617d1b | |||
| 370c8c4a06 | |||
| 4782bf39af | |||
| 39f9832ce5 | |||
| ef0d79745f | |||
| e1b1217749 | |||
| 57886390a6 | |||
| 2a6ee587d3 | |||
| 43ab5e777d | |||
| 3f96ad977e | |||
| de068eb91a | |||
| e6539e7139 | |||
| 9a6c86b23f | |||
| ec2f7c0fe9 | |||
| 2077354356 | |||
| a3bce19260 | |||
| 08943d8121 | |||
| b053efae5d | |||
| 8bb3a1d295 | |||
| b3bd9df0fd | |||
| 1d5341843f | |||
| 5da74261d3 | |||
| ee3b7666f2 | |||
| 9c96a6fcf7 | |||
| 6ab4eaf7f2 | |||
| 46c4afbeaf | |||
| e0e75192e8 | |||
| c0078c08df | |||
| e2c4f9d374 | |||
| 1b26a3db64 | |||
| fa5aa45de4 | |||
| 9c9ac43919 | |||
| b214024bda | |||
| cd59d03500 | |||
| 0db181f9a9 | |||
| 868c037261 | |||
| a1714472d3 | |||
| 7883551c72 | |||
| bc11df440e | |||
| 4efaec0a53 | |||
| 0ded67ffd7 | |||
| 61923d3bdd | |||
| 035d608c59 | |||
| d49a5c7826 | |||
| 7305ed72ec | |||
| 7ab8ebf5b1 | |||
| c4b9758766 | |||
| 679d2d1129 | |||
| 5cad3e5d46 | |||
| 4faf9ff6c6 | |||
| 0a77242e3c | |||
| 1453ce1208 | |||
| 798dc31ada | |||
| 4a2a533fe1 | |||
| 61373c843d | |||
| 2937760c27 | |||
| 03989cb776 | |||
| a4f78b52f6 | |||
| ecc1bd1c73 | |||
| 694f33c2f6 | |||
| d93cdd955b | |||
| d80d0b4142 | |||
| b73ab4bf04 | |||
| a398df5381 | |||
| b0ff1a1600 | |||
| 98070f7020 | |||
| 40271e858d | |||
| f839aff2b5 | |||
| 0096c60d46 | |||
| 65424cea97 | |||
| 863b9081f5 | |||
| 44c178ec4f | |||
| e6e99db401 | |||
| 74c783924f | |||
| 0703eeca7c | |||
| 866f014372 | |||
| 22ad84cb00 | |||
| d56311006a | |||
| 30d4327769 | |||
| d987202dff | |||
| 25d288d297 | |||
| aa6b0c6d03 | |||
| 6f3819a805 | |||
| 2641b5e31e | |||
| 35db491a6d | |||
| 27deb31ded | |||
| 511e5c933a | |||
| 5574d3431b | |||
| ee8c5098c9 | |||
| 480396103b | |||
| 4e5ebf89ba | |||
| 015607040a | |||
| c58a1e9067 | |||
| eecc04f29c | |||
| f237e35755 | |||
| bee606d3b1 | |||
| 38b5816722 | |||
| 6e5e4cc208 | |||
| 4af9077f26 | |||
| 0b2c17a183 | |||
| 2a55bff8f6 | |||
| e235ef7bd9 | |||
| 47dd7dd840 | |||
| 70c75a7a47 | |||
| a7367b6cf3 | |||
| ae8dfad361 | |||
| a0bdd53e21 | |||
| c615b3e96b | |||
| e3475fd088 | |||
| e934a351e9 | |||
| 564753102d | |||
| 91916adde5 | |||
| 7af3ae4834 | |||
| fdfd266454 | |||
| f3e11eef99 | |||
| 94c5e0ade7 | |||
| 55929d8a49 | |||
| d0b1204d8e | |||
| 81a3d127b1 | |||
| 4f7eaa8b46 | |||
| 9b6a5a9b24 | |||
| c3c8dfeb51 | |||
| 07f8abfb30 | |||
| 54c6679153 | |||
| 089fbd15cc | |||
| 7132749e18 | |||
| 9ca2c8dc52 | |||
| f55a4c094e | |||
| 3a3a212405 | |||
| 0998cf8010 | |||
| 3766be85b2 | |||
| 83273d25b9 | |||
| b798b05411 | |||
| 7eb50a3753 | |||
| 4a4b4e28a4 | |||
| 42c31d53c8 | |||
| ea770fe8c8 | |||
| 434a580558 | |||
| 9a7a447722 | |||
| 1bf28ecb43 | |||
| 9c99a5da5c | |||
| 95008df6d9 | |||
| f499fa90f1 | |||
| 015b617739 | |||
| 423c1d6c50 | |||
| c4bee8e510 | |||
| 023ea98fc1 | |||
| f1e0128a43 | |||
| 167b85e60c | |||
| 4b6e850e68 | |||
| e48dd422f9 | |||
| dc8b92e0b2 | |||
| 840d6ba543 | |||
| 078699a1a5 | |||
| c0266bdaf6 | |||
| 46f7f67db1 | |||
| e8b50bbe34 | |||
| 33113481b5 | |||
| 8f11f7741a | |||
| b31ec4dfbf | |||
| 2b63da7763 | |||
| 24bc58278f | |||
| b59f56c259 | |||
| 29e40f3c13 | |||
| d2707c2d28 | |||
| 898befb275 | |||
| 938267b43a | |||
| f9f5f5ddc8 | |||
| ca66ad24c8 | |||
| e1f4756dfb | |||
| 12e04336a0 | |||
| 266aa66267 | |||
| af098adec2 | |||
| 202cfa2987 | |||
| bafa907941 | |||
| f5131809c8 | |||
| 37c30f2249 | |||
| 110a3639c3 | |||
| 7631b43d33 | |||
| a51f9bd003 | |||
| e998b14686 | |||
| 5ed8d694ee | |||
| f0782cc57b | |||
| 33b74df149 | |||
| 24e0b238d3 | |||
| dfddaa8ab6 | |||
| 57b83a4f41 | |||
| c9be953f05 | |||
| 794391b978 | |||
| a7df733250 | |||
| 15d5c9a276 | |||
| ec60f63f59 | |||
| a024a024e8 | |||
| 09304bcbff | |||
| 53ef327e54 | |||
| 685a71917b | |||
| 04288af505 | |||
| 4ac6149680 | |||
| 308046f1bc | |||
| d6c2bf620c | |||
| 8869cf8cd9 | |||
| b32974f12a | |||
| 48b3e4e9b2 | |||
| 4996f75a3b | |||
| bf2cecc440 | |||
| ec920f7901 | |||
| 1131af4409 | |||
| 46d8ffcefa | |||
| e2ea9b4c09 | |||
| 523efc4cd0 | |||
| 3f853115e9 | |||
| 8a8a02c903 | |||
| 946533c623 | |||
| 1f686d7fdf | |||
| 4e9e994da4 | |||
| 3ce4575dc0 | |||
| 88dfc54de9 | |||
| d855dcd29e | |||
| 5d4bf77a16 | |||
| fc00a6641c | |||
| cee73270c7 | |||
| 245de290f7 | |||
| 1a6160df3c | |||
| 2a3df3d55c | |||
| c227fc61f1 | |||
| 38a9ba9bcd | |||
| a4e309709d | |||
| e39f3b7db2 | |||
| 2a64720ac8 | |||
| cf0307a529 | |||
| c4758ab813 | |||
| d2c91281db | |||
| 9a88b8ec35 | |||
| 7a2beab44e | |||
| a586240cc0 | |||
| d2680dbb27 | |||
| c5b884bd51 | |||
| 5d5313537b | |||
| 5e6bc1b0f3 | |||
| 65d4f096db | |||
| cb69e26b15 | |||
| f25a7d2ac7 | |||
| de760475cf | |||
| a3824e559b | |||
| 67b64f85e9 | |||
| ac11f60853 | |||
| 09558248e8 | |||
| d186ba2f81 | |||
| 7ee550a943 | |||
| e260354fc9 | |||
| cd9c54c93c | |||
| 2cd4e5f8dc | |||
| 8978731b82 | |||
| 5c06a1935b | |||
| c04e89b086 | |||
| 4909257b07 | |||
| 695675483f | |||
| c3217a6b0d | |||
| 21527bf096 | |||
| 8178cf1bb9 | |||
| bc4f56abc3 | |||
| 0864ebc14c | |||
| 31354cc381 | |||
| 422a34a6f5 | |||
| d16540aa88 | |||
| d3a76147e0 | |||
| c48f2c90cc | |||
| 1f2cde345a | |||
| 171a83f79b | |||
| a137762fec | |||
| b52ceb2972 | |||
| 400239c7c5 | |||
| 159f904af5 | |||
| a01edef5be | |||
| cfa7d2653c |
+6
-8
@@ -4,6 +4,7 @@
|
||||
node_modules/
|
||||
vendor/
|
||||
admin/tool/policy/amd/src/jquery-eu-cookie-law-popup.js
|
||||
admin/tool/usertours/amd/src/tour.js
|
||||
auth/cas/CAS/
|
||||
cache/stores/mongodb/MongoDB/
|
||||
enrol/lti/ims-blti/
|
||||
@@ -19,12 +20,15 @@ lib/mlbackend/php/phpml/
|
||||
lib/adodb/
|
||||
lib/bennu/
|
||||
lib/evalmath/
|
||||
lib/phpspreadsheet/
|
||||
lib/lessphp/
|
||||
lib/phpexcel/
|
||||
lib/google/
|
||||
lib/htmlpurifier/
|
||||
lib/jabber/
|
||||
lib/minify/matthiasmullie-minify/
|
||||
lib/minify/matthiasmullie-pathconverter/
|
||||
lib/pear/Auth/RADIUS.php
|
||||
lib/pear/Crypt/CHAP.php
|
||||
lib/pear/HTML/Common.php
|
||||
lib/pear/HTML/QuickForm.php
|
||||
lib/pear/HTML/QuickForm/
|
||||
@@ -38,6 +42,7 @@ lib/yuilib/gallery/
|
||||
lib/jquery/
|
||||
lib/html2text/
|
||||
lib/markdown/
|
||||
lib/recaptchalib.php
|
||||
lib/xhprof/
|
||||
lib/horde/
|
||||
lib/requirejs/
|
||||
@@ -60,10 +65,6 @@ lib/validateurlsyntax.php
|
||||
lib/amd/src/popper.js
|
||||
lib/geopattern-php/
|
||||
lib/php-jwt/
|
||||
lib/babel-polyfill/
|
||||
lib/mdn-polyfills/
|
||||
lib/emoji-data/
|
||||
lib/h5p/
|
||||
media/player/videojs/amd/src/video-lazy.js
|
||||
media/player/videojs/amd/src/Youtube-lazy.js
|
||||
media/player/videojs/videojs/
|
||||
@@ -77,13 +78,10 @@ theme/boost/amd/src/button.js
|
||||
theme/boost/amd/src/carousel.js
|
||||
theme/boost/amd/src/collapse.js
|
||||
theme/boost/amd/src/dropdown.js
|
||||
theme/boost/amd/src/index.js
|
||||
theme/boost/amd/src/modal.js
|
||||
theme/boost/amd/src/popover.js
|
||||
theme/boost/amd/src/sanitizer.js
|
||||
theme/boost/amd/src/scrollspy.js
|
||||
theme/boost/amd/src/tab.js
|
||||
theme/boost/amd/src/toast.js
|
||||
theme/boost/amd/src/tooltip.js
|
||||
theme/boost/amd/src/util.js
|
||||
theme/boost/amd/src/tether.js
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
'plugins': [
|
||||
'babel',
|
||||
'promise',
|
||||
],
|
||||
'env': {
|
||||
@@ -204,45 +203,11 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ["**/amd/src/*.js", "**/amd/src/**/*.js", "Gruntfile*.js", "babel-plugin-add-module-to-define.js"],
|
||||
// We support es6 now. Woot!
|
||||
env: {
|
||||
es6: true
|
||||
},
|
||||
// We're using babel transpiling so use their parser
|
||||
// for linting.
|
||||
parser: 'babel-eslint',
|
||||
files: ["**/amd/src/*.js", "Gruntfile.js"],
|
||||
// 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'
|
||||
},
|
||||
parserOptions: {
|
||||
'ecmaVersion': 9,
|
||||
'sourceType': 'module'
|
||||
'no-implicit-globals': 'error'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
+6
-8
@@ -5,6 +5,7 @@ theme/classic/style/moodle.css
|
||||
node_modules/
|
||||
vendor/
|
||||
admin/tool/policy/amd/src/jquery-eu-cookie-law-popup.js
|
||||
admin/tool/usertours/amd/src/tour.js
|
||||
auth/cas/CAS/
|
||||
cache/stores/mongodb/MongoDB/
|
||||
enrol/lti/ims-blti/
|
||||
@@ -20,12 +21,15 @@ lib/mlbackend/php/phpml/
|
||||
lib/adodb/
|
||||
lib/bennu/
|
||||
lib/evalmath/
|
||||
lib/phpspreadsheet/
|
||||
lib/lessphp/
|
||||
lib/phpexcel/
|
||||
lib/google/
|
||||
lib/htmlpurifier/
|
||||
lib/jabber/
|
||||
lib/minify/matthiasmullie-minify/
|
||||
lib/minify/matthiasmullie-pathconverter/
|
||||
lib/pear/Auth/RADIUS.php
|
||||
lib/pear/Crypt/CHAP.php
|
||||
lib/pear/HTML/Common.php
|
||||
lib/pear/HTML/QuickForm.php
|
||||
lib/pear/HTML/QuickForm/
|
||||
@@ -39,6 +43,7 @@ lib/yuilib/gallery/
|
||||
lib/jquery/
|
||||
lib/html2text/
|
||||
lib/markdown/
|
||||
lib/recaptchalib.php
|
||||
lib/xhprof/
|
||||
lib/horde/
|
||||
lib/requirejs/
|
||||
@@ -61,10 +66,6 @@ lib/validateurlsyntax.php
|
||||
lib/amd/src/popper.js
|
||||
lib/geopattern-php/
|
||||
lib/php-jwt/
|
||||
lib/babel-polyfill/
|
||||
lib/mdn-polyfills/
|
||||
lib/emoji-data/
|
||||
lib/h5p/
|
||||
media/player/videojs/amd/src/video-lazy.js
|
||||
media/player/videojs/amd/src/Youtube-lazy.js
|
||||
media/player/videojs/videojs/
|
||||
@@ -78,13 +79,10 @@ theme/boost/amd/src/button.js
|
||||
theme/boost/amd/src/carousel.js
|
||||
theme/boost/amd/src/collapse.js
|
||||
theme/boost/amd/src/dropdown.js
|
||||
theme/boost/amd/src/index.js
|
||||
theme/boost/amd/src/modal.js
|
||||
theme/boost/amd/src/popover.js
|
||||
theme/boost/amd/src/sanitizer.js
|
||||
theme/boost/amd/src/scrollspy.js
|
||||
theme/boost/amd/src/tab.js
|
||||
theme/boost/amd/src/toast.js
|
||||
theme/boost/amd/src/tooltip.js
|
||||
theme/boost/amd/src/util.js
|
||||
theme/boost/amd/src/tether.js
|
||||
|
||||
+13
-28
@@ -2,23 +2,23 @@
|
||||
# process (which uses our internal CI system) this file is here for the benefit
|
||||
# of community developers git clones - see MDL-51458.
|
||||
|
||||
sudo: required
|
||||
|
||||
# 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
|
||||
|
||||
dist: xenial
|
||||
|
||||
services:
|
||||
- mysql
|
||||
- docker
|
||||
|
||||
php:
|
||||
# We only run the highest and lowest supported versions to reduce the load on travis-ci.org.
|
||||
- 7.4
|
||||
- 7.3
|
||||
- 7.1.30 # Make this sticky because current default version (7.1.11) has a bug with redis-extension output (MDL-66062)
|
||||
|
||||
addons:
|
||||
@@ -41,18 +41,18 @@ env:
|
||||
# Perform an upgrade test too.
|
||||
- DB=pgsql TASK=UPGRADE
|
||||
|
||||
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:
|
||||
# Run mysql only on highest - it's just too slow
|
||||
- php: 7.4
|
||||
# Run mysql only on 7.3 - it's just too slow
|
||||
- php: 7.3
|
||||
env: DB=mysqli TASK=PHPUNIT
|
||||
# Run grunt/npm install on highest version too ('node' is an alias for the latest node.js version.)
|
||||
- php: 7.4
|
||||
# Run grunt/npm install on highest version ('node' is an alias for the latest node.js version.)
|
||||
- php: 7.2
|
||||
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
|
||||
|
||||
cache:
|
||||
@@ -61,9 +61,8 @@ 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
|
||||
sudo service redis-server start --bind 127.0.0.1
|
||||
|
||||
install:
|
||||
- >
|
||||
@@ -170,12 +169,6 @@ before_script:
|
||||
-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');" \
|
||||
@@ -213,7 +206,7 @@ before_script:
|
||||
# We need the official upstream for comparison
|
||||
git remote add upstream https://github.com/moodle/moodle.git;
|
||||
|
||||
git fetch upstream MOODLE_38_STABLE;
|
||||
git fetch upstream MOODLE_37_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`
|
||||
@@ -291,11 +284,3 @@ script:
|
||||
exit 1 ;
|
||||
fi
|
||||
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
|
||||
|
||||
+39
-332
@@ -32,10 +32,7 @@ module.exports = function(grunt) {
|
||||
async = require('async'),
|
||||
DOMParser = require('xmldom').DOMParser,
|
||||
xpath = require('xpath'),
|
||||
semver = require('semver'),
|
||||
watchman = require('fb-watchman'),
|
||||
watchmanClient = new watchman.Client(),
|
||||
gruntFilePath = process.cwd();
|
||||
semver = require('semver');
|
||||
|
||||
// Verify the node version is new enough.
|
||||
var expected = semver.validRange(grunt.file.readJSON('package.json').engines.node);
|
||||
@@ -56,23 +53,10 @@ module.exports = function(grunt) {
|
||||
}
|
||||
}
|
||||
|
||||
var files = null;
|
||||
if (grunt.option('files')) {
|
||||
// Accept a comma separated list of files to process.
|
||||
files = grunt.option('files').split(',');
|
||||
}
|
||||
|
||||
var inAMD = path.basename(cwd) == 'amd';
|
||||
|
||||
// Globbing pattern for matching all AMD JS source files.
|
||||
var amdSrc = [];
|
||||
if (inAMD) {
|
||||
amdSrc.push(cwd + "/src/*.js");
|
||||
amdSrc.push(cwd + "/src/**/*.js");
|
||||
} else {
|
||||
amdSrc.push("**/amd/src/*.js");
|
||||
amdSrc.push("**/amd/src/**/*.js");
|
||||
}
|
||||
var amdSrc = [inAMD ? cwd + '/src/*.js' : '**/amd/src/*.js'];
|
||||
|
||||
/**
|
||||
* Function to generate the destination for the uglify task
|
||||
@@ -84,9 +68,10 @@ module.exports = function(grunt) {
|
||||
* @param {String} srcPath the matched src path
|
||||
* @return {String} The rewritten destination path.
|
||||
*/
|
||||
var babelRename = function(destPath, srcPath) {
|
||||
var uglifyRename = function(destPath, srcPath) {
|
||||
destPath = srcPath.replace('src', 'build');
|
||||
destPath = destPath.replace('.js', '.min.js');
|
||||
destPath = path.resolve(cwd, destPath);
|
||||
return destPath;
|
||||
};
|
||||
|
||||
@@ -127,65 +112,19 @@ module.exports = function(grunt) {
|
||||
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)
|
||||
},
|
||||
amd: {src: files ? files : amdSrc},
|
||||
options: {quiet: !grunt.option('show-lint-warnings')},
|
||||
amd: {src: amdSrc},
|
||||
// Check YUI module source files.
|
||||
yui: {src: files ? files : ['**/yui/src/**/*.js', '!*/**/yui/src/*/meta/*.js']}
|
||||
yui: {src: ['**/yui/src/**/*.js', '!*/**/yui/src/*/meta/*.js']}
|
||||
},
|
||||
babel: {
|
||||
options: {
|
||||
sourceMaps: true,
|
||||
comments: false,
|
||||
plugins: [
|
||||
'transform-es2015-modules-amd-lazy',
|
||||
'system-import-transformer',
|
||||
// This plugin modifies the Babel transpiling for "export default"
|
||||
// so that if it's used then only the exported value is returned
|
||||
// by the generated AMD module.
|
||||
//
|
||||
// It also adds the Moodle plugin name to the AMD module definition
|
||||
// so that it can be imported as expected in other modules.
|
||||
path.resolve('babel-plugin-add-module-to-define.js'),
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
'@babel/plugin-syntax-import-meta',
|
||||
['@babel/plugin-proposal-class-properties', {'loose': false}],
|
||||
'@babel/plugin-proposal-json-strings'
|
||||
],
|
||||
presets: [
|
||||
['minify', {
|
||||
// This minification plugin needs to be disabled because it breaks the
|
||||
// source map generation and causes invalid source maps to be output.
|
||||
simplify: false,
|
||||
builtIns: false
|
||||
}],
|
||||
['@babel/preset-env', {
|
||||
targets: {
|
||||
browsers: [
|
||||
">0.25%",
|
||||
"last 2 versions",
|
||||
"not ie <= 10",
|
||||
"not op_mini all",
|
||||
"not Opera > 0",
|
||||
"not dead"
|
||||
]
|
||||
},
|
||||
modules: false,
|
||||
useBuiltIns: false
|
||||
}]
|
||||
]
|
||||
},
|
||||
dist: {
|
||||
uglify: {
|
||||
amd: {
|
||||
files: [{
|
||||
expand: true,
|
||||
src: files ? files : amdSrc,
|
||||
rename: babelRename
|
||||
}]
|
||||
src: amdSrc,
|
||||
rename: uglifyRename
|
||||
}],
|
||||
options: {report: 'none'}
|
||||
}
|
||||
},
|
||||
sass: {
|
||||
@@ -207,14 +146,6 @@ module.exports = function(grunt) {
|
||||
files: ['**/amd/src/**/*.js'],
|
||||
tasks: ['amd']
|
||||
},
|
||||
boost: {
|
||||
files: ['**/theme/boost/scss/**/*.scss'],
|
||||
tasks: ['scss']
|
||||
},
|
||||
rawcss: {
|
||||
files: ['**/*.css', '**/theme/**/!(moodle.css|editor.css)'],
|
||||
tasks: ['rawcss']
|
||||
},
|
||||
yui: {
|
||||
files: ['**/yui/src/**/*.js'],
|
||||
tasks: ['yui']
|
||||
@@ -227,21 +158,21 @@ module.exports = function(grunt) {
|
||||
shifter: {
|
||||
options: {
|
||||
recursive: true,
|
||||
paths: files ? files : [cwd]
|
||||
paths: [cwd]
|
||||
}
|
||||
},
|
||||
gherkinlint: {
|
||||
options: {
|
||||
files: files ? files : ['**/tests/behat/*.feature'],
|
||||
files: ['**/tests/behat/*.feature'],
|
||||
}
|
||||
},
|
||||
stylelint: {
|
||||
scss: {
|
||||
options: {syntax: 'scss'},
|
||||
src: files ? files : ['*/**/*.scss']
|
||||
src: ['*/**/*.scss']
|
||||
},
|
||||
css: {
|
||||
src: files ? files : ['*/**/*.css'],
|
||||
src: ['*/**/*.css'],
|
||||
options: {
|
||||
configOverrides: {
|
||||
rules: {
|
||||
@@ -362,27 +293,19 @@ module.exports = function(grunt) {
|
||||
};
|
||||
|
||||
tasks.gherkinlint = function() {
|
||||
const done = this.async();
|
||||
const options = grunt.config('gherkinlint.options');
|
||||
var done = this.async(),
|
||||
options = grunt.config('gherkinlint.options');
|
||||
|
||||
// Grab the gherkin-lint linter and required scaffolding.
|
||||
const linter = require('gherkin-lint/src/linter.js');
|
||||
const featureFinder = require('gherkin-lint/src/feature-finder.js');
|
||||
const configParser = require('gherkin-lint/src/config-parser.js');
|
||||
const formatter = require('gherkin-lint/src/formatters/stylish.js');
|
||||
|
||||
// Run the linter.
|
||||
const results = linter.lint(
|
||||
featureFinder.getFeatureFiles(grunt.file.expand(options.files)),
|
||||
configParser.getConfiguration(configParser.defaultConfigFileName)
|
||||
);
|
||||
|
||||
// Print the results out uncondtionally.
|
||||
formatter.printResults(results);
|
||||
|
||||
// Report on the results.
|
||||
// The done function takes a bool whereby a falsey statement causes the task to fail.
|
||||
done(results.every(result => result.errors.length === 0));
|
||||
var args = grunt.file.expand(options.files);
|
||||
args.unshift(path.normalize(__dirname + '/node_modules/.bin/gherkin-lint'));
|
||||
grunt.util.spawn({
|
||||
cmd: 'node',
|
||||
args: args,
|
||||
opts: {stdio: 'inherit', env: process.env}
|
||||
}, function(error, result, code) {
|
||||
// Propagate the exit code.
|
||||
done(code === 0);
|
||||
});
|
||||
};
|
||||
|
||||
tasks.startup = function() {
|
||||
@@ -400,232 +323,23 @@ module.exports = function(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.
|
||||
*/
|
||||
tasks.watch = function() {
|
||||
var watchTaskDone = this.async();
|
||||
var watchInitialised = false;
|
||||
var watchTaskQueue = {};
|
||||
var processingQueue = false;
|
||||
|
||||
// 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: cwd,
|
||||
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();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
var watchConfig = grunt.config.get(['watch']);
|
||||
watchConfig = Object.keys(watchConfig).reduce(function(carry, key) {
|
||||
if (key == 'options') {
|
||||
return carry;
|
||||
}
|
||||
|
||||
var value = watchConfig[key];
|
||||
var fileGlobs = value.files;
|
||||
var taskNames = value.tasks;
|
||||
|
||||
taskNames.forEach(function(taskName) {
|
||||
carry[taskName] = fileGlobs;
|
||||
});
|
||||
|
||||
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 = cwd + '/' + file.name;
|
||||
Object.keys(watchConfig).forEach(function(task) {
|
||||
var fileGlobs = watchConfig[task];
|
||||
var match = fileGlobs.every(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(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', cwd], 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;
|
||||
}
|
||||
|
||||
// Use the matching patterns specified in the watch config.
|
||||
var matches = Object.keys(watchConfig).map(function(task) {
|
||||
var fileGlobs = watchConfig[task];
|
||||
var fileGlobMatches = fileGlobs.map(function(fileGlob) {
|
||||
return ['match', fileGlob, 'wholename'];
|
||||
});
|
||||
|
||||
return ['allof'].concat(fileGlobMatches);
|
||||
});
|
||||
|
||||
var sub = {
|
||||
expression: ["anyof"].concat(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 ' + cwd);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 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('eslint.amd.src', files);
|
||||
grunt.config('eslint.yui.src', files);
|
||||
grunt.config('shifter.options.paths', files);
|
||||
grunt.config('gherkinlint.options.files', files);
|
||||
grunt.config('babel.dist.files', [{expand: true, src: files, rename: babelRename}]);
|
||||
changedFiles = Object.create(null);
|
||||
var files = Object.keys(changedFiles);
|
||||
grunt.config('eslint.amd.src', files);
|
||||
grunt.config('eslint.yui.src', files);
|
||||
grunt.config('uglify.amd.files', [{expand: true, src: files, rename: uglifyRename}]);
|
||||
grunt.config('shifter.options.paths', files);
|
||||
grunt.config('gherkinlint.options.files', files);
|
||||
changedFiles = Object.create(null);
|
||||
}, 200);
|
||||
|
||||
grunt.event.on('watch', function(action, filepath) {
|
||||
changedFiles[filepath] = action;
|
||||
onChange();
|
||||
changedFiles[filepath] = action;
|
||||
onChange();
|
||||
});
|
||||
|
||||
// Register NPM tasks.
|
||||
@@ -634,24 +348,17 @@ module.exports = function(grunt) {
|
||||
grunt.loadNpmTasks('grunt-sass');
|
||||
grunt.loadNpmTasks('grunt-eslint');
|
||||
grunt.loadNpmTasks('grunt-stylelint');
|
||||
grunt.loadNpmTasks('grunt-babel');
|
||||
|
||||
// Rename the grunt-contrib-watch "watch" task because we're going to wrap it.
|
||||
grunt.renameTask('watch', 'watch-grunt');
|
||||
|
||||
// Register JS tasks.
|
||||
grunt.registerTask('shifter', 'Run Shifter against the current directory', tasks.shifter);
|
||||
grunt.registerTask('gherkinlint', 'Run gherkinlint against the current directory', tasks.gherkinlint);
|
||||
grunt.registerTask('ignorefiles', 'Generate ignore files for linters', tasks.ignorefiles);
|
||||
grunt.registerTask('watch', 'Run tasks on file changes', tasks.watch);
|
||||
grunt.registerTask('yui', ['eslint:yui', 'shifter']);
|
||||
grunt.registerTask('amd', ['eslint:amd', 'babel']);
|
||||
grunt.registerTask('amd', ['eslint:amd', 'uglify']);
|
||||
grunt.registerTask('js', ['amd', 'yui']);
|
||||
|
||||
// Register CSS taks.
|
||||
grunt.registerTask('css', ['stylelint:scss', 'sass', 'stylelint:css']);
|
||||
grunt.registerTask('scss', ['stylelint:scss', 'sass']);
|
||||
grunt.registerTask('rawcss', ['stylelint:css']);
|
||||
|
||||
// Register the startup task.
|
||||
grunt.registerTask('startup', 'Run the correct tasks for the current directory', tasks.startup);
|
||||
|
||||
@@ -33,7 +33,8 @@ $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();
|
||||
require_login();
|
||||
require_capability('moodle/site:config', context_system::instance());
|
||||
|
||||
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=manageantiviruses";
|
||||
|
||||
|
||||
+2
-1
@@ -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'));
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -50,7 +50,6 @@ class purge_caches extends \moodleform {
|
||||
$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'))
|
||||
|
||||
@@ -1,195 +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;
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
$bytes = $data['v'] * $data['u'];
|
||||
|
||||
$result = $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);
|
||||
}
|
||||
}
|
||||
@@ -131,8 +131,7 @@ class task_log_table extends \table_sql {
|
||||
}
|
||||
|
||||
$sql = "SELECT
|
||||
tl.id, tl.type, tl.component, tl.classname, tl.userid, tl.timestart, tl.timeend,
|
||||
tl.dbreads, tl.dbwrites, tl.result,
|
||||
tl.*,
|
||||
tl.dbreads + tl.dbwrites AS db,
|
||||
tl.timeend - tl.timestart AS duration,
|
||||
{$userfields}
|
||||
|
||||
+98
-106
@@ -266,7 +266,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);
|
||||
@@ -392,6 +391,7 @@ if ($interactive) {
|
||||
$CFG->wwwroot = $wwwroot;
|
||||
$CFG->httpswwwroot = $CFG->wwwroot;
|
||||
|
||||
|
||||
//We need dataroot before lang download
|
||||
$CFG->dataroot = $options['dataroot'];
|
||||
if ($interactive) {
|
||||
@@ -638,100 +638,96 @@ do {
|
||||
}
|
||||
} 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, $options['adminemail']);
|
||||
}
|
||||
|
||||
// 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();
|
||||
@@ -750,27 +746,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
|
||||
@@ -818,7 +810,7 @@ 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.
|
||||
|
||||
@@ -94,7 +94,7 @@ if ($options['password'] == '' ) {
|
||||
|
||||
$errmsg = '';//prevent eclipse warning
|
||||
if (!$options['ignore-password-policy'] ) {
|
||||
if (!check_password_policy($password, $errmsg, $user)) {
|
||||
if (!check_password_policy($password, $errmsg)) {
|
||||
cli_error(html_to_text($errmsg, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ $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
|
||||
@@ -45,9 +44,6 @@ 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.
|
||||
|
||||
@@ -67,7 +63,6 @@ Examples:
|
||||
list($options, $unrecognised) = cli_get_params([
|
||||
'help' => false,
|
||||
'show-all' => false,
|
||||
'show-contrib' => false,
|
||||
'show-missing' => false,
|
||||
'purge-missing' => false,
|
||||
'plugins' => false,
|
||||
@@ -89,15 +84,12 @@ if ($options['help']) {
|
||||
$pluginman = core_plugin_manager::instance();
|
||||
$plugininfo = $pluginman->get_plugins();
|
||||
|
||||
if ($options['show-all'] || $options['show-missing'] || $options['show-contrib']) {
|
||||
if ($options['show-all'] || $options['show-missing']) {
|
||||
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']) {
|
||||
if ($options['show-all']) {
|
||||
cli_writeln($pluginstring);
|
||||
} else {
|
||||
if ($plugin->get_status() === core_plugin_manager::PLUGIN_STATUS_MISSING) {
|
||||
|
||||
@@ -52,8 +52,7 @@ list($options, $unrecognized) = cli_get_params(
|
||||
'allow-unstable' => false,
|
||||
'help' => false,
|
||||
'lang' => $lang,
|
||||
'verbose-settings' => false,
|
||||
'is-pending' => false,
|
||||
'verbose-settings' => false
|
||||
),
|
||||
array(
|
||||
'h' => 'help'
|
||||
@@ -89,8 +88,6 @@ Options:
|
||||
--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 +116,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) {
|
||||
|
||||
@@ -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'));
|
||||
|
||||
@@ -32,7 +32,8 @@ $syscontext = context_system::instance();
|
||||
$PAGE->set_url('/admin/customfields.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' => 'managecustomfields'));
|
||||
|
||||
@@ -33,7 +33,8 @@ $syscontext = context_system::instance();
|
||||
$PAGE->set_url('/admin/dataformats.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' => 'managedataformats'));
|
||||
|
||||
+2
-1
@@ -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";
|
||||
|
||||
|
||||
+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);
|
||||
|
||||
@@ -2982,366 +2982,4 @@
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
<MOODLE version="3.9" requires="3.5">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mariadb" version="10.2.29" />
|
||||
<VENDOR name="mysql" version="5.6" />
|
||||
<VENDOR name="postgres" version="9.5" />
|
||||
<VENDOR name="mssql" version="11.0" />
|
||||
<VENDOR name="oracle" version="11.2" />
|
||||
</DATABASE>
|
||||
<PHP version="7.2.0" level="required">
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="pcreunicodewarning" />
|
||||
</FEEDBACK>
|
||||
</PCREUNICODE>
|
||||
<PHP_EXTENSIONS>
|
||||
<PHP_EXTENSION name="iconv" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="iconvrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="mbstring" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="mbstringrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="curl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="curlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="openssl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="opensslrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="tokenizer" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="tokenizerrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xmlrpc" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="xmlrpcrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="soap" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="soaprecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="ctype" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ctyperequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zip" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ziprequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zlib" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="gd" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="gdrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="simplexml" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="simplexmlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="spl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="splrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="pcre" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="dom" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xml" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xmlreader" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="intl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="intlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="json" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="hash" level="required"/>
|
||||
<PHP_EXTENSION name="fileinfo" level="required"/>
|
||||
</PHP_EXTENSIONS>
|
||||
<PHP_SETTINGS>
|
||||
<PHP_SETTING name="memory_limit" value="96M" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="settingmemorylimit" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="file_uploads" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingfileuploads" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="opcache.enable" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="opcacherecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
<CUSTOM_CHECKS>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbstorageengine" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="quizattemptsupgradedmessage" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="slashargumentswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="unsupporteddbtablerowformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_unoconv_version" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="unoconvwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="libcurlwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfileformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfilepertable" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddblargeprefix" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_is_https" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="ishttpswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_incomplete_unicode_support" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="incompleteunicodesupport" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_sixtyfour_bits" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="sixtyfourbitswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
<MOODLE version="3.10" requires="3.5">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mariadb" version="10.2.29" />
|
||||
<VENDOR name="mysql" version="5.7" />
|
||||
<VENDOR name="postgres" version="9.6" />
|
||||
<VENDOR name="mssql" version="11.0" />
|
||||
<VENDOR name="oracle" version="11.2" />
|
||||
</DATABASE>
|
||||
<PHP version="7.2.0" level="required">
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="pcreunicodewarning" />
|
||||
</FEEDBACK>
|
||||
</PCREUNICODE>
|
||||
<PHP_EXTENSIONS>
|
||||
<PHP_EXTENSION name="iconv" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="iconvrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="mbstring" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="mbstringrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="curl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="curlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="openssl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="opensslrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="tokenizer" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="tokenizerrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xmlrpc" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="xmlrpcrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="soap" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="soaprecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="ctype" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ctyperequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zip" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="ziprequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="zlib" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="gd" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="gdrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="simplexml" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="simplexmlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="spl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="splrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="pcre" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="dom" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xml" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="xmlreader" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="intl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="intlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="json" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="hash" level="required"/>
|
||||
<PHP_EXTENSION name="fileinfo" level="required"/>
|
||||
</PHP_EXTENSIONS>
|
||||
<PHP_SETTINGS>
|
||||
<PHP_SETTING name="memory_limit" value="96M" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="settingmemorylimit" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="file_uploads" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingfileuploads" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="opcache.enable" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="opcacherecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
<CUSTOM_CHECKS>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_storage_engine" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbstorageengine" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="question/engine/upgrade/upgradelib.php" function="quiz_attempts_upgraded" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="quizattemptsupgradedmessage" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_slasharguments" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="slashargumentswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_database_tables_row_format" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="unsupporteddbtablerowformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_unoconv_version" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="unoconvwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_libcurl_version" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="libcurlwarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_format" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfileformat" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_file_per_table" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddbfilepertable" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_large_prefix" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unsupporteddblargeprefix" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_is_https" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="ishttpswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_mysql_incomplete_unicode_support" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="incompleteunicodesupport" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/upgradelib.php" function="check_sixtyfour_bits" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="sixtyfourbitswarning" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
</COMPATIBILITY_MATRIX>
|
||||
|
||||
+10
-29
@@ -226,7 +226,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,7 +235,7 @@ 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();
|
||||
}
|
||||
|
||||
@@ -358,9 +358,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 +368,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)) {
|
||||
@@ -509,8 +509,7 @@ if (!$cache and $version > $CFG->version) { // upgrade
|
||||
// Always verify plugin dependencies!
|
||||
$failed = array();
|
||||
if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
|
||||
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);
|
||||
@@ -534,10 +533,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 +543,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);
|
||||
@@ -702,8 +684,7 @@ if (!$cache and moodle_needs_upgrading()) {
|
||||
$failed = array();
|
||||
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);
|
||||
@@ -821,7 +802,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');
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -23,7 +23,8 @@ require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/licenselib.php');
|
||||
|
||||
require_admin();
|
||||
require_login();
|
||||
require_capability('moodle/site:config', context_system::instance());
|
||||
|
||||
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=managelicenses";
|
||||
|
||||
|
||||
+2
-1
@@ -35,7 +35,8 @@ $confirm = optional_param('confirm', 0, PARAM_BOOL);
|
||||
$PAGE->set_url('/admin/media.php');
|
||||
$PAGE->set_context(context_system::instance());
|
||||
|
||||
require_admin();
|
||||
require_login();
|
||||
require_capability('moodle/site:config', context_system::instance());
|
||||
require_sesskey();
|
||||
|
||||
$plugins = core_plugin_manager::instance()->get_plugins_of_type('media');
|
||||
|
||||
+11
-31
@@ -33,17 +33,13 @@ $allprocessors = get_message_processors();
|
||||
$processors = array_filter($allprocessors, function($processor) {
|
||||
return $processor->enabled;
|
||||
});
|
||||
$disabledprocessors = array_filter($allprocessors, function($processor) {
|
||||
return !$processor->enabled;
|
||||
});
|
||||
|
||||
// Fetch message providers.
|
||||
$providers = get_message_providers();
|
||||
// Fetch the manage message outputs interface.
|
||||
$preferences = get_message_output_default_preferences();
|
||||
|
||||
if (($form = data_submitted()) && confirm_sesskey()) {
|
||||
$newpreferences = array();
|
||||
$preferences = array();
|
||||
// Prepare default message outputs settings.
|
||||
foreach ($providers as $provider) {
|
||||
$componentproviderbase = $provider->component.'_'.$provider->name;
|
||||
@@ -51,9 +47,9 @@ if (($form = data_submitted()) && confirm_sesskey()) {
|
||||
$providerdisabled = false;
|
||||
if (!isset($form->$disableprovidersetting)) {
|
||||
$providerdisabled = true;
|
||||
$newpreferences[$disableprovidersetting] = 1;
|
||||
$preferences[$disableprovidersetting] = 1;
|
||||
} else {
|
||||
$newpreferences[$disableprovidersetting] = 0;
|
||||
$preferences[$disableprovidersetting] = 0;
|
||||
}
|
||||
|
||||
foreach (array('permitted', 'loggedin', 'loggedoff') as $setting) {
|
||||
@@ -79,36 +75,20 @@ if (($form = data_submitted()) && confirm_sesskey()) {
|
||||
$form->{$componentproviderbase.'_loggedoff'}[$processor->name] = 1;
|
||||
}
|
||||
// Record the site preference.
|
||||
$newpreferences[$processor->name.'_provider_'.$componentprovidersetting] = $value;
|
||||
$preferences[$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);
|
||||
} else if (array_key_exists($componentprovidersetting, $form)) {
|
||||
// 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.
|
||||
$value = join(',', array_keys(array_filter($form->{$componentprovidersetting})));
|
||||
if (empty($value)) {
|
||||
$value = null;
|
||||
}
|
||||
}
|
||||
if ($setting != 'permitted') {
|
||||
// We have already recoded site preferences for 'permitted' type.
|
||||
$newpreferences['message_provider_'.$componentprovidersetting] = $value;
|
||||
$preferences['message_provider_'.$componentprovidersetting] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,7 +102,7 @@ if (($form = data_submitted()) && confirm_sesskey()) {
|
||||
\core_message\api::update_processor_status($processor, $enabled);
|
||||
}
|
||||
|
||||
foreach ($newpreferences as $name => $value) {
|
||||
foreach ($preferences as $name => $value) {
|
||||
set_config($name, $value, 'message');
|
||||
}
|
||||
$transaction->allow_commit();
|
||||
|
||||
@@ -34,6 +34,9 @@ $step = optional_param('step', 'verify', PARAM_ALPHA);
|
||||
$hostid = required_param('hostid', PARAM_INT);
|
||||
|
||||
|
||||
|
||||
$context = context_system::instance();
|
||||
|
||||
$mnet = get_mnet_environment();
|
||||
|
||||
$PAGE->set_url('/admin/mnet/delete.php');
|
||||
|
||||
+2
-4
@@ -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();
|
||||
@@ -123,8 +121,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 {
|
||||
|
||||
+3
-2
@@ -43,8 +43,9 @@ $confirminstallupdate = optional_param('confirminstallupdate', false, PARAM_BOOL
|
||||
// NOTE: do not use admin_externalpage_setup() here because it loads
|
||||
// full admin tree which is not possible during uninstallation.
|
||||
|
||||
require_admin();
|
||||
require_login();
|
||||
$syscontext = context_system::instance();
|
||||
require_capability('moodle/site:config', $syscontext);
|
||||
|
||||
// URL params we want to maintain on redirects.
|
||||
$pageparams = array('updatesonly' => $updatesonly, 'contribonly' => $contribonly);
|
||||
@@ -53,6 +54,7 @@ $pageurl = new moodle_url('/admin/plugins.php', $pageparams);
|
||||
$pluginman = core_plugin_manager::instance();
|
||||
|
||||
if ($uninstall) {
|
||||
require_sesskey();
|
||||
|
||||
if (!$confirmed) {
|
||||
admin_externalpage_setup('pluginsoverview', '', $pageparams);
|
||||
@@ -91,7 +93,6 @@ if ($uninstall) {
|
||||
exit();
|
||||
|
||||
} else {
|
||||
require_sesskey();
|
||||
$SESSION->pluginuninstallreturn = $pluginfo->get_return_url_after_uninstall($return);
|
||||
$progress = new progress_trace_buffer(new text_progress_trace(), false);
|
||||
$pluginman->uninstall_plugin($pluginfo->component, $progress);
|
||||
|
||||
@@ -31,7 +31,7 @@ require_once($CFG->libdir . '/adminlib.php');
|
||||
require_once($CFG->libdir . '/tablelib.php');
|
||||
|
||||
// Check permissions.
|
||||
require_login(null, false);
|
||||
require_login();
|
||||
$systemcontext = context_system::instance();
|
||||
require_capability('moodle/question:config', $systemcontext);
|
||||
|
||||
|
||||
+2
-2
@@ -30,12 +30,12 @@ require_once($CFG->libdir . '/questionlib.php');
|
||||
require_once($CFG->libdir . '/adminlib.php');
|
||||
require_once($CFG->libdir . '/tablelib.php');
|
||||
|
||||
admin_externalpage_setup('manageqtypes');
|
||||
|
||||
// Check permissions.
|
||||
$systemcontext = context_system::instance();
|
||||
require_capability('moodle/question:config', $systemcontext);
|
||||
$canviewreports = has_capability('report/questioninstances:view', $systemcontext);
|
||||
|
||||
admin_externalpage_setup('manageqtypes');
|
||||
$thispageurl = new moodle_url('/admin/qtypes.php');
|
||||
|
||||
$qtypes = question_bank::get_all_qtypes();
|
||||
|
||||
@@ -45,7 +45,7 @@ $error = optional_param('error', '', PARAM_ALPHANUM);
|
||||
|
||||
admin_externalpage_setup('registrationmoodleorg');
|
||||
|
||||
if (parse_url($url, PHP_URL_HOST) !== parse_url(HUB_MOODLEORGHUBURL, PHP_URL_HOST)) {
|
||||
if ($url !== HUB_MOODLEORGHUBURL) {
|
||||
// Allow other plugins to confirm registration on custom hubs. Plugins implementing this
|
||||
// callback need to redirect or exit. See https://docs.moodle.org/en/Hub_registration .
|
||||
$callbacks = get_plugins_with_function('hub_registration');
|
||||
|
||||
@@ -32,25 +32,24 @@ require_once($CFG->libdir . '/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('registrationmoodleorg');
|
||||
|
||||
$unregistration = optional_param('unregistration', false, PARAM_BOOL);
|
||||
$confirm = optional_param('confirm', false, PARAM_BOOL);
|
||||
$unregistration = optional_param('unregistration', 0, PARAM_INT);
|
||||
|
||||
if ($unregistration && \core\hub\registration::is_registered()) {
|
||||
if ($confirm) {
|
||||
require_sesskey();
|
||||
\core\hub\registration::unregister(false, false);
|
||||
$siteunregistrationform = new \core\hub\site_unregistration_form();
|
||||
|
||||
if ($siteunregistrationform->is_cancelled()) {
|
||||
redirect(new moodle_url('/admin/registration/index.php'));
|
||||
} else if ($data = $siteunregistrationform->get_data()) {
|
||||
\core\hub\registration::unregister($data->unpublishalladvertisedcourses,
|
||||
$data->unpublishalluploadedcourses);
|
||||
if (!\core\hub\registration::is_registered()) {
|
||||
redirect(new moodle_url('/admin/registration/index.php'));
|
||||
}
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->confirm(
|
||||
get_string('registerwithmoodleorgremove', 'core_hub'),
|
||||
new moodle_url(new moodle_url('/admin/registration/index.php', ['unregistration' => 1, 'confirm' => 1])),
|
||||
new moodle_url(new moodle_url('/admin/registration/index.php'))
|
||||
);
|
||||
echo $OUTPUT->heading(get_string('registerwithmoodleorgremove', 'core_hub'), 3, 'main');
|
||||
$siteunregistrationform->display();
|
||||
echo $OUTPUT->footer();
|
||||
exit;
|
||||
}
|
||||
@@ -120,9 +119,8 @@ $siteregistrationform->display();
|
||||
if (\core\hub\registration::is_registered()) {
|
||||
// Unregister link.
|
||||
$unregisterhuburl = new moodle_url("/admin/registration/index.php", ['unregistration' => 1]);
|
||||
echo html_writer::div(html_writer::link($unregisterhuburl, get_string('unregister', 'hub')), 'unregister mt-2');
|
||||
echo html_writer::div(html_writer::link($unregisterhuburl, get_string('unregister', 'hub')), 'unregister');
|
||||
} else if ($isinitialregistration) {
|
||||
echo html_writer::div(html_writer::link(new moodle_url($returnurl), get_string('skipregistration', 'hub')),
|
||||
'skipregistration mt-2');
|
||||
echo html_writer::div(html_writer::link(new moodle_url($returnurl), get_string('skipregistration', 'hub')), 'skipregistration');
|
||||
}
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
@@ -39,7 +39,7 @@ $token = optional_param('token', '', PARAM_TEXT);
|
||||
|
||||
admin_externalpage_setup('registrationmoodleorg');
|
||||
|
||||
if (parse_url($url, PHP_URL_HOST) !== parse_url(HUB_MOODLEORGHUBURL, PHP_URL_HOST)) {
|
||||
if ($url !== HUB_MOODLEORGHUBURL) {
|
||||
// Allow other plugins to renew registration on custom hubs. Plugins implementing this
|
||||
// callback need to redirect or exit. See https://docs.moodle.org/en/Hub_registration .
|
||||
$callbacks = get_plugins_with_function('hub_registration');
|
||||
|
||||
+44
-53
@@ -361,15 +361,14 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$output = '';
|
||||
|
||||
if ($checker->enabled()) {
|
||||
$output .= $this->container_start('checkforupdates mb-4');
|
||||
$output .= $this->container_start('checkforupdates');
|
||||
$output .= $this->single_button(
|
||||
new moodle_url($reloadurl, array('fetchupdates' => 1)),
|
||||
get_string('checkforupdates', 'core_plugin')
|
||||
);
|
||||
if ($timefetched = $checker->get_last_timefetched()) {
|
||||
$timefetched = userdate($timefetched, get_string('strftimedatetime', 'core_langconfig'));
|
||||
$output .= $this->container(get_string('checkforupdateslast', 'core_plugin', $timefetched),
|
||||
'lasttimefetched small text-muted mt-1');
|
||||
$output .= $this->container(get_string('checkforupdateslast', 'core_plugin', $timefetched), 'lasttimefetched');
|
||||
}
|
||||
$output .= $this->container_end();
|
||||
}
|
||||
@@ -824,7 +823,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
}
|
||||
|
||||
$updateinfo .= $this->container_start('checkforupdates mt-1');
|
||||
$updateinfo .= $this->container_start('checkforupdates');
|
||||
$fetchurl = new moodle_url('/admin/index.php', array('fetchupdates' => 1, 'sesskey' => sesskey(), 'cache' => 0));
|
||||
$updateinfo .= $this->single_button($fetchurl, get_string('checkforupdates', 'core_plugin'));
|
||||
if ($fetch) {
|
||||
@@ -913,7 +912,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
*/
|
||||
protected function moodle_available_update_info(\core\update\info $updateinfo) {
|
||||
|
||||
$boxclasses = 'moodleupdateinfo mb-2';
|
||||
$boxclasses = 'moodleupdateinfo';
|
||||
$info = array();
|
||||
|
||||
if (isset($updateinfo->release)) {
|
||||
@@ -933,8 +932,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
|
||||
if (isset($updateinfo->download)) {
|
||||
$info[] = html_writer::link($updateinfo->download, get_string('download'),
|
||||
array('class' => 'info download btn btn-secondary'));
|
||||
$info[] = html_writer::link($updateinfo->download, get_string('download'), array('class' => 'info download'));
|
||||
}
|
||||
|
||||
if (isset($updateinfo->url)) {
|
||||
@@ -942,9 +940,9 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
array('class' => 'info more'));
|
||||
}
|
||||
|
||||
$box = $this->output->container_start($boxclasses);
|
||||
$box .= $this->output->container(implode(html_writer::tag('span', ' | ', array('class' => 'separator')), $info), '');
|
||||
$box .= $this->output->container_end();
|
||||
$box = $this->output->box_start($boxclasses);
|
||||
$box .= $this->output->box(implode(html_writer::tag('span', ' ', array('class' => 'separator')), $info), '');
|
||||
$box .= $this->output->box_end();
|
||||
|
||||
return $box;
|
||||
}
|
||||
@@ -1056,7 +1054,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$displayname = new html_table_cell(
|
||||
$icon.
|
||||
html_writer::span($plugin->displayname, 'pluginname').
|
||||
html_writer::div($plugin->get_dir(), 'plugindir text-muted small')
|
||||
html_writer::div($plugin->get_dir(), 'plugindir')
|
||||
);
|
||||
|
||||
$versiondb = new html_table_cell($plugin->versiondb);
|
||||
@@ -1091,17 +1089,17 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
break;
|
||||
case core_plugin_manager::PLUGIN_STATUS_NODB:
|
||||
case core_plugin_manager::PLUGIN_STATUS_UPTODATE:
|
||||
$statusclass .= $dependenciesok ? 'badge-light' : 'badge-warning';
|
||||
$statusclass .= $dependenciesok ? '' : 'badge-warning';
|
||||
break;
|
||||
}
|
||||
$status = html_writer::span(get_string('status_' . $statuscode, 'core_plugin'), $statusclass);
|
||||
|
||||
if (!empty($installabortable[$plugin->component])) {
|
||||
$status .= $this->output->single_button(
|
||||
new moodle_url($this->page->url, array('abortinstall' => $plugin->component, 'confirmplugincheck' => 0)),
|
||||
new moodle_url($this->page->url, array('abortinstall' => $plugin->component)),
|
||||
get_string('cancelinstallone', 'core_plugin'),
|
||||
'post',
|
||||
array('class' => 'actionbutton cancelinstallone d-block mt-1')
|
||||
array('class' => 'actionbutton cancelinstallone')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1110,7 +1108,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
new moodle_url($this->page->url, array('abortupgrade' => $plugin->component)),
|
||||
get_string('cancelupgradeone', 'core_plugin'),
|
||||
'post',
|
||||
array('class' => 'actionbutton cancelupgradeone d-block mt-1')
|
||||
array('class' => 'actionbutton cancelupgradeone')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1180,7 +1178,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
}
|
||||
|
||||
$out .= $this->output->container_start('actions mb-2');
|
||||
$out .= $this->output->container_start('actions');
|
||||
|
||||
$installableupdates = $pluginman->filter_installable($pluginman->available_updates());
|
||||
if ($installableupdates) {
|
||||
@@ -1188,16 +1186,16 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
new moodle_url($this->page->url, array('installupdatex' => 1)),
|
||||
get_string('updateavailableinstallall', 'core_admin', count($installableupdates)),
|
||||
'post',
|
||||
array('class' => 'singlebutton updateavailableinstallall mr-1')
|
||||
array('class' => 'singlebutton updateavailableinstallall')
|
||||
);
|
||||
}
|
||||
|
||||
if ($installabortable) {
|
||||
$out .= $this->output->single_button(
|
||||
new moodle_url($this->page->url, array('abortinstallx' => 1, 'confirmplugincheck' => 0)),
|
||||
new moodle_url($this->page->url, array('abortinstallx' => 1)),
|
||||
get_string('cancelinstallall', 'core_plugin', count($installabortable)),
|
||||
'post',
|
||||
array('class' => 'singlebutton cancelinstallall mr-1')
|
||||
array('class' => 'singlebutton cancelinstallall')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1206,17 +1204,15 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
new moodle_url($this->page->url, array('abortupgradex' => 1)),
|
||||
get_string('cancelupgradeall', 'core_plugin', count($upgradeabortable)),
|
||||
'post',
|
||||
array('class' => 'singlebutton cancelupgradeall mr-1')
|
||||
array('class' => 'singlebutton cancelupgradeall')
|
||||
);
|
||||
}
|
||||
|
||||
$out .= html_writer::div(html_writer::link(new moodle_url($this->page->url, array('showallplugins' => 0)),
|
||||
get_string('plugincheckattention', 'core_plugin')).' '.html_writer::span($sumattention, 'badge badge-light'),
|
||||
'btn btn-link mr-1');
|
||||
get_string('plugincheckattention', 'core_plugin')).' '.html_writer::span($sumattention, 'badge'));
|
||||
|
||||
$out .= html_writer::div(html_writer::link(new moodle_url($this->page->url, array('showallplugins' => 1)),
|
||||
get_string('plugincheckall', 'core_plugin')).' '.html_writer::span($sumtotal, 'badge badge-light'),
|
||||
'btn btn-link mr-1');
|
||||
get_string('plugincheckall', 'core_plugin')).' '.html_writer::span($sumtotal, 'badge'));
|
||||
|
||||
$out .= $this->output->container_end(); // End of .actions container.
|
||||
$out .= $this->output->container_end(); // End of #plugins-check-info container.
|
||||
@@ -1284,13 +1280,12 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
}
|
||||
|
||||
$out = $this->output->container_start('plugins-check-dependencies mb-4');
|
||||
$out = $this->output->container_start('plugins-check-dependencies');
|
||||
|
||||
if ($unavailable or $unknown) {
|
||||
$out .= $this->output->heading(get_string('misdepsunavail', 'core_plugin'));
|
||||
if ($unknown) {
|
||||
$out .= $this->output->render((new \core\output\notification(get_string('misdepsunknownlist', 'core_plugin',
|
||||
implode(', ', $unknown))))->set_show_closebutton(false));
|
||||
$out .= $this->output->notification(get_string('misdepsunknownlist', 'core_plugin', implode($unknown, ', ')));
|
||||
}
|
||||
if ($unavailable) {
|
||||
$unavailablelist = array();
|
||||
@@ -1304,18 +1299,18 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
$unavailablelist[] = $unavailablelistitem;
|
||||
}
|
||||
$out .= $this->output->render((new \core\output\notification(get_string('misdepsunavaillist', 'core_plugin',
|
||||
implode(', ', $unavailablelist))))->set_show_closebutton(false));
|
||||
$out .= $this->output->notification(get_string('misdepsunavaillist', 'core_plugin',
|
||||
implode($unavailablelist, ', ')));
|
||||
}
|
||||
$out .= $this->output->container_start('plugins-check-dependencies-actions mb-4');
|
||||
$out .= $this->output->container_start('plugins-check-dependencies-actions');
|
||||
$out .= ' '.html_writer::link(new moodle_url('/admin/tool/installaddon/'),
|
||||
get_string('dependencyuploadmissing', 'core_plugin'), array('class' => 'btn btn-secondary'));
|
||||
get_string('dependencyuploadmissing', 'core_plugin'));
|
||||
$out .= $this->output->container_end(); // End of .plugins-check-dependencies-actions container.
|
||||
}
|
||||
|
||||
if ($available) {
|
||||
$out .= $this->output->heading(get_string('misdepsavail', 'core_plugin'));
|
||||
$out .= $this->output->container_start('plugins-check-dependencies-actions mb-2');
|
||||
$out .= $this->output->container_start('plugins-check-dependencies-actions');
|
||||
|
||||
$installable = $pluginman->filter_installable($available);
|
||||
if ($installable) {
|
||||
@@ -1323,13 +1318,12 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
new moodle_url($this->page->url, array('installdepx' => 1)),
|
||||
get_string('dependencyinstallmissing', 'core_plugin', count($installable)),
|
||||
'post',
|
||||
array('class' => 'singlebutton dependencyinstallmissing d-inline-block mr-1')
|
||||
array('class' => 'singlebutton dependencyinstallmissing')
|
||||
);
|
||||
}
|
||||
|
||||
$out .= html_writer::div(html_writer::link(new moodle_url('/admin/tool/installaddon/'),
|
||||
get_string('dependencyuploadmissing', 'core_plugin'), array('class' => 'btn btn-link')),
|
||||
'dependencyuploadmissing d-inline-block mr-1');
|
||||
get_string('dependencyuploadmissing', 'core_plugin')), 'dependencyuploadmissing');
|
||||
|
||||
$out .= $this->output->container_end(); // End of .plugins-check-dependencies-actions container.
|
||||
|
||||
@@ -1370,7 +1364,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
if ($CFG->branch == str_replace('.', '', $moodle->release)) {
|
||||
$supportedmoodles[] = html_writer::span($moodle->release, 'badge badge-success');
|
||||
} else {
|
||||
$supportedmoodles[] = html_writer::span($moodle->release, 'badge badge-light');
|
||||
$supportedmoodles[] = html_writer::span($moodle->release, 'label');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1384,7 +1378,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
$info = html_writer::div(
|
||||
get_string('requiredby', 'core_plugin', implode(', ', $requriedby)),
|
||||
'requiredby mb-1'
|
||||
'requiredby'
|
||||
);
|
||||
} else {
|
||||
$info = '';
|
||||
@@ -1395,39 +1389,38 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$info .= html_writer::div(
|
||||
html_writer::link('https://moodle.org/plugins/view.php?plugin='.$plugin->component,
|
||||
get_string('misdepinfoplugin', 'core_plugin')),
|
||||
'misdepinfoplugin d-inline-block mr-3 mb-1'
|
||||
'misdepinfoplugin'
|
||||
);
|
||||
|
||||
$info .= html_writer::div(
|
||||
html_writer::link('https://moodle.org/plugins/pluginversion.php?id='.$plugin->version->id,
|
||||
get_string('misdepinfoversion', 'core_plugin')),
|
||||
'misdepinfoversion d-inline-block mr-3 mb-1'
|
||||
'misdepinfoversion'
|
||||
);
|
||||
|
||||
$info .= html_writer::div(html_writer::link($plugin->version->downloadurl, get_string('download')),
|
||||
'misdepdownload d-inline-block mr-3 mb-1');
|
||||
$info .= html_writer::div(html_writer::link($plugin->version->downloadurl, get_string('download')), 'misdepdownload');
|
||||
|
||||
if ($pluginman->is_remote_plugin_installable($plugin->component, $plugin->version->version, $reason)) {
|
||||
$info .= $this->output->single_button(
|
||||
new moodle_url($this->page->url, array('installdep' => $plugin->component)),
|
||||
get_string('dependencyinstall', 'core_plugin'),
|
||||
'post',
|
||||
array('class' => 'singlebutton dependencyinstall mr-3 mb-1')
|
||||
array('class' => 'singlebutton dependencyinstall')
|
||||
);
|
||||
} else {
|
||||
$reasonhelp = $this->info_remote_plugin_not_installable($reason);
|
||||
if ($reasonhelp) {
|
||||
$info .= html_writer::div($reasonhelp, 'reasonhelp dependencyinstall d-inline-block mr-3 mb-1');
|
||||
$info .= html_writer::div($reasonhelp, 'reasonhelp dependencyinstall');
|
||||
}
|
||||
}
|
||||
|
||||
$info .= $this->output->container_end(); // End of .actions container.
|
||||
|
||||
$table->data[] = array(
|
||||
html_writer::div($plugin->name, 'name').' '.html_writer::div($plugin->component, 'component text-muted small'),
|
||||
html_writer::div($plugin->name, 'name').' '.html_writer::div($plugin->component, 'component'),
|
||||
$plugin->version->release,
|
||||
$plugin->version->version,
|
||||
implode(' ', $supportedmoodles),
|
||||
implode($supportedmoodles, ' '),
|
||||
$info
|
||||
);
|
||||
}
|
||||
@@ -1470,7 +1463,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
foreach ($pluginman->resolve_requirements($plugin, $version) as $reqname => $reqinfo) {
|
||||
if ($reqname === 'core') {
|
||||
if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_OK) {
|
||||
$class = 'requires-ok text-muted';
|
||||
$class = 'requires-ok';
|
||||
$label = '';
|
||||
} else {
|
||||
$class = 'requires-failed';
|
||||
@@ -1487,7 +1480,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
|
||||
if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_OK) {
|
||||
$label = '';
|
||||
$class = 'requires-ok text-muted';
|
||||
$class = 'requires-ok';
|
||||
|
||||
} else if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_MISSING) {
|
||||
if ($reqinfo->availability == $pluginman::REQUIREMENT_AVAILABLE) {
|
||||
@@ -1541,14 +1534,13 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
return '';
|
||||
}
|
||||
|
||||
$out = html_writer::tag('ul', implode("\n", $requires), array('class' => 'm-0'));
|
||||
$out = html_writer::tag('ul', implode("\n", $requires));
|
||||
|
||||
if ($displayuploadlink) {
|
||||
$out .= html_writer::div(
|
||||
html_writer::link(
|
||||
new moodle_url('/admin/tool/installaddon/'),
|
||||
get_string('dependencyuploadmissing', 'core_plugin'),
|
||||
array('class' => 'btn btn-secondary btn-sm m-1')
|
||||
get_string('dependencyuploadmissing', 'core_plugin')
|
||||
),
|
||||
'dependencyuploadmissing'
|
||||
);
|
||||
@@ -1558,8 +1550,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$out .= html_writer::div(
|
||||
html_writer::link(
|
||||
new moodle_url($this->page->url, array('sesskey' => sesskey(), 'fetchupdates' => 1)),
|
||||
get_string('checkforupdates', 'core_plugin'),
|
||||
array('class' => 'btn btn-secondary btn-sm m-1')
|
||||
get_string('checkforupdates', 'core_plugin')
|
||||
),
|
||||
'checkforupdates'
|
||||
);
|
||||
@@ -2020,7 +2011,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
if (empty($CFG->docroot) or $environment_result->plugin) {
|
||||
$report = get_string($stringtouse, 'admin', $rec);
|
||||
} else {
|
||||
$report = $this->doc_link(join('/', $linkparts), get_string($stringtouse, 'admin', $rec), true);
|
||||
$report = $this->doc_link(join($linkparts, '/'), get_string($stringtouse, 'admin', $rec), true);
|
||||
}
|
||||
// Enclose report text in div so feedback text will be displayed underneath it.
|
||||
$report = html_writer::div($report);
|
||||
|
||||
@@ -123,13 +123,13 @@ if (($action == 'edit') || ($action == 'new')) {
|
||||
}
|
||||
$instanceoptionnames = repository::static_function($repository, 'get_instance_option_names');
|
||||
if (!empty($instanceoptionnames)) {
|
||||
if (property_exists($fromform, 'enablecourseinstances')) {
|
||||
if (array_key_exists('enablecourseinstances', $fromform)) {
|
||||
$settings['enablecourseinstances'] = $fromform->enablecourseinstances;
|
||||
}
|
||||
else {
|
||||
$settings['enablecourseinstances'] = 0;
|
||||
}
|
||||
if (property_exists($fromform, 'enableuserinstances')) {
|
||||
if (array_key_exists('enableuserinstances', $fromform)) {
|
||||
$settings['enableuserinstances'] = $fromform->enableuserinstances;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -46,6 +46,25 @@ $controller = new $classformode[$mode]();
|
||||
|
||||
if (optional_param('submit', false, PARAM_BOOL) && data_submitted() && confirm_sesskey()) {
|
||||
$controller->process_submission();
|
||||
$event = null;
|
||||
// Create event depending on mode.
|
||||
switch ($mode) {
|
||||
case 'assign':
|
||||
$event = \core\event\role_allow_assign_updated::create(array('context' => $syscontext));
|
||||
break;
|
||||
case 'override':
|
||||
$event = \core\event\role_allow_override_updated::create(array('context' => $syscontext));
|
||||
break;
|
||||
case 'switch':
|
||||
$event = \core\event\role_allow_switch_updated::create(array('context' => $syscontext));
|
||||
break;
|
||||
case 'view':
|
||||
$event = \core\event\role_allow_view_updated::create(array('context' => $syscontext));
|
||||
break;
|
||||
}
|
||||
if ($event) {
|
||||
$event->trigger();
|
||||
}
|
||||
redirect($baseurl);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,4 @@ class core_role_allow_assign_page extends core_role_allow_role_page {
|
||||
public function get_intro_text() {
|
||||
return get_string('configallowassign', 'core_admin');
|
||||
}
|
||||
|
||||
protected function get_eventclass() {
|
||||
return \core\event\role_allow_assign_updated::class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +46,4 @@ class core_role_allow_override_page extends core_role_allow_role_page {
|
||||
public function get_intro_text() {
|
||||
return get_string('configallowoverride2', 'core_admin');
|
||||
}
|
||||
|
||||
protected function get_eventclass() {
|
||||
return \core\event\role_allow_override_updated::class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,36 +59,12 @@ abstract class core_role_allow_role_page {
|
||||
*/
|
||||
public function process_submission() {
|
||||
global $DB;
|
||||
|
||||
$context = context_system::instance();
|
||||
$this->load_current_settings();
|
||||
|
||||
// Delete all records, then add back the ones that should be allowed.
|
||||
$DB->delete_records($this->tablename);
|
||||
foreach ($this->roles as $fromroleid => $notused) {
|
||||
foreach ($this->roles as $targetroleid => $alsonotused) {
|
||||
$isallowed = $this->allowed[$fromroleid][$targetroleid];
|
||||
if (optional_param('s_' . $fromroleid . '_' . $targetroleid, false, PARAM_BOOL)) {
|
||||
$this->set_allow($fromroleid, $targetroleid);
|
||||
// Only trigger events if this role allow relationship did not exist and the checkbox element
|
||||
// has been submitted.
|
||||
if (!$isallowed) {
|
||||
$eventclass = $this->get_eventclass();
|
||||
$eventclass::create([
|
||||
'context' => $context,
|
||||
'objectid' => $fromroleid,
|
||||
'other' => ['targetroleid' => $targetroleid, 'allow' => true]
|
||||
])->trigger();
|
||||
}
|
||||
} else if ($isallowed) {
|
||||
// When the user has deselect an existing role allow checkbox but it is in the list of roles
|
||||
// allowances.
|
||||
$eventclass = $this->get_eventclass();
|
||||
$eventclass::create([
|
||||
'context' => $context,
|
||||
'objectid' => $fromroleid,
|
||||
'other' => ['targetroleid' => $targetroleid, 'allow' => false]
|
||||
])->trigger();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,10 +161,4 @@ abstract class core_role_allow_role_page {
|
||||
* @return string
|
||||
*/
|
||||
public abstract function get_intro_text();
|
||||
|
||||
/**
|
||||
* Returns the allow class respective event class name.
|
||||
* @return string
|
||||
*/
|
||||
protected abstract function get_eventclass();
|
||||
}
|
||||
|
||||
@@ -58,8 +58,4 @@ class core_role_allow_switch_page extends core_role_allow_role_page {
|
||||
public function get_intro_text() {
|
||||
return get_string('configallowswitch', 'core_admin');
|
||||
}
|
||||
|
||||
protected function get_eventclass() {
|
||||
return \core\event\role_allow_switch_updated::class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,8 +74,4 @@ class core_role_allow_view_page extends core_role_allow_role_page {
|
||||
public function get_intro_text() {
|
||||
return get_string('configallowview', 'core_admin');
|
||||
}
|
||||
|
||||
protected function get_eventclass() {
|
||||
return \core\event\role_allow_view_updated::class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,19 +157,19 @@ class core_role_define_role_table_advanced extends core_role_capability_table_wi
|
||||
// Allowed roles.
|
||||
$allow = optional_param_array('allowassign', null, PARAM_INT);
|
||||
if (!is_null($allow)) {
|
||||
$this->allowassign = array_filter($allow);
|
||||
$this->allowassign = $allow;
|
||||
}
|
||||
$allow = optional_param_array('allowoverride', null, PARAM_INT);
|
||||
if (!is_null($allow)) {
|
||||
$this->allowoverride = array_filter($allow);
|
||||
$this->allowoverride = $allow;
|
||||
}
|
||||
$allow = optional_param_array('allowswitch', null, PARAM_INT);
|
||||
if (!is_null($allow)) {
|
||||
$this->allowswitch = array_filter($allow);
|
||||
$this->allowswitch = $allow;
|
||||
}
|
||||
$allow = optional_param_array('allowview', null, PARAM_INT);
|
||||
if (!is_null($allow)) {
|
||||
$this->allowview = array_filter($allow);
|
||||
$this->allowview = $allow;
|
||||
}
|
||||
|
||||
// Now read the permissions for each capability.
|
||||
@@ -434,7 +434,7 @@ class core_role_define_role_table_advanced extends core_role_capability_table_wi
|
||||
}
|
||||
|
||||
public function save_changes() {
|
||||
global $DB, $USER;
|
||||
global $DB;
|
||||
|
||||
if (!$this->roleid) {
|
||||
// Creating role.
|
||||
@@ -444,20 +444,6 @@ class core_role_define_role_table_advanced extends core_role_capability_table_wi
|
||||
// Updating role.
|
||||
$DB->update_record('role', $this->role);
|
||||
|
||||
// Trigger role updated event.
|
||||
\core\event\role_updated::create([
|
||||
'userid' => $USER->id,
|
||||
'objectid' => $this->role->id,
|
||||
'context' => $this->context,
|
||||
'other' => [
|
||||
'name' => $this->role->name,
|
||||
'shortname' => $this->role->shortname,
|
||||
'description' => $this->role->description,
|
||||
'archetype' => $this->role->archetype,
|
||||
'contextlevels' => $this->contextlevels
|
||||
]
|
||||
])->trigger();
|
||||
|
||||
// This will ensure the course contacts cache is purged so name changes get updated in
|
||||
// the UI. It would be better to do this only when we know that fields affected are
|
||||
// updated. But thats getting into the weeds of the coursecat cache and role edits
|
||||
@@ -487,17 +473,10 @@ class core_role_define_role_table_advanced extends core_role_capability_table_wi
|
||||
$addfunction = "core_role_set_{$type}_allowed";
|
||||
$deltable = 'role_allow_'.$type;
|
||||
$field = 'allow'.$type;
|
||||
$eventclass = "\\core\\event\\role_allow_" . $type . "_updated";
|
||||
$context = context_system::instance();
|
||||
|
||||
foreach ($current as $roleid) {
|
||||
if (!in_array($roleid, $wanted)) {
|
||||
$DB->delete_records($deltable, array('roleid'=>$this->roleid, $field=>$roleid));
|
||||
$eventclass::create([
|
||||
'context' => $context,
|
||||
'objectid' => $this->roleid,
|
||||
'other' => ['targetroleid' => $roleid, 'allow' => false]
|
||||
])->trigger();
|
||||
continue;
|
||||
}
|
||||
$key = array_search($roleid, $wanted);
|
||||
@@ -509,14 +488,6 @@ class core_role_define_role_table_advanced extends core_role_capability_table_wi
|
||||
$roleid = $this->roleid;
|
||||
}
|
||||
$addfunction($this->roleid, $roleid);
|
||||
|
||||
if (in_array($roleid, $wanted)) {
|
||||
$eventclass::create([
|
||||
'context' => $context,
|
||||
'objectid' => $this->roleid,
|
||||
'other' => ['targetroleid' => $roleid, 'allow' => true]
|
||||
])->trigger();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,9 +589,7 @@ class core_role_define_role_table_advanced extends core_role_capability_table_wi
|
||||
if ($this->roleid == 0) {
|
||||
$options[-1] = get_string('thisnewrole', 'core_role');
|
||||
}
|
||||
return
|
||||
html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'allow'.$type.'[]', 'value' => "")) .
|
||||
html_writer::select($options, 'allow'.$type.'[]', $selected, false, array('multiple' => 'multiple',
|
||||
return html_writer::select($options, 'allow'.$type.'[]', $selected, false, array('multiple' => 'multiple',
|
||||
'size' => 10, 'class' => 'form-control'));
|
||||
}
|
||||
|
||||
|
||||
+14
-3
@@ -52,12 +52,10 @@ if ($return === 'manage') {
|
||||
$returnurl = new moodle_url('/admin/roles/define.php', array('action'=>'view', 'roleid'=>$roleid));;
|
||||
}
|
||||
|
||||
admin_externalpage_setup('defineroles', '', array('action' => $action, 'roleid' => $roleid),
|
||||
new moodle_url('/admin/roles/define.php'));
|
||||
|
||||
// Check access permissions.
|
||||
$systemcontext = context_system::instance();
|
||||
require_capability('moodle/role:manage', $systemcontext);
|
||||
admin_externalpage_setup('defineroles', '', array('action' => $action, 'roleid' => $roleid), new moodle_url('/admin/roles/define.php'));
|
||||
|
||||
// Export role.
|
||||
if ($action === 'export') {
|
||||
@@ -200,6 +198,19 @@ if (optional_param('cancel', false, PARAM_BOOL)) {
|
||||
if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey() && $definitiontable->is_submission_valid()) {
|
||||
$definitiontable->save_changes();
|
||||
$tableroleid = $definitiontable->get_role_id();
|
||||
// Trigger event.
|
||||
$event = \core\event\role_capabilities_updated::create(
|
||||
array(
|
||||
'context' => $systemcontext,
|
||||
'objectid' => $tableroleid
|
||||
)
|
||||
);
|
||||
$event->set_legacy_logdata(array(SITEID, 'role', $action, 'admin/roles/define.php?action=view&roleid=' . $tableroleid,
|
||||
$definitiontable->get_role_name(), '', $USER->id));
|
||||
if (!empty($role)) {
|
||||
$event->add_record_snapshot('role', $role);
|
||||
}
|
||||
$event->trigger();
|
||||
|
||||
if ($action === 'add') {
|
||||
redirect(new moodle_url('/admin/roles/define.php', array('action'=>'view', 'roleid'=>$definitiontable->get_role_id())));
|
||||
|
||||
@@ -46,11 +46,10 @@ if ($action) {
|
||||
$baseurl = $CFG->wwwroot . '/' . $CFG->admin . '/roles/manage.php';
|
||||
$defineurl = $CFG->wwwroot . '/' . $CFG->admin . '/roles/define.php';
|
||||
|
||||
admin_externalpage_setup('defineroles');
|
||||
|
||||
// Check access permissions.
|
||||
$systemcontext = context_system::instance();
|
||||
require_capability('moodle/role:manage', $systemcontext);
|
||||
admin_externalpage_setup('defineroles');
|
||||
|
||||
// Get some basic data we are going to need.
|
||||
$roles = role_fix_names(get_all_roles(), $systemcontext, ROLENAME_ORIGINAL);
|
||||
|
||||
@@ -134,6 +134,22 @@ $overridestable->read_submitted_permissions();
|
||||
if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) {
|
||||
$overridestable->save_changes();
|
||||
$rolename = $overridableroles[$roleid];
|
||||
// Trigger event.
|
||||
$event = \core\event\role_capabilities_updated::create(
|
||||
array(
|
||||
'context' => $context,
|
||||
'objectid' => $roleid,
|
||||
)
|
||||
);
|
||||
|
||||
$event->set_legacy_logdata(
|
||||
array(
|
||||
$course->id, 'role', 'override', 'admin/roles/override.php?contextid=' . $context->id . '&roleid=' . $roleid,
|
||||
$rolename, '', $USER->id
|
||||
)
|
||||
);
|
||||
$event->add_record_snapshot('role', $role);
|
||||
$event->trigger();
|
||||
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ $PAGE->set_pagelayout('admin');
|
||||
|
||||
// Check login and permissions.
|
||||
if ($course->id == SITEID) {
|
||||
require_login(null, false);
|
||||
require_login();
|
||||
$PAGE->set_context($usercontext);
|
||||
} else {
|
||||
require_login($course);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
if ($hassiteconfig && \core_analytics\manager::is_analytics_enabled()) {
|
||||
if ($hassiteconfig) {
|
||||
|
||||
$settings = new admin_settingpage('analyticssite', new lang_string('analyticssiteinfo', 'analytics'));
|
||||
$ADMIN->add('analytics', $settings);
|
||||
@@ -131,10 +131,15 @@ if ($hassiteconfig && \core_analytics\manager::is_analytics_enabled()) {
|
||||
$timesplittingdefaults, $timesplittingoptions)
|
||||
);
|
||||
|
||||
// Predictions processor output dir - specify default in setting description (used if left blank).
|
||||
$defaultmodeloutputdir = \core_analytics\model::default_output_dir();
|
||||
// Predictions processor output dir.
|
||||
$defaultmodeloutputdir = rtrim($CFG->dataroot, '/') . DIRECTORY_SEPARATOR . 'models';
|
||||
if (empty(get_config('analytics', 'modeloutputdir')) && !file_exists($defaultmodeloutputdir) &&
|
||||
is_writable($defaultmodeloutputdir)) {
|
||||
// Automatically create the dir for them so users don't see the invalid value red cross.
|
||||
mkdir($defaultmodeloutputdir, $CFG->directorypermissions, true);
|
||||
}
|
||||
$settings->add(new admin_setting_configdirectory('analytics/modeloutputdir', new lang_string('modeloutputdir', 'analytics'),
|
||||
new lang_string('modeloutputdirwithdefaultinfo', 'analytics', $defaultmodeloutputdir), ''));
|
||||
new lang_string('modeloutputdirinfo', 'analytics'), $defaultmodeloutputdir));
|
||||
|
||||
// Disable web interface evaluation and get predictions.
|
||||
$settings->add(new admin_setting_configcheckbox('analytics/onlycli', new lang_string('onlycli', 'analytics'),
|
||||
|
||||
@@ -76,24 +76,6 @@ preferences,moodle|/user/preferences.php|t/preferences',
|
||||
|
||||
$ADMIN->add('appearance', $temp);
|
||||
|
||||
// Course colours section.
|
||||
$temp = new admin_settingpage('coursecolors', new lang_string('coursecolorsettings', 'admin'));
|
||||
$temp->add(new admin_setting_heading('coursecolorheading', '',
|
||||
new lang_string('coursecolorheading_desc', 'admin')));
|
||||
|
||||
$basecolors = ['#81ecec', '#74b9ff', '#a29bfe', '#dfe6e9', '#00b894',
|
||||
'#0984e3', '#b2bec3', '#fdcb6e', '#fd79a8', '#6c5ce7'];
|
||||
|
||||
foreach ($basecolors as $key => $color) {
|
||||
$number = $key + 1;
|
||||
$name = 'core_admin/coursecolor' . $number;
|
||||
$title = get_string('coursecolor', 'admin', $number);
|
||||
$setting = new admin_setting_configcolourpicker($name, $title, '', $color);
|
||||
$temp->add($setting);
|
||||
}
|
||||
|
||||
$ADMIN->add('appearance', $temp);
|
||||
|
||||
// Calendar settings.
|
||||
$temp = new admin_settingpage('calendar', new lang_string('calendarsettings','admin'));
|
||||
|
||||
@@ -197,10 +179,6 @@ preferences,moodle|/user/preferences.php|t/preferences',
|
||||
'idnumber' => new lang_string('sort_idnumber', 'admin'),
|
||||
);
|
||||
$temp->add(new admin_setting_configselect('navsortmycoursessort', new lang_string('navsortmycoursessort', 'admin'), new lang_string('navsortmycoursessort_help', 'admin'), 'sortorder', $sortoptions));
|
||||
$temp->add(new admin_setting_configcheckbox('navsortmycourseshiddenlast',
|
||||
new lang_string('navsortmycourseshiddenlast', 'admin'),
|
||||
new lang_string('navsortmycourseshiddenlast_help', 'admin'),
|
||||
1));
|
||||
$temp->add(new admin_setting_configtext('navcourselimit', new lang_string('navcourselimit', 'admin'),
|
||||
new lang_string('confignavcourselimit', 'admin'), 10, PARAM_INT));
|
||||
$temp->add(new admin_setting_configcheckbox('usesitenameforsitepages', new lang_string('usesitenameforsitepages', 'admin'), new lang_string('configusesitenameforsitepages', 'admin'), 0));
|
||||
@@ -279,10 +257,4 @@ preferences,moodle|/user/preferences.php|t/preferences',
|
||||
$temp->add(new admin_setting_configtextarea('additionalhtmlfooter', new lang_string('additionalhtmlfooter', 'admin'), new lang_string('additionalhtmlfooter_desc', 'admin'), '', PARAM_RAW));
|
||||
$ADMIN->add('appearance', $temp);
|
||||
|
||||
$setting = new admin_setting_configcheckbox('cachetemplates', new lang_string('cachetemplates', 'admin'),
|
||||
new lang_string('cachetemplates_help', 'admin'), 1);
|
||||
$setting->set_updatedcallback('template_reset_all_caches');
|
||||
$temp = new admin_settingpage('templates', new lang_string('templates', 'admin'));
|
||||
$temp->add($setting);
|
||||
$ADMIN->add('appearance', $temp);
|
||||
} // end of speedup
|
||||
|
||||
@@ -105,6 +105,13 @@ if (($hassiteconfig || has_any_capability(array(
|
||||
new lang_string('sitebackpack_help', 'badges'),
|
||||
1, $choices));
|
||||
|
||||
$warning = badges_verify_site_backpack();
|
||||
if (!empty($warning)) {
|
||||
$backpacksettings->add(new admin_setting_description('badges_site_backpack_verify',
|
||||
new lang_string('sitebackpackverify', 'badges'),
|
||||
$warning));
|
||||
}
|
||||
|
||||
$ADMIN->add('badges', $backpacksettings);
|
||||
|
||||
$ADMIN->add('badges',
|
||||
|
||||
@@ -163,15 +163,9 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
|
||||
// "courserequests" settingpage.
|
||||
$temp = new admin_settingpage('courserequest', new lang_string('courserequest'));
|
||||
$temp->add(new admin_setting_configcheckbox('enablecourserequests',
|
||||
new lang_string('enablecourserequests', 'admin'),
|
||||
new lang_string('configenablecourserequests', 'admin'), 1));
|
||||
$temp->add(new admin_settings_coursecat_select('defaultrequestcategory',
|
||||
new lang_string('defaultrequestcategory', 'admin'),
|
||||
new lang_string('configdefaultrequestcategory', 'admin'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('lockrequestcategory',
|
||||
new lang_string('lockrequestcategory', 'admin'),
|
||||
new lang_string('configlockrequestcategory', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('enablecourserequests', new lang_string('enablecourserequests', 'admin'), new lang_string('configenablecourserequests', 'admin'), 0));
|
||||
$temp->add(new admin_settings_coursecat_select('defaultrequestcategory', new lang_string('defaultrequestcategory', 'admin'), new lang_string('configdefaultrequestcategory', 'admin'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('requestcategoryselection', new lang_string('requestcategoryselection', 'admin'), new lang_string('configrequestcategoryselection', 'admin'), 0));
|
||||
$temp->add(new admin_setting_users_with_capability('courserequestnotify', new lang_string('courserequestnotify', 'admin'), new lang_string('configcourserequestnotify2', 'admin'), array(), 'moodle/site:approvecourse'));
|
||||
$ADMIN->add('courses', $temp);
|
||||
|
||||
@@ -212,11 +206,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_role_assignments', new lang_string('generalroleassignments','backup'), new lang_string('configgeneralroleassignments','backup'), array('value'=>1, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_activities', new lang_string('generalactivities','backup'), new lang_string('configgeneralactivities','backup'), array('value'=>1, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_blocks', new lang_string('generalblocks','backup'), new lang_string('configgeneralblocks','backup'), array('value'=>1, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock(
|
||||
'backup/backup_general_files',
|
||||
new lang_string('generalfiles', 'backup'),
|
||||
new lang_string('configgeneralfiles', 'backup'),
|
||||
array('value' => '1', 'locked' => 0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_filters', new lang_string('generalfilters','backup'), new lang_string('configgeneralfilters','backup'), array('value'=>1, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_comments', new lang_string('generalcomments','backup'), new lang_string('configgeneralcomments','backup'), array('value'=>1, 'locked'=>0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_badges', new lang_string('generalbadges','backup'), new lang_string('configgeneralbadges','backup'), array('value'=>1,'locked'=>0)));
|
||||
@@ -352,10 +341,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_role_assignments', new lang_string('generalroleassignments','backup'), new lang_string('configgeneralroleassignments','backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_activities', new lang_string('generalactivities','backup'), new lang_string('configgeneralactivities','backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_blocks', new lang_string('generalblocks','backup'), new lang_string('configgeneralblocks','backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox(
|
||||
'backup/backup_auto_files',
|
||||
new lang_string('generalfiles', 'backup'),
|
||||
new lang_string('configgeneralfiles', 'backup'), '1'));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_filters', new lang_string('generalfilters','backup'), new lang_string('configgeneralfilters','backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_comments', new lang_string('generalcomments','backup'), new lang_string('configgeneralcomments','backup'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_badges', new lang_string('generalbadges','backup'), new lang_string('configgeneralbadges','backup'), 1));
|
||||
|
||||
@@ -29,17 +29,13 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$temp->add(new admin_setting_configcheckbox('forceclean', new lang_string('forceclean', 'core_admin'),
|
||||
new lang_string('forceclean_desc', 'core_admin'), 0));
|
||||
|
||||
// Relative course dates mode setting.
|
||||
$temp->add(new admin_setting_configcheckbox('enablecourserelativedates',
|
||||
new lang_string('enablecourserelativedates', 'core_admin'),
|
||||
new lang_string('enablecourserelativedates_desc', 'core_admin'), 0));
|
||||
|
||||
$ADMIN->add('experimental', $temp);
|
||||
|
||||
// "debugging" settingpage
|
||||
$temp = new admin_settingpage('debugging', new lang_string('debugging', 'admin'));
|
||||
$temp->add(new admin_setting_special_debug());
|
||||
$temp->add(new admin_setting_configcheckbox('debugdisplay', new lang_string('debugdisplay', 'admin'), new lang_string('configdebugdisplay', 'admin'), ini_get_bool('display_errors')));
|
||||
$temp->add(new admin_setting_configcheckbox('debugsmtp', new lang_string('debugsmtp', 'admin'), new lang_string('configdebugsmtp', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('perfdebug', new lang_string('perfdebug', 'admin'), new lang_string('configperfdebug', 'admin'), '7', '15', '7'));
|
||||
$temp->add(new admin_setting_configcheckbox('debugstringids', new lang_string('debugstringids', 'admin'), new lang_string('debugstringids_desc', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('debugvalidators', new lang_string('debugvalidators', 'admin'), new lang_string('configdebugvalidators', 'admin'), 0));
|
||||
|
||||
@@ -58,7 +58,7 @@ if (!during_initial_install()) { //do not use during installation
|
||||
foreach ($roles as $role) {
|
||||
if (empty($role->archetype) or $role->archetype === 'guest' or $role->archetype === 'frontpage' or $role->archetype === 'student') {
|
||||
$options[$role->id] = $role->localname;
|
||||
if ($role->archetype === 'frontpage' && !$defaultfrontpageroleid) {
|
||||
if ($role->archetype === 'frontpage') {
|
||||
$defaultfrontpageroleid = $role->id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +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/>.
|
||||
|
||||
/**
|
||||
* H5P settings link.
|
||||
*
|
||||
* @package core_h5p
|
||||
* @copyright 2019 Amaia Anabitarte <amaia@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
// Settings page.
|
||||
$ADMIN->add('h5p', new admin_externalpage('h5psettings', get_string('h5pmanage', 'core_h5p'),
|
||||
new moodle_url('/h5p/libraries.php'), ['moodle/site:config', 'moodle/h5p:updatelibraries']));
|
||||
+14
-50
@@ -1,57 +1,21 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://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/>.
|
||||
|
||||
/**
|
||||
* Define administration settings on the Location settings page.
|
||||
*
|
||||
* @package core
|
||||
* @category admin
|
||||
* @copyright 2006 Martin Dougiamas <martin@moodle.com>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
// "locations" settingpage
|
||||
$temp = new admin_settingpage('locationsettings', new lang_string('locationsettings', 'admin'));
|
||||
$temp->add(new admin_setting_servertimezone());
|
||||
$temp->add(new admin_setting_forcetimezone());
|
||||
$temp->add(new admin_settings_country_select('country', new lang_string('country', 'admin'), new lang_string('configcountry', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configtext('defaultcity', new lang_string('defaultcity', 'admin'), new lang_string('defaultcity_help', 'admin'), ''));
|
||||
|
||||
if ($hassiteconfig) {
|
||||
$temp = new admin_settingpage('locationsettings', new lang_string('locationsettings', 'core_admin'));
|
||||
$temp->add(new admin_setting_heading('iplookup', new lang_string('iplookup', 'admin'), new lang_string('iplookupinfo', 'admin')));
|
||||
$temp->add(new admin_setting_configfile('geoip2file', new lang_string('geoipfile', 'admin'),
|
||||
new lang_string('configgeoipfile', 'admin', $CFG->dataroot.'/geoip/'), $CFG->dataroot.'/geoip/GeoLite2-City.mmdb'));
|
||||
$temp->add(new admin_setting_configtext('googlemapkey3', new lang_string('googlemapkey3', 'admin'), new lang_string('googlemapkey3_help', 'admin'), '', PARAM_RAW, 60));
|
||||
|
||||
if ($ADMIN->fulltree) {
|
||||
$temp->add(new admin_setting_servertimezone());
|
||||
|
||||
$temp->add(new admin_setting_forcetimezone());
|
||||
|
||||
$temp->add(new admin_settings_country_select('country', new lang_string('country', 'core_admin'),
|
||||
new lang_string('configcountry', 'core_admin'), 0));
|
||||
|
||||
$temp->add(new admin_setting_configtext('defaultcity', new lang_string('defaultcity', 'core_admin'),
|
||||
new lang_string('defaultcity_help', 'core_admin'), ''));
|
||||
|
||||
$temp->add(new admin_setting_heading('iplookup', new lang_string('iplookup', 'core_admin'),
|
||||
new lang_string('iplookupinfo', 'core_admin')));
|
||||
|
||||
$temp->add(new admin_setting_configfile('geoip2file', new lang_string('geoipfile', 'core_admin'),
|
||||
new lang_string('configgeoipfile', 'core_admin', $CFG->dataroot . '/geoip/'),
|
||||
$CFG->dataroot . '/geoip/GeoLite2-City.mmdb'));
|
||||
|
||||
$temp->add(new admin_setting_configtext('googlemapkey3', new lang_string('googlemapkey3', 'core_admin'),
|
||||
new lang_string('googlemapkey3_help', 'core_admin'), '', PARAM_RAW, 60));
|
||||
|
||||
$temp->add(new admin_setting_countrycodes('allcountrycodes', new lang_string('allcountrycodes', 'core_admin'),
|
||||
new lang_string('configallcountrycodes', 'core_admin')));
|
||||
}
|
||||
$temp->add(new admin_setting_configtext('allcountrycodes', new lang_string('allcountrycodes', 'admin'), new lang_string('configallcountrycodes', 'admin'), '', '/^(?:\w+(?:,\w+)*)?$/'));
|
||||
|
||||
$ADMIN->add('location', $temp);
|
||||
}
|
||||
|
||||
} // end of speedup
|
||||
|
||||
@@ -175,13 +175,6 @@ if ($hassiteconfig) {
|
||||
$plugin->load_settings($ADMIN, 'antivirussettings', $hassiteconfig);
|
||||
}
|
||||
|
||||
// Machine learning backend plugins.
|
||||
$ADMIN->add('modules', new admin_category('mlbackendsettings', new lang_string('mlbackendsettings', 'admin')));
|
||||
$plugins = core_plugin_manager::instance()->get_plugins_of_type('mlbackend');
|
||||
foreach ($plugins as $plugin) {
|
||||
$plugin->load_settings($ADMIN, 'mlbackendsettings', $hassiteconfig);
|
||||
}
|
||||
|
||||
/// License types
|
||||
$ADMIN->add('modules', new admin_category('licensesettings', new lang_string('licenses')));
|
||||
$temp = new admin_settingpage('managelicenses', new lang_string('managelicenses', 'admin'));
|
||||
|
||||
@@ -1,29 +1,4 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Adds security related settings links for security category to admin tree.
|
||||
*
|
||||
* @copyright 1999 Martin Dougiamas http://dougiamas.com
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use core_admin\local\settings\filesize;
|
||||
|
||||
if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
@@ -42,7 +17,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$temp->add(new admin_setting_configcheckbox('forcelogin', new lang_string('forcelogin', 'admin'), new lang_string('configforcelogin', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('forceloginforprofiles', new lang_string('forceloginforprofiles', 'admin'), new lang_string('configforceloginforprofiles', 'admin'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('forceloginforprofileimage', new lang_string('forceloginforprofileimage', 'admin'), new lang_string('forceloginforprofileimage_help', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('opentowebcrawlers', new lang_string('opentowebcrawlers', 'admin'), new lang_string('configopentowebcrawlers', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('opentogoogle', new lang_string('opentogoogle', 'admin'), new lang_string('configopentogoogle', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configselect('allowindexing', new lang_string('allowindexing', 'admin'), new lang_string('allowindexing_desc', 'admin'),
|
||||
0,
|
||||
array(0 => new lang_string('allowindexingexceptlogin', 'admin'),
|
||||
@@ -61,9 +36,12 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
// maxbytes set to 0 will allow the maximum server limit for uploads
|
||||
$temp->add(new admin_setting_configselect('maxbytes', new lang_string('maxbytes', 'admin'), new lang_string('configmaxbytes', 'admin'), 0, $max_upload_choices));
|
||||
// 100MB
|
||||
$defaultuserquota = 100 * filesize::UNIT_MB;
|
||||
$temp->add(new filesize('userquota', new lang_string('userquota', 'admin'),
|
||||
new lang_string('userquota_desc', 'admin'), $defaultuserquota));
|
||||
$defaultuserquota = 104857600;
|
||||
$params = new stdClass();
|
||||
$params->bytes = $defaultuserquota;
|
||||
$params->displaysize = display_size($defaultuserquota);
|
||||
$temp->add(new admin_setting_configtext('userquota', new lang_string('userquota', 'admin'),
|
||||
new lang_string('configuserquota', 'admin', $params), $defaultuserquota, PARAM_INT, 30));
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('allowobjectembed', new lang_string('allowobjectembed', 'admin'), new lang_string('configallowobjectembed', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('enabletrusttext', new lang_string('enabletrusttext', 'admin'), new lang_string('configenabletrusttext', 'admin'), 0));
|
||||
|
||||
@@ -97,10 +97,7 @@ $options = array(
|
||||
GETREMOTEADDR_SKIP_HTTP_CLIENT_IP => 'HTTP_X_FORWARDED_FOR, REMOTE_ADDR',
|
||||
GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR => 'HTTP_CLIENT, REMOTE_ADDR',
|
||||
GETREMOTEADDR_SKIP_HTTP_X_FORWARDED_FOR|GETREMOTEADDR_SKIP_HTTP_CLIENT_IP => 'REMOTE_ADDR');
|
||||
$temp->add(new admin_setting_configselect('getremoteaddrconf', new lang_string('getremoteaddrconf', 'admin'),
|
||||
new lang_string('configgetremoteaddrconf', 'admin'),
|
||||
GETREMOTEADDR_SKIP_DEFAULT, $options));
|
||||
$temp->add(new admin_setting_configtext('reverseproxyignore', new lang_string('reverseproxyignore', 'admin'), new lang_string('configreverseproxyignore', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configselect('getremoteaddrconf', new lang_string('getremoteaddrconf', 'admin'), new lang_string('configgetremoteaddrconf', 'admin'), 0, $options));
|
||||
|
||||
$temp->add(new admin_setting_heading('webproxy', new lang_string('webproxy', 'admin'), new lang_string('webproxyinfo', 'admin')));
|
||||
$temp->add(new admin_setting_configtext('proxyhost', new lang_string('proxyhost', 'admin'), new lang_string('configproxyhost', 'admin'), '', PARAM_HOST));
|
||||
@@ -175,10 +172,7 @@ $temp->add(new admin_setting_configselect('tempdatafoldercleanup', new lang_stri
|
||||
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
$temp->add(new admin_setting_configduration('filescleanupperiod',
|
||||
new lang_string('filescleanupperiod', 'admin'),
|
||||
new lang_string('filescleanupperiod_help', 'admin'),
|
||||
86400));
|
||||
|
||||
|
||||
$ADMIN->add('server', new admin_externalpage('environment', new lang_string('environment','admin'), "$CFG->wwwroot/$CFG->admin/environment.php"));
|
||||
$ADMIN->add('server', new admin_externalpage('phpinfo', new lang_string('phpinfo'), "$CFG->wwwroot/$CFG->admin/phpinfo.php"));
|
||||
@@ -274,14 +268,6 @@ $temp->add(
|
||||
]
|
||||
)
|
||||
);
|
||||
$temp->add(
|
||||
new admin_setting_configcheckbox(
|
||||
'task_logtostdout',
|
||||
new lang_string('task_logtostdout', 'admin'),
|
||||
new lang_string('task_logtostdout_desc', 'admin'),
|
||||
1
|
||||
)
|
||||
);
|
||||
|
||||
if (\core\task\logmanager::uses_standard_settings()) {
|
||||
$temp->add(
|
||||
|
||||
@@ -48,30 +48,4 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
$optionalsubsystems->add(new admin_setting_configcheckbox('allowstealth', new lang_string('allowstealthmodules'),
|
||||
new lang_string('allowstealthmodules_help'), 0, 1, 0));
|
||||
|
||||
$optionalsubsystems->add(new admin_setting_configcheckbox('enableanalytics', new lang_string('enableanalytics', 'admin'),
|
||||
new lang_string('configenableanalytics', 'admin'), 1, 1, 0));
|
||||
|
||||
$fullunicodesupport = true;
|
||||
if ($DB->get_dbfamily() == 'mysql') {
|
||||
$collation = $DB->get_dbcollation();
|
||||
$collationinfo = explode('_', $collation);
|
||||
$charset = reset($collationinfo);
|
||||
$fullunicodesupport = $charset === 'utf8mb4';
|
||||
}
|
||||
|
||||
if ($fullunicodesupport) {
|
||||
$optionalsubsystems->add(new admin_setting_configcheckbox(
|
||||
'allowemojipicker',
|
||||
new lang_string('allowemojipicker', 'admin'),
|
||||
new lang_string('configallowemojipicker', 'admin'),
|
||||
1
|
||||
));
|
||||
} else {
|
||||
$optionalsubsystems->add(new admin_setting_description(
|
||||
'allowemojipicker',
|
||||
new lang_string('allowemojipicker', 'admin'),
|
||||
new lang_string('configallowemojipickerincompatible', 'admin')
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ $ADMIN->add('root', new admin_category('grades', new lang_string('grades')));
|
||||
$ADMIN->add('root', new admin_category('analytics', new lang_string('analytics', 'analytics')));
|
||||
$ADMIN->add('root', new admin_category('competencies', new lang_string('competencies', 'core_competency')));
|
||||
$ADMIN->add('root', new admin_category('badges', new lang_string('badges'), empty($CFG->enablebadges)));
|
||||
$ADMIN->add('root', new admin_category('h5p', new lang_string('h5p', 'core_h5p')));
|
||||
$ADMIN->add('root', new admin_category('location', new lang_string('location','admin')));
|
||||
$ADMIN->add('root', new admin_category('language', new lang_string('language')));
|
||||
$ADMIN->add('root', new admin_category('messaging', new lang_string('messagingcategory', 'admin')));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
// This file defines settingpages and externalpages under the "users" category.
|
||||
// This file defines settingpages and externalpages under the "users" category
|
||||
|
||||
$ADMIN->add('users', new admin_category('accounts', new lang_string('accounts', 'admin')));
|
||||
$ADMIN->add('users', new admin_category('roles', new lang_string('permissions', 'role')));
|
||||
@@ -13,47 +13,15 @@ if ($hassiteconfig
|
||||
or has_capability('moodle/role:manage', $systemcontext)
|
||||
or has_capability('moodle/role:assign', $systemcontext)
|
||||
or has_capability('moodle/cohort:manage', $systemcontext)
|
||||
or has_capability('moodle/cohort:view', $systemcontext)) { // Speedup for non-admins, add all caps used on this page.
|
||||
or has_capability('moodle/cohort:view', $systemcontext)) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
|
||||
// Stuff under the "accounts" subcategory.
|
||||
// stuff under the "accounts" subcategory
|
||||
$ADMIN->add('accounts', new admin_externalpage('editusers', new lang_string('userlist','admin'), "$CFG->wwwroot/$CFG->admin/user.php", array('moodle/user:update', 'moodle/user:delete')));
|
||||
$ADMIN->add('accounts', new admin_externalpage('userbulk', new lang_string('userbulk','admin'), "$CFG->wwwroot/$CFG->admin/user/user_bulk.php", array('moodle/user:update', 'moodle/user:delete')));
|
||||
$ADMIN->add('accounts', new admin_externalpage('addnewuser', new lang_string('addnewuser'), "$CFG->wwwroot/user/editadvanced.php?id=-1", 'moodle/user:create'));
|
||||
|
||||
// User management settingpage.
|
||||
$temp = new admin_settingpage('usermanagement', new lang_string('usermanagement', 'admin'));
|
||||
if ($ADMIN->fulltree) {
|
||||
$choices = array();
|
||||
$choices['realname'] = new lang_string('fullnameuser');
|
||||
$choices['lastname'] = new lang_string('lastname');
|
||||
$choices['firstname'] = new lang_string('firstname');
|
||||
$choices['username'] = new lang_string('username');
|
||||
$choices['email'] = new lang_string('email');
|
||||
$choices['city'] = new lang_string('city');
|
||||
$choices['country'] = new lang_string('country');
|
||||
$choices['confirmed'] = new lang_string('confirmed', 'admin');
|
||||
$choices['suspended'] = new lang_string('suspended', 'auth');
|
||||
$choices['profile'] = new lang_string('profilefields', 'admin');
|
||||
$choices['courserole'] = new lang_string('courserole', 'filters');
|
||||
$choices['anycourses'] = new lang_string('anycourses', 'filters');
|
||||
$choices['systemrole'] = new lang_string('globalrole', 'role');
|
||||
$choices['cohort'] = new lang_string('idnumber', 'core_cohort');
|
||||
$choices['firstaccess'] = new lang_string('firstaccess', 'filters');
|
||||
$choices['lastaccess'] = new lang_string('lastaccess');
|
||||
$choices['neveraccessed'] = new lang_string('neveraccessed', 'filters');
|
||||
$choices['timemodified'] = new lang_string('lastmodified');
|
||||
$choices['nevermodified'] = new lang_string('nevermodified', 'filters');
|
||||
$choices['auth'] = new lang_string('authentication');
|
||||
$choices['idnumber'] = new lang_string('idnumber');
|
||||
$choices['lastip'] = new lang_string('lastip');
|
||||
$choices['mnethostid'] = new lang_string('mnetidprovider', 'mnet');
|
||||
$temp->add(new admin_setting_configmultiselect('userfiltersdefault', new lang_string('userfiltersdefault', 'admin'),
|
||||
new lang_string('userfiltersdefault_desc', 'admin'), array('realname'), $choices));
|
||||
}
|
||||
$ADMIN->add('accounts', $temp);
|
||||
|
||||
// User default preferences settingpage.
|
||||
// "User default preferences" settingpage.
|
||||
$temp = new admin_settingpage('userdefaultpreferences', new lang_string('userdefaultpreferences', 'admin'));
|
||||
if ($ADMIN->fulltree) {
|
||||
$choices = array();
|
||||
@@ -94,9 +62,9 @@ if ($hassiteconfig
|
||||
$ADMIN->add('accounts', new admin_externalpage('cohorts', new lang_string('cohorts', 'cohort'), $CFG->wwwroot . '/cohort/index.php', array('moodle/cohort:manage', 'moodle/cohort:view')));
|
||||
|
||||
|
||||
// Stuff under the "roles" subcategory.
|
||||
// stuff under the "roles" subcategory
|
||||
|
||||
// User policies settingpage.
|
||||
// "userpolicies" settingpage
|
||||
$temp = new admin_settingpage('userpolicies', new lang_string('userpolicies', 'admin'));
|
||||
if ($ADMIN->fulltree) {
|
||||
if (!during_initial_install()) {
|
||||
@@ -170,7 +138,7 @@ if ($hassiteconfig
|
||||
$temp->add(new admin_setting_configselect('restorernewroleid', new lang_string('restorernewroleid', 'admin'),
|
||||
new lang_string('restorernewroleid_help', 'admin'), $defaultteacherid, $restorersnewrole));
|
||||
|
||||
// Release memory.
|
||||
// release memory
|
||||
unset($otherroles);
|
||||
unset($guestroles);
|
||||
unset($userroles);
|
||||
@@ -241,7 +209,7 @@ if ($hassiteconfig
|
||||
$ADMIN->add('roles', new admin_externalpage('assignroles', new lang_string('assignglobalroles', 'role'), "$CFG->wwwroot/$CFG->admin/roles/assign.php?contextid=".$systemcontext->id, 'moodle/role:assign'));
|
||||
$ADMIN->add('roles', new admin_externalpage('checkpermissions', new lang_string('checkglobalpermissions', 'role'), "$CFG->wwwroot/$CFG->admin/roles/check.php?contextid=".$systemcontext->id, array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:manage')));
|
||||
|
||||
} // End of speedup.
|
||||
} // end of speedup
|
||||
|
||||
// Privacy settings.
|
||||
if ($hassiteconfig) {
|
||||
@@ -260,28 +228,10 @@ if ($hassiteconfig) {
|
||||
$temp->add($setting);
|
||||
|
||||
// See {@link https://gdpr-info.eu/art-8-gdpr/}.
|
||||
// See {@link https://www.betterinternetforkids.eu/web/portal/practice/awareness/detail?articleId=3017751}.
|
||||
$ageofdigitalconsentmap = implode(PHP_EOL, [
|
||||
'*, 16',
|
||||
'AT, 14',
|
||||
'BE, 13',
|
||||
'BG, 14',
|
||||
'CY, 14',
|
||||
'CZ, 15',
|
||||
'DK, 13',
|
||||
'EE, 13',
|
||||
'ES, 14',
|
||||
'FI, 13',
|
||||
'FR, 15',
|
||||
'GB, 13',
|
||||
'GR, 15',
|
||||
'IT, 14',
|
||||
'LT, 14',
|
||||
'LV, 13',
|
||||
'MT, 13',
|
||||
'NO, 13',
|
||||
'PT, 13',
|
||||
'SE, 13',
|
||||
'US, 13'
|
||||
]);
|
||||
$setting = new admin_setting_agedigitalconsentmap('agedigitalconsentmap',
|
||||
|
||||
+5
-4
@@ -40,14 +40,15 @@ $strheading = get_string('tasklogs', 'tool_task');
|
||||
$PAGE->set_title($strheading);
|
||||
$PAGE->set_heading($strheading);
|
||||
|
||||
require_login();
|
||||
|
||||
require_capability('moodle/site:config', context_system::instance());
|
||||
admin_externalpage_setup('tasklogs');
|
||||
|
||||
$logid = optional_param('logid', null, PARAM_INT);
|
||||
$download = optional_param('download', false, PARAM_BOOL);
|
||||
|
||||
if (null !== $logid) {
|
||||
// Raise memory limit in case the log is large.
|
||||
raise_memory_limit(MEMORY_HUGE);
|
||||
$log = $DB->get_record('task_log', ['id' => $logid], '*', MUST_EXIST);
|
||||
|
||||
if ($download) {
|
||||
@@ -55,7 +56,7 @@ if (null !== $logid) {
|
||||
header("Content-Disposition: attachment; filename=\"{$filename}\"");
|
||||
}
|
||||
|
||||
readstring_accel($log->output, 'text/plain');
|
||||
readstring_accel($log->output, 'text/plain', false);
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -64,7 +65,7 @@ $renderer = $PAGE->get_renderer('tool_task');
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->render_from_template('core_admin/tasklogs', (object) [
|
||||
'action' => $pageurl->out(),
|
||||
'filter' => htmlentities($filter),
|
||||
'filter' => $filter,
|
||||
'resultfilteroptions' => [
|
||||
(object) [
|
||||
'value' => -1,
|
||||
|
||||
@@ -49,28 +49,15 @@
|
||||
}}
|
||||
<div class="form-item row" id="{{id}}">
|
||||
<div class="form-label col-sm-3 text-sm-right">
|
||||
{{#customcontrol}}
|
||||
<p {{#labelfor}}id="{{labelfor}}_label"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="form-overridden">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="form-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</p>
|
||||
{{/customcontrol}}
|
||||
{{^customcontrol}}
|
||||
<label {{#labelfor}}for="{{labelfor}}"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="form-overridden">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="form-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</label>
|
||||
{{/customcontrol}}
|
||||
<label {{#labelfor}}for="{{labelfor}}"{{/labelfor}}>
|
||||
{{{title}}}
|
||||
{{#override}}
|
||||
<div class="form-overridden">{{override}}</div>
|
||||
{{/override}}
|
||||
{{#warning}}
|
||||
<div class="form-warning">{{warning}}</div>
|
||||
{{/warning}}
|
||||
</label>
|
||||
<span class="form-shortname d-block small text-muted">{{{name}}}</span>
|
||||
</div>
|
||||
<div class="form-setting col-sm-9">
|
||||
@@ -85,16 +72,3 @@
|
||||
{{#dependenton}}<div class="form-dependenton mb-4 text-muted">{{{.}}}</div>{{/dependenton}}
|
||||
</div>
|
||||
</div>
|
||||
{{#customcontrol}}
|
||||
{{#js}}
|
||||
require(['jquery'], function($) {
|
||||
$('#{{id}}_label').css('cursor', 'default');
|
||||
$('#{{id}}_label').click(function() {
|
||||
$('#{{id}}')
|
||||
.find('button, a, input:not([type="hidden"]), select, textarea, [tabindex]')
|
||||
.filter(':not([disabled]):not([tabindex="0"]):not([tabindex="-1"])')
|
||||
.first().focus();
|
||||
});
|
||||
});
|
||||
{{/js}}
|
||||
{{/customcontrol}}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
* value - yes value
|
||||
* id - element id
|
||||
* checked - boole
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
@@ -33,11 +32,10 @@
|
||||
"no": "False",
|
||||
"value": "True",
|
||||
"id": "test0",
|
||||
"checked": "checked",
|
||||
"readonly": false
|
||||
"checked": "checked"
|
||||
}
|
||||
}}
|
||||
<div class="form-checkbox defaultsnext">
|
||||
<input type="hidden" name="{{name}}" value="{{no}}">
|
||||
<input {{#readonly}}disabled{{/readonly}} type="checkbox" name="{{name}}" value="{{value}}" id="{{id}}" {{#checked}}checked{{/checked}}>
|
||||
<input type="checkbox" name="{{name}}" value="{{value}}" id="{{id}}" {{#checked}}checked{{/checked}}>
|
||||
</div>
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
* id - element id
|
||||
* value - element value
|
||||
* haspreviewconfig - show preview of selected color
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
@@ -33,7 +32,6 @@
|
||||
"name": "name0",
|
||||
"id": "id0",
|
||||
"value": "#555655",
|
||||
"readonly": false,
|
||||
"haspreviewconfig": false
|
||||
}
|
||||
}}
|
||||
@@ -46,7 +44,7 @@
|
||||
{{>core/pix_icon}}
|
||||
{{/icon}}
|
||||
</div>
|
||||
<input type="text" name="{{name}}" id="{{id}}" value="{{value}}" size="12" class="form-control text-ltr" {{#readonly}}disabled{{/readonly}}>
|
||||
<input type="text" name="{{name}}" id="{{id}}" value="{{value}}" size="12" class="form-control text-ltr">
|
||||
{{#haspreviewconfig}}
|
||||
<input type="button" id="{{id}}_preview" value={{#quote}}{{#str}}preview{{/str}}{{/quote}} class="admin_colourpicker_preview">
|
||||
{{/haspreviewconfig}}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"name": "test",
|
||||
"value": "/my-super-secret-path/",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"readonly": true,
|
||||
"showvalidity": true,
|
||||
"valid": false
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
* name - form element name
|
||||
* options - list of options for units containing name, value, selected
|
||||
* value - yes
|
||||
* readonly - bool
|
||||
* id - element id
|
||||
|
||||
Example context (json):
|
||||
@@ -31,7 +30,6 @@
|
||||
"name": "test",
|
||||
"value": "5",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"options": [ { "name": "Minutes", "value": "mins", "selected": true } ]
|
||||
}
|
||||
}}
|
||||
@@ -40,9 +38,9 @@
|
||||
}}
|
||||
<div class="form-duration defaultsnext">
|
||||
<div class="form-inline">
|
||||
<input type="text" size="5" id="{{id}}v" name="{{name}}[v]" value="{{value}}" class="form-control text-ltr" {{#readonly}}disabled{{/readonly}}>
|
||||
<input type="text" size="5" id="{{id}}v" name="{{name}}[v]" value="{{value}}" class="form-control text-ltr">
|
||||
<label class="sr-only" for="{{id}}u">{{#str}}durationunits, admin{{/str}}</label>
|
||||
<select id="{{id}}u" name="{{name}}[u]" class="form-control custom-select" {{#readonly}}disabled{{/readonly}}>
|
||||
<select id="{{id}}u" name="{{name}}[u]" class="form-control custom-select">
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"name": "test",
|
||||
"value": "/usr/bin/cowsay",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"readonly": true,
|
||||
"showvalidity": true,
|
||||
"valid": false
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
* readonly - Make the field readonly
|
||||
* value - value
|
||||
* showvalidity - Show a green check if the path is readable
|
||||
* readonly - bool
|
||||
* valid - True if the path is readable
|
||||
|
||||
Example context (json):
|
||||
@@ -34,9 +33,8 @@
|
||||
"name": "test",
|
||||
"value": "/my-super-secret-path/file",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"readonly": true,
|
||||
"showvalidity": true,
|
||||
"readonly": false,
|
||||
"valid": false
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -1,52 +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/>.
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_configfilesize
|
||||
|
||||
Admin file size setting template.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* options - list of options for units containing name, value, selected
|
||||
* value - yes
|
||||
* id - element id
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"value": "5",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"options": [ { "name": "KB", "value": "1024", "selected": true } ]
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
Setting configfilesize.
|
||||
}}
|
||||
<div class="form-filesize defaultsnext">
|
||||
<div class="form-inline">
|
||||
<input type="text" size="5" id="{{id}}v" name="{{name}}[v]" value="{{value}}" class="form-control text-ltr" {{#readonly}}disabled{{/readonly}}>
|
||||
<label class="sr-only" for="{{id}}u">{{#str}}filesizeunits, admin{{/str}}</label>
|
||||
<select id="{{id}}u" name="{{name}}[u]" class="form-control custom-select" {{#readonly}}disabled{{/readonly}}>
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,13 +24,11 @@
|
||||
* id - element id
|
||||
* size - element size
|
||||
* options - list of options containing name, value, selected
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"size": "3",
|
||||
"options": [ { "name": "Option 1", "value": "V", "selected": true },
|
||||
{ "name": "Option 2", "value": "V", "selected": true } ]
|
||||
@@ -41,7 +39,7 @@
|
||||
}}
|
||||
<div class="form-select">
|
||||
<input type="hidden" name="{{name}}[xxxxx]" value="1">
|
||||
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
|
||||
<select id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
|
||||
@@ -25,13 +25,11 @@
|
||||
* size - element size
|
||||
* options - list of options not grouped
|
||||
* optgroups - list of options grouped containing the group label and for each option: name, value, selected
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"size": "3",
|
||||
"options": [
|
||||
{ "name": "Option 1", "value": "V", "selected": false },
|
||||
@@ -60,7 +58,7 @@
|
||||
}}
|
||||
<div class="form-select">
|
||||
<input type="hidden" name="{{name}}[xxxxx]" value="1">
|
||||
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
|
||||
<select id="{{id}}" name="{{name}}[]" size="{{size}}" class="form-control" multiple>
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
|
||||
@@ -24,30 +24,15 @@
|
||||
* size - form element size
|
||||
* value - form element value
|
||||
* id - element id
|
||||
* readonly - has value been defined in config.php
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"size": "8",
|
||||
"value": "secret",
|
||||
"readonly": false
|
||||
"value": "secret"
|
||||
}
|
||||
}}
|
||||
{{#readonly}}
|
||||
<div class="form-password">
|
||||
<input type="text"
|
||||
name = "{{ name }}"
|
||||
id="{{ id }}"
|
||||
value="********"
|
||||
size="{{ size }}"
|
||||
class="form-control"
|
||||
disabled
|
||||
>
|
||||
</div>
|
||||
{{/readonly}}
|
||||
{{^readonly}}
|
||||
<div class="form-password">
|
||||
<span data-passwordunmask="wrapper" data-passwordunmaskid="{{ id }}">
|
||||
<span data-passwordunmask="editor">
|
||||
@@ -76,4 +61,3 @@ require(['core_form/passwordunmask'], function(PasswordUnmask) {
|
||||
new PasswordUnmask("{{ id }}");
|
||||
});
|
||||
{{/js}}
|
||||
{{/readonly}}
|
||||
|
||||
@@ -23,13 +23,11 @@
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* options - list of options containing name, value, selected
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"options": [
|
||||
{ "name": "Option 1", "value": "V", "selected": true },
|
||||
{ "name": "Option 2", "value": "V", "selected": true }
|
||||
@@ -40,7 +38,7 @@
|
||||
Setting configselect.
|
||||
}}
|
||||
<div class="form-select defaultsnext">
|
||||
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}" class="custom-select">
|
||||
<select id="{{id}}" name="{{name}}" class="custom-select">
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
Context variables required for this template:
|
||||
* name - form element name
|
||||
* id - element id
|
||||
* readonly - bool
|
||||
* options - list of options (not grouped)
|
||||
* optgroups - list of options grouped containing the group label and for each option: name, value, selected
|
||||
|
||||
@@ -30,7 +29,6 @@
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"options": [
|
||||
{ "name": "Option 1", "value": "V", "selected": false },
|
||||
{ "name": "Option 2", "value": "V", "selected": false }
|
||||
@@ -57,7 +55,7 @@
|
||||
Setting configselect with optgroup support.
|
||||
}}
|
||||
<div class="form-select defaultsnext">
|
||||
<select {{#readonly}}disabled{{/readonly}} id="{{id}}" name="{{name}}" class="custom-select">
|
||||
<select id="{{id}}" name="{{name}}" class="custom-select">
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/options}}
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
* size - element size
|
||||
* forceltr - always display as ltr
|
||||
* attributes - list of additional attributes containing name, value
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
@@ -35,7 +34,6 @@
|
||||
"value": "A tall, dark stranger will have more fun than you.",
|
||||
"size": "21",
|
||||
"forceltr": false,
|
||||
"readonly": false,
|
||||
"attributes": [ { "name": "readonly", "value": "readonly" } ]
|
||||
}
|
||||
}}
|
||||
@@ -43,5 +41,5 @@
|
||||
Setting configtext.
|
||||
}}
|
||||
<div class="form-text defaultsnext">
|
||||
<input type="text" name="{{name}}" value="{{value}}" size="{{size}}" id="{{id}}" class="form-control {{#forceltr}}text-ltr{{/forceltr}}" {{#readonly}}disabled{{/readonly}}>
|
||||
<input type="text" name="{{name}}" value="{{value}}" size="{{size}}" id="{{id}}" class="form-control {{#forceltr}}text-ltr{{/forceltr}}">
|
||||
</div>
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
"cols": "30",
|
||||
"rows": "3",
|
||||
"value": "Excellent day for putting Slinkies on an escalator.",
|
||||
"readonly": false,
|
||||
"id": "test0"
|
||||
}
|
||||
}}
|
||||
@@ -41,5 +40,5 @@
|
||||
Setting configtextarea.
|
||||
}}
|
||||
<div class="form-textarea">
|
||||
<textarea {{#readonly}}disabled{{/readonly}} rows="{{rows}}" cols="{{cols}}" id="{{id}}" name="{{name}}" spellcheck="true" class="form-control {{#forceltr}}text-ltr{{/forceltr}}">{{value}}</textarea>
|
||||
<textarea rows="{{rows}}" cols="{{cols}}" id="{{id}}" name="{{name}}" spellcheck="true" class="form-control {{#forceltr}}text-ltr{{/forceltr}}">{{value}}</textarea>
|
||||
</div>
|
||||
|
||||
@@ -24,13 +24,11 @@
|
||||
* id - element id
|
||||
* hours - list of valid hour options containing name, value, selected
|
||||
* minutes - list of valid minute options containing name, value, selected
|
||||
* readonly - bool
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "test",
|
||||
"id": "test0",
|
||||
"readonly": false,
|
||||
"minutes": [
|
||||
{ "name": "00", "value": "0", "selected": true },
|
||||
{ "name": "01", "value": "1", "selected": false }
|
||||
@@ -47,13 +45,13 @@
|
||||
<div class="form-time defaultsnext">
|
||||
<div class="form-inline text-ltr">
|
||||
<label class="sr-only" for="{{id}}h">{{#str}}hours{{/str}}</label>
|
||||
<select id="{{id}}h" name="{{name}}[h]" class="custom-select" {{#readonly}}disabled{{/readonly}}>
|
||||
<select id="{{id}}h" name="{{name}}[h]" class="custom-select">
|
||||
{{#hours}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/hours}}
|
||||
</select>:
|
||||
<label class="sr-only" for="{{id}}m">{{#str}}minutes{{/str}}</label>
|
||||
<select id="{{id}}m" name="{{name}}[m]" class="custom-select" {{#readonly}}disabled{{/readonly}}>
|
||||
<select id="{{id}}m" name="{{name}}[m]" class="custom-select">
|
||||
{{#minutes}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{name}}</option>
|
||||
{{/minutes}}
|
||||
|
||||
@@ -46,8 +46,7 @@ if ($data) {
|
||||
$emailuser->email = $data->recipient;
|
||||
$emailuser->id = -99;
|
||||
|
||||
$subject = get_string('testoutgoingmailconf_subject', 'admin',
|
||||
format_string($SITE->fullname, true, ['context' => context_system::instance()]));
|
||||
$subject = get_string('testoutgoingmailconf_subject', 'admin', $SITE->fullname);
|
||||
$messagetext = get_string('testoutgoingmailconf_message', 'admin');
|
||||
|
||||
// Manage Moodle debugging options.
|
||||
|
||||
@@ -6,11 +6,11 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email | auth | confirmed | lastip |
|
||||
| user1 | User | One | one@example.com | manual | 0 | 127.0.1.1 |
|
||||
| user2 | User | Two | two@example.com | ldap | 1 | 0.0.0.0 |
|
||||
| user3 | User | Three | three@example.com | manual | 1 | 0.0.0.0 |
|
||||
| user4 | User | Four | four@example.com | ldap | 0 | 127.0.1.2 |
|
||||
| username | firstname | lastname | email | auth | confirmed |
|
||||
| user1 | User | One | one@example.com | manual | 0 |
|
||||
| user2 | User | Two | two@example.com | ldap | 1 |
|
||||
| user3 | User | Three | three@example.com | manual | 1 |
|
||||
| user4 | User | Four | four@example.com | ldap | 0 |
|
||||
And the following "cohorts" exist:
|
||||
| name | idnumber |
|
||||
| Cohort 1 | CH1 |
|
||||
@@ -82,25 +82,3 @@ Feature: An administrator can filter user accounts by role, cohort and other pro
|
||||
And I should not see "User Two"
|
||||
And I should not see "User Three"
|
||||
And I should see "User Four"
|
||||
|
||||
Scenario: Filter user accounts by last IP address
|
||||
When I set the following fields to these values:
|
||||
| id_lastip | 127.0.1.1 |
|
||||
And I press "Add filter"
|
||||
Then I should see "User One"
|
||||
And I should not see "User Two"
|
||||
And I should not see "User Three"
|
||||
And I should not see "User Four"
|
||||
And I press "Remove all filters"
|
||||
And I set the following fields to these values:
|
||||
| id_lastip | 127.0.1.2 |
|
||||
And I press "Add filter"
|
||||
And I should not see "User One"
|
||||
And I should not see "User Two"
|
||||
And I should not see "User Three"
|
||||
And I should see "User Four"
|
||||
And I press "Remove all filters"
|
||||
And I should see "User One"
|
||||
And I should see "User Two"
|
||||
And I should see "User Three"
|
||||
And I should see "User Four"
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
@core @core_admin @javascript
|
||||
Feature: An administrator can configure the available user list filters
|
||||
In order to have all needed user filters instantly at hand
|
||||
As an admin
|
||||
I want to configure the filters which are shown as default
|
||||
|
||||
Scenario: Do not change the user filter default configuration
|
||||
When I log in as "admin"
|
||||
And I navigate to "Users > Accounts > Browse list of users" in site administration
|
||||
Then I should see "User full name"
|
||||
And I should not see "Surname" in the "New filter" "fieldset"
|
||||
And I should not see "Firstname" in the "New filter" "fieldset"
|
||||
And I should not see "Username" in the "New filter" "fieldset"
|
||||
And I should not see "Email address" in the "New filter" "fieldset"
|
||||
And I should not see "City/town" in the "New filter" "fieldset"
|
||||
And I should not see "Country" in the "New filter" "fieldset"
|
||||
And I should not see "Confirmed" in the "New filter" "fieldset"
|
||||
And I should not see "Suspended account" in the "New filter" "fieldset"
|
||||
And I should not see "User profile fields" in the "New filter" "fieldset"
|
||||
And I should not see "Course role" in the "New filter" "fieldset"
|
||||
And I should not see "Enrolled in any course" in the "New filter" "fieldset"
|
||||
And I should not see "System role" in the "New filter" "fieldset"
|
||||
And I should not see "Cohort ID" in the "New filter" "fieldset"
|
||||
And I should not see "First access" in the "New filter" "fieldset"
|
||||
And I should not see "Last access" in the "New filter" "fieldset"
|
||||
And I should not see "Last modified" in the "New filter" "fieldset"
|
||||
And I should not see "Authentication" in the "New filter" "fieldset"
|
||||
And I should not see "ID number" in the "New filter" "fieldset"
|
||||
And I should not see "Last IP address" in the "New filter" "fieldset"
|
||||
And I should not see "MNet ID provider" in the "New filter" "fieldset"
|
||||
And I navigate to "Users > Accounts > Bulk user actions" in site administration
|
||||
Then I should see "User full name"
|
||||
And I should not see "Surname" in the "New filter" "fieldset"
|
||||
And I should not see "Firstname" in the "New filter" "fieldset"
|
||||
And I should not see "Username" in the "New filter" "fieldset"
|
||||
And I should not see "Email address" in the "New filter" "fieldset"
|
||||
And I should not see "City/town" in the "New filter" "fieldset"
|
||||
And I should not see "Country" in the "New filter" "fieldset"
|
||||
And I should not see "Confirmed" in the "New filter" "fieldset"
|
||||
And I should not see "Suspended account" in the "New filter" "fieldset"
|
||||
And I should not see "User profile fields" in the "New filter" "fieldset"
|
||||
And I should not see "Course role" in the "New filter" "fieldset"
|
||||
And I should not see "Enrolled in any course" in the "New filter" "fieldset"
|
||||
And I should not see "System role" in the "New filter" "fieldset"
|
||||
And I should not see "Cohort ID" in the "New filter" "fieldset"
|
||||
And I should not see "First access" in the "New filter" "fieldset"
|
||||
And I should not see "Last access" in the "New filter" "fieldset"
|
||||
And I should not see "Last modified" in the "New filter" "fieldset"
|
||||
And I should not see "Authentication" in the "New filter" "fieldset"
|
||||
And I should not see "ID number" in the "New filter" "fieldset"
|
||||
And I should not see "Last IP address" in the "New filter" "fieldset"
|
||||
And I should not see "MNet ID provider" in the "New filter" "fieldset"
|
||||
|
||||
Scenario: Change the user filter default configuration to something else
|
||||
Given the following config values are set as admin:
|
||||
| userfiltersdefault | realname,username,email |
|
||||
And I log in as "admin"
|
||||
And I navigate to "Users > Accounts > Browse list of users" in site administration
|
||||
Then I should see "User full name"
|
||||
And I should not see "Surname" in the "New filter" "fieldset"
|
||||
And I should not see "Firstname" in the "New filter" "fieldset"
|
||||
And I should see "Username" in the "New filter" "fieldset"
|
||||
And I should see "Email address" in the "New filter" "fieldset"
|
||||
And I should not see "City/town" in the "New filter" "fieldset"
|
||||
And I should not see "Country" in the "New filter" "fieldset"
|
||||
And I should not see "Confirmed" in the "New filter" "fieldset"
|
||||
And I should not see "Suspended account" in the "New filter" "fieldset"
|
||||
And I should not see "User profile fields" in the "New filter" "fieldset"
|
||||
And I should not see "Course role" in the "New filter" "fieldset"
|
||||
And I should not see "Enrolled in any course" in the "New filter" "fieldset"
|
||||
And I should not see "System role" in the "New filter" "fieldset"
|
||||
And I should not see "Cohort ID" in the "New filter" "fieldset"
|
||||
And I should not see "First access" in the "New filter" "fieldset"
|
||||
And I should not see "Last access" in the "New filter" "fieldset"
|
||||
And I should not see "Last modified" in the "New filter" "fieldset"
|
||||
And I should not see "Authentication" in the "New filter" "fieldset"
|
||||
And I should not see "ID number" in the "New filter" "fieldset"
|
||||
And I should not see "Last IP address" in the "New filter" "fieldset"
|
||||
And I should not see "MNet ID provider" in the "New filter" "fieldset"
|
||||
And I navigate to "Users > Accounts > Bulk user actions" in site administration
|
||||
Then I should see "User full name"
|
||||
And I should not see "Surname" in the "New filter" "fieldset"
|
||||
And I should not see "Firstname" in the "New filter" "fieldset"
|
||||
And I should see "Username" in the "New filter" "fieldset"
|
||||
And I should see "Email address" in the "New filter" "fieldset"
|
||||
And I should not see "City/town" in the "New filter" "fieldset"
|
||||
And I should not see "Country" in the "New filter" "fieldset"
|
||||
And I should not see "Confirmed" in the "New filter" "fieldset"
|
||||
And I should not see "Suspended account" in the "New filter" "fieldset"
|
||||
And I should not see "User profile fields" in the "New filter" "fieldset"
|
||||
And I should not see "Course role" in the "New filter" "fieldset"
|
||||
And I should not see "Enrolled in any course" in the "New filter" "fieldset"
|
||||
And I should not see "System role" in the "New filter" "fieldset"
|
||||
And I should not see "Cohort ID" in the "New filter" "fieldset"
|
||||
And I should not see "First access" in the "New filter" "fieldset"
|
||||
And I should not see "Last access" in the "New filter" "fieldset"
|
||||
And I should not see "Last modified" in the "New filter" "fieldset"
|
||||
And I should not see "Authentication" in the "New filter" "fieldset"
|
||||
And I should not see "ID number" in the "New filter" "fieldset"
|
||||
And I should not see "Last IP address" in the "New filter" "fieldset"
|
||||
And I should not see "MNet ID provider" in the "New filter" "fieldset"
|
||||
|
||||
Scenario: Change the user filter default configuration to no filter at all
|
||||
Given the following config values are set as admin:
|
||||
| userfiltersdefault | |
|
||||
And I log in as "admin"
|
||||
And I navigate to "Users > Accounts > Browse list of users" in site administration
|
||||
Then I should see "User full name"
|
||||
And I should not see "Surname" in the "New filter" "fieldset"
|
||||
And I should not see "Firstname" in the "New filter" "fieldset"
|
||||
And I should not see "Username" in the "New filter" "fieldset"
|
||||
And I should not see "Email address" in the "New filter" "fieldset"
|
||||
And I should not see "City/town" in the "New filter" "fieldset"
|
||||
And I should not see "Country" in the "New filter" "fieldset"
|
||||
And I should not see "Confirmed" in the "New filter" "fieldset"
|
||||
And I should not see "Suspended account" in the "New filter" "fieldset"
|
||||
And I should not see "User profile fields" in the "New filter" "fieldset"
|
||||
And I should not see "Course role" in the "New filter" "fieldset"
|
||||
And I should not see "Enrolled in any course" in the "New filter" "fieldset"
|
||||
And I should not see "System role" in the "New filter" "fieldset"
|
||||
And I should not see "Cohort ID" in the "New filter" "fieldset"
|
||||
And I should not see "First access" in the "New filter" "fieldset"
|
||||
And I should not see "Last access" in the "New filter" "fieldset"
|
||||
And I should not see "Last modified" in the "New filter" "fieldset"
|
||||
And I should not see "Authentication" in the "New filter" "fieldset"
|
||||
And I should not see "ID number" in the "New filter" "fieldset"
|
||||
And I should not see "Last IP address" in the "New filter" "fieldset"
|
||||
And I should not see "MNet ID provider" in the "New filter" "fieldset"
|
||||
And I navigate to "Users > Accounts > Bulk user actions" in site administration
|
||||
Then I should see "User full name"
|
||||
And I should not see "Surname" in the "New filter" "fieldset"
|
||||
And I should not see "Firstname" in the "New filter" "fieldset"
|
||||
And I should not see "Username" in the "New filter" "fieldset"
|
||||
And I should not see "Email address" in the "New filter" "fieldset"
|
||||
And I should not see "City/town" in the "New filter" "fieldset"
|
||||
And I should not see "Country" in the "New filter" "fieldset"
|
||||
And I should not see "Confirmed" in the "New filter" "fieldset"
|
||||
And I should not see "Suspended account" in the "New filter" "fieldset"
|
||||
And I should not see "User profile fields" in the "New filter" "fieldset"
|
||||
And I should not see "Course role" in the "New filter" "fieldset"
|
||||
And I should not see "Enrolled in any course" in the "New filter" "fieldset"
|
||||
And I should not see "System role" in the "New filter" "fieldset"
|
||||
And I should not see "Cohort ID" in the "New filter" "fieldset"
|
||||
And I should not see "First access" in the "New filter" "fieldset"
|
||||
And I should not see "Last access" in the "New filter" "fieldset"
|
||||
And I should not see "Last modified" in the "New filter" "fieldset"
|
||||
And I should not see "Authentication" in the "New filter" "fieldset"
|
||||
And I should not see "ID number" in the "New filter" "fieldset"
|
||||
And I should not see "Last IP address" in the "New filter" "fieldset"
|
||||
And I should not see "MNet ID provider" in the "New filter" "fieldset"
|
||||
@@ -1,29 +0,0 @@
|
||||
@core @core_admin
|
||||
Feature: Administrator is warned and when trying to set invalid allcountrycodes value.
|
||||
In order to avoid misconfiguration of the country selector fields
|
||||
As an admin
|
||||
I want to be warned when I try to set an invalid country code in the allcountrycodes field
|
||||
|
||||
Scenario: Attempting to set allcountrycodes field with valid country codes
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Location > Location settings" in site administration
|
||||
When I set the following administration settings values:
|
||||
| All country codes | CZ,BE,GB,ES |
|
||||
Then I should not see "Invalid country code"
|
||||
|
||||
Scenario: Attempting to set allcountrycodes field with invalid country code
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Location > Location settings" in site administration
|
||||
When I set the following administration settings values:
|
||||
| All country codes | CZ,BE,FOOBAR,GB,ES |
|
||||
Then I should see "Invalid country code: FOOBAR"
|
||||
|
||||
Scenario: Attempting to unset allcountrycodes field
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Location > Location settings" in site administration
|
||||
And I set the following administration settings values:
|
||||
| All country codes | CZ,BE,GB,ES |
|
||||
And I navigate to "Location > Location settings" in site administration
|
||||
When I set the following administration settings values:
|
||||
| All country codes | |
|
||||
Then I should not see "Invalid country code"
|
||||
@@ -1,34 +0,0 @@
|
||||
@core @core_admin
|
||||
Feature: Configure language settings for the site
|
||||
In order to configure language settings for the site
|
||||
As an admin
|
||||
I want to set language settings relevant to my site users
|
||||
|
||||
Scenario: Set languages on language menu
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language settings" in site administration
|
||||
When I set the field "Languages on language menu" to "en"
|
||||
And I press "Save changes"
|
||||
Then I should not see "Invalid language code"
|
||||
|
||||
Scenario: Reset languages on language menu
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language settings" in site administration
|
||||
When I set the field "Languages on language menu" to ""
|
||||
And I press "Save changes"
|
||||
Then I should not see "Invalid language code"
|
||||
|
||||
Scenario Outline: Set languages on language menu with invalid language
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language settings" in site administration
|
||||
When I set the field "Languages on language menu" to "<fieldvalue>"
|
||||
And I press "Save changes"
|
||||
Then I should see "Invalid language code: <invalidlang>"
|
||||
Examples:
|
||||
| fieldvalue | invalidlang |
|
||||
| xx | xx |
|
||||
| xx\|Bad | xx |
|
||||
| en,qq | qq |
|
||||
| en,qq\|Bad | qq |
|
||||
| en$$ | en$$ |
|
||||
| en$$\|Bad | en$$ |
|
||||
+3
-1
@@ -12,7 +12,9 @@
|
||||
$PAGE->set_url('/admin/timezone.php');
|
||||
$PAGE->set_context(context_system::instance());
|
||||
|
||||
require_admin();
|
||||
require_login();
|
||||
|
||||
require_capability('moodle/site:config', context_system::instance());
|
||||
|
||||
$strtimezone = get_string("timezone");
|
||||
$strsavechanges = get_string("savechanges");
|
||||
|
||||
+1
-2
@@ -1,2 +1 @@
|
||||
define ("tool_analytics/log_info",["jquery","core/str","core/modal_factory","core/notification"],function(a,b,c,d){return{loadInfo:function loadInfo(e,f){var g=a("[data-model-log-id=\""+e+"\"]");b.get_string("loginfo","tool_analytics").then(function(b){var d=a("<ul>");f.forEach(function(a){d.append("<li>"+a+"</li>")});d.append("</ul>");return c.create({title:b,body:d.html(),large:!0},g)}).catch(d.exception)}}});
|
||||
//# sourceMappingURL=log_info.min.js.map
|
||||
define(["jquery","core/str","core/modal_factory","core/notification"],function(a,b,c,d){return{loadInfo:function(e,f){var g=a('[data-model-log-id="'+e+'"]');b.get_string("loginfo","tool_analytics").then(function(b){var d=a("<ul>");return f.forEach(function(a){d.append("<li>"+a+"</li>")}),d.append("</ul>"),c.create({title:b,body:d.html(),large:!0},g)})["catch"](d.exception)}}});
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":["../src/log_info.js"],"names":["define","$","str","ModalFactory","Notification","loadInfo","id","info","link","get_string","then","langString","bodyInfo","forEach","item","append","create","title","body","html","large","catch","exception"],"mappings":"AAwBAA,OAAM,2BAAC,CAAC,QAAD,CAAW,UAAX,CAAuB,oBAAvB,CAA6C,mBAA7C,CAAD,CAAoE,SAASC,CAAT,CAAYC,CAAZ,CAAiBC,CAAjB,CAA+BC,CAA/B,CAA6C,CAEnH,MAAoD,CAShDC,QAAQ,CAAE,kBAASC,CAAT,CAAaC,CAAb,CAAmB,CAEzB,GAAIC,CAAAA,CAAI,CAAGP,CAAC,CAAC,wBAAyBK,CAAzB,CAA8B,KAA/B,CAAZ,CACAJ,CAAG,CAACO,UAAJ,CAAe,SAAf,CAA0B,gBAA1B,EAA4CC,IAA5C,CAAiD,SAASC,CAAT,CAAqB,CAElE,GAAIC,CAAAA,CAAQ,CAAGX,CAAC,CAAC,MAAD,CAAhB,CACAM,CAAI,CAACM,OAAL,CAAa,SAASC,CAAT,CAAe,CACxBF,CAAQ,CAACG,MAAT,CAAgB,OAASD,CAAT,CAAgB,OAAhC,CACH,CAFD,EAGAF,CAAQ,CAACG,MAAT,CAAgB,OAAhB,EAEA,MAAOZ,CAAAA,CAAY,CAACa,MAAb,CAAoB,CACvBC,KAAK,CAAEN,CADgB,CAEvBO,IAAI,CAAEN,CAAQ,CAACO,IAAT,EAFiB,CAGvBC,KAAK,GAHkB,CAApB,CAIJZ,CAJI,CAMV,CAdD,EAcGa,KAdH,CAcSjB,CAAY,CAACkB,SAdtB,CAeH,CA3B+C,CA6BvD,CA/BK,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Shows a dialogue with info about this logs.\n *\n * @module tool_analytics/log_info\n * @class log_info\n * @package tool_analytics\n * @copyright 2017 David Monllao {@link http://www.davidmonllao.com}\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/str', 'core/modal_factory', 'core/notification'], function($, str, ModalFactory, Notification) {\n\n return /** @alias module:tool_analytics/log_info */ {\n\n /**\n * Prepares a modal info for a log's results.\n *\n * @method loadInfo\n * @param {int} id\n * @param {string[]} info\n */\n loadInfo: function(id, info) {\n\n var link = $('[data-model-log-id=\"' + id + '\"]');\n str.get_string('loginfo', 'tool_analytics').then(function(langString) {\n\n var bodyInfo = $(\"<ul>\");\n info.forEach(function(item) {\n bodyInfo.append('<li>' + item + '</li>');\n });\n bodyInfo.append(\"</ul>\");\n\n return ModalFactory.create({\n title: langString,\n body: bodyInfo.html(),\n large: true,\n }, link);\n\n }).catch(Notification.exception);\n }\n };\n});\n"],"file":"log_info.min.js"}
|
||||
+1
-2
@@ -1,2 +1 @@
|
||||
define ("tool_analytics/model",["jquery","core/str","core/log","core/notification","core/modal_factory","core/modal_events","core/templates"],function(b,c,d,e,f,g,h){var i={clear:{title:{key:"clearpredictions",component:"tool_analytics"},body:{key:"clearmodelpredictions",component:"tool_analytics"}},delete:{title:{key:"delete",component:"tool_analytics"},body:{key:"deletemodelconfirmation",component:"tool_analytics"}}},j=function(a){var c=b(a).closest("[data-model-name]");if(c.length){return c.attr("data-model-name")}else{d.error("Unexpected DOM error - unable to obtain the model name");return""}};return{confirmAction:function confirmAction(a,h){b("[data-action-id=\""+a+"\"]").on("click",function(k){k.preventDefault();var l=b(k.currentTarget);if("undefined"==typeof i[h]){d.error("Action \""+h+"\" is not allowed.");return}var a=[i[h].title,i[h].body];a[1].param=j(l);var m=c.get_strings(a),n=f.create({type:f.types.SAVE_CANCEL});b.when(m,n).then(function(a,b){b.setTitle(a[0]);b.setBody(a[1]);b.setSaveButtonText(a[0]);b.getRoot().on(g.save,function(){window.location.href=l.attr("href")});b.show();return b}).fail(e.exception)})},selectEvaluationOptions:function selectEvaluationOptions(a,d){b("[data-action-id=\""+a+"\"]").on("click",function(i){i.preventDefault();var j=b(i.currentTarget),a=b(this).attr("data-timesplitting-methods"),k=c.get_strings([{key:"evaluatemodel",component:"tool_analytics"},{key:"evaluate",component:"tool_analytics"}]),l=f.create({type:f.types.SAVE_CANCEL}),m=h.render("tool_analytics/evaluation_options",{trainedexternally:d,timesplittingmethods:JSON.parse(a)});b.when(k,l).then(function(a,c){c.getRoot().on(g.hidden,c.destroy.bind(c));c.setTitle(a[0]);c.setSaveButtonText(a[1]);c.setBody(m);c.getRoot().on(g.save,function(){var a=b("input[name='evaluationmode']:checked").val();if("trainedmodel"==a){j.attr("href",j.attr("href")+"&mode=trainedmodel")}var c=b("#id-evaluation-timesplitting").val();j.attr("href",j.attr("href")+"×plitting="+c);window.location.href=j.attr("href")});c.show();return c}).fail(e.exception)})},selectExportOptions:function selectExportOptions(a,d){b("[data-action-id=\""+a+"\"]").on("click",function(i){i.preventDefault();var j=b(i.currentTarget);if(!d){j.attr("href",j.attr("href")+"&action=exportmodel&includeweights=0");window.location.href=j.attr("href");return}var a=c.get_strings([{key:"export",component:"tool_analytics"}]),k=f.create({type:f.types.SAVE_CANCEL}),l=h.render("tool_analytics/export_options",{});b.when(a,k).then(function(a,c){c.getRoot().on(g.hidden,c.destroy.bind(c));c.setTitle(a[0]);c.setSaveButtonText(a[0]);c.setBody(l);c.getRoot().on(g.save,function(){var a=b("input[name='exportoption']:checked").val();if("exportdata"==a){j.attr("href",j.attr("href")+"&action=exportdata")}else{j.attr("href",j.attr("href")+"&action=exportmodel");if(b("#id-includeweights").is(":checked")){j.attr("href",j.attr("href")+"&includeweights=1")}else{j.attr("href",j.attr("href")+"&includeweights=0")}}window.location.href=j.attr("href")});c.show();return c}).fail(e.exception)})}}});
|
||||
//# sourceMappingURL=model.min.js.map
|
||||
define(["jquery","core/str","core/log","core/notification","core/modal_factory","core/modal_events","core/templates"],function(a,b,c,d,e,f,g){var h={clear:{title:{key:"clearpredictions",component:"tool_analytics"},body:{key:"clearmodelpredictions",component:"tool_analytics"}},"delete":{title:{key:"delete",component:"tool_analytics"},body:{key:"deletemodelconfirmation",component:"tool_analytics"}}},i=function(b){var d=a(b).closest("[data-model-name]");return d.length?d.attr("data-model-name"):(c.error("Unexpected DOM error - unable to obtain the model name"),"")};return{confirmAction:function(g,j){a('[data-action-id="'+g+'"]').on("click",function(g){g.preventDefault();var k=a(g.currentTarget);if("undefined"==typeof h[j])return void c.error('Action "'+j+'" is not allowed.');var l=[h[j].title,h[j].body];l[1].param=i(k);var m=b.get_strings(l),n=e.create({type:e.types.SAVE_CANCEL});a.when(m,n).then(function(a,b){return b.setTitle(a[0]),b.setBody(a[1]),b.setSaveButtonText(a[0]),b.getRoot().on(f.save,function(){window.location.href=k.attr("href")}),b.show(),b}).fail(d.exception)})},selectEvaluationOptions:function(c,h,i){a('[data-action-id="'+c+'"]').on("click",function(c){c.preventDefault();var j=a(c.currentTarget),k=b.get_strings([{key:"evaluatemodel",component:"tool_analytics"},{key:"evaluate",component:"tool_analytics"}]),l=e.create({type:e.types.SAVE_CANCEL}),m=g.render("tool_analytics/evaluation_options",{trainedexternally:h,timesplittingmethods:i});a.when(k,l).then(function(b,c){return c.getRoot().on(f.hidden,c.destroy.bind(c)),c.setTitle(b[0]),c.setSaveButtonText(b[1]),c.setBody(m),c.getRoot().on(f.save,function(){var b=a("input[name='evaluationmode']:checked").val();"trainedmodel"==b&&j.attr("href",j.attr("href")+"&mode=trainedmodel");var c=a("#id-evaluation-timesplitting").val();j.attr("href",j.attr("href")+"×plitting="+c),window.location.href=j.attr("href")}),c.show(),c}).fail(d.exception)})},selectExportOptions:function(c,h){a('[data-action-id="'+c+'"]').on("click",function(c){c.preventDefault();var i=a(c.currentTarget);if(!h)return i.attr("href",i.attr("href")+"&action=exportmodel&includeweights=0"),void(window.location.href=i.attr("href"));var j=b.get_strings([{key:"export",component:"tool_analytics"}]),k=e.create({type:e.types.SAVE_CANCEL}),l=g.render("tool_analytics/export_options",{});a.when(j,k).then(function(b,c){return c.getRoot().on(f.hidden,c.destroy.bind(c)),c.setTitle(b[0]),c.setSaveButtonText(b[0]),c.setBody(l),c.getRoot().on(f.save,function(){var b=a("input[name='exportoption']:checked").val();"exportdata"==b?i.attr("href",i.attr("href")+"&action=exportdata"):(i.attr("href",i.attr("href")+"&action=exportmodel"),a("#id-includeweights").is(":checked")?i.attr("href",i.attr("href")+"&includeweights=1"):i.attr("href",i.attr("href")+"&includeweights=0")),window.location.href=i.attr("href")}),c.show(),c}).fail(d.exception)})}}});
|
||||
File diff suppressed because one or more lines are too long
@@ -1,2 +0,0 @@
|
||||
define ("tool_analytics/potential-contexts",["jquery","core/ajax"],function(a,b){return{processResults:function processResults(b,c){var d=[];if(a.isArray(c)){a.each(c,function(a,b){d.push({value:b.id,label:b.name})});return d}else{return c}},transport:function transport(c,d,e,f){var g,h=a(c).attr("modelid")||null;g=b.call([{methodname:"tool_analytics_potential_contexts",args:{query:d,modelid:h}}]);g[0].then(e).fail(f)}}});
|
||||
//# sourceMappingURL=potential-contexts.min.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":["../src/potential-contexts.js"],"names":["define","$","Ajax","processResults","selector","results","contexts","isArray","each","index","context","push","value","id","label","name","transport","query","success","failure","promise","modelid","attr","call","methodname","args","then","fail"],"mappings":"AAyBAA,OAAM,qCAAC,CAAC,QAAD,CAAW,WAAX,CAAD,CAA0B,SAASC,CAAT,CAAYC,CAAZ,CAAkB,CAE9C,MAA8D,CAE1DC,cAAc,CAAE,wBAASC,CAAT,CAAmBC,CAAnB,CAA4B,CACxC,GAAIC,CAAAA,CAAQ,CAAG,EAAf,CACA,GAAIL,CAAC,CAACM,OAAF,CAAUF,CAAV,CAAJ,CAAwB,CACpBJ,CAAC,CAACO,IAAF,CAAOH,CAAP,CAAgB,SAASI,CAAT,CAAgBC,CAAhB,CAAyB,CACrCJ,CAAQ,CAACK,IAAT,CAAc,CACVC,KAAK,CAAEF,CAAO,CAACG,EADL,CAEVC,KAAK,CAAEJ,CAAO,CAACK,IAFL,CAAd,CAIH,CALD,EAMA,MAAOT,CAAAA,CAEV,CATD,IASO,CACH,MAAOD,CAAAA,CACV,CACJ,CAhByD,CAkB1DW,SAAS,CAAE,mBAASZ,CAAT,CAAmBa,CAAnB,CAA0BC,CAA1B,CAAmCC,CAAnC,CAA4C,IAC/CC,CAAAA,CAD+C,CAG/CC,CAAO,CAAGpB,CAAC,CAACG,CAAD,CAAD,CAAYkB,IAAZ,CAAiB,SAAjB,GAA+B,IAHM,CAInDF,CAAO,CAAGlB,CAAI,CAACqB,IAAL,CAAU,CAAC,CACjBC,UAAU,CAAE,mCADK,CAEjBC,IAAI,CAAE,CACFR,KAAK,CAAEA,CADL,CAEFI,OAAO,CAAEA,CAFP,CAFW,CAAD,CAAV,CAAV,CAQAD,CAAO,CAAC,CAAD,CAAP,CAAWM,IAAX,CAAgBR,CAAhB,EAAyBS,IAAzB,CAA8BR,CAA9B,CACH,CA/ByD,CAmCjE,CArCK,CAAN","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Potential contexts selector module.\n *\n * @module tool_analytics/potential-contexts\n * @class potential-contexts\n * @package tool_analytics\n * @copyright 2019 David Monllao\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['jquery', 'core/ajax'], function($, Ajax) {\n\n return /** @alias module:tool_analytics/potential-contexts */ {\n\n processResults: function(selector, results) {\n var contexts = [];\n if ($.isArray(results)) {\n $.each(results, function(index, context) {\n contexts.push({\n value: context.id,\n label: context.name\n });\n });\n return contexts;\n\n } else {\n return results;\n }\n },\n\n transport: function(selector, query, success, failure) {\n var promise;\n\n let modelid = $(selector).attr('modelid') || null;\n promise = Ajax.call([{\n methodname: 'tool_analytics_potential_contexts',\n args: {\n query: query,\n modelid: modelid\n }\n }]);\n\n promise[0].then(success).fail(failure);\n }\n\n };\n\n});\n"],"file":"potential-contexts.min.js"}
|
||||
@@ -114,14 +114,12 @@ define(['jquery', 'core/str', 'core/log', 'core/notification', 'core/modal_facto
|
||||
* @param {String} actionId
|
||||
* @param {Boolean} trainedOnlyExternally
|
||||
*/
|
||||
selectEvaluationOptions: function(actionId, trainedOnlyExternally) {
|
||||
selectEvaluationOptions: function(actionId, trainedOnlyExternally, timeSplittingMethods) {
|
||||
$('[data-action-id="' + actionId + '"]').on('click', function(ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
var a = $(ev.currentTarget);
|
||||
|
||||
var timeSplittingMethods = $(this).attr('data-timesplitting-methods');
|
||||
|
||||
var stringsPromise = Str.get_strings([
|
||||
{
|
||||
key: 'evaluatemodel',
|
||||
@@ -134,7 +132,7 @@ define(['jquery', 'core/str', 'core/log', 'core/notification', 'core/modal_facto
|
||||
var modalPromise = ModalFactory.create({type: ModalFactory.types.SAVE_CANCEL});
|
||||
var bodyPromise = Templates.render('tool_analytics/evaluation_options', {
|
||||
trainedexternally: trainedOnlyExternally,
|
||||
timesplittingmethods: JSON.parse(timeSplittingMethods)
|
||||
timesplittingmethods: timeSplittingMethods
|
||||
});
|
||||
|
||||
$.when(stringsPromise, modalPromise).then(function(strings, modal) {
|
||||
|
||||
@@ -1,63 +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/>.
|
||||
|
||||
/**
|
||||
* Potential contexts selector module.
|
||||
*
|
||||
* @module tool_analytics/potential-contexts
|
||||
* @class potential-contexts
|
||||
* @package tool_analytics
|
||||
* @copyright 2019 David Monllao
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define(['jquery', 'core/ajax'], function($, Ajax) {
|
||||
|
||||
return /** @alias module:tool_analytics/potential-contexts */ {
|
||||
|
||||
processResults: function(selector, results) {
|
||||
var contexts = [];
|
||||
if ($.isArray(results)) {
|
||||
$.each(results, function(index, context) {
|
||||
contexts.push({
|
||||
value: context.id,
|
||||
label: context.name
|
||||
});
|
||||
});
|
||||
return contexts;
|
||||
|
||||
} else {
|
||||
return results;
|
||||
}
|
||||
},
|
||||
|
||||
transport: function(selector, query, success, failure) {
|
||||
var promise;
|
||||
|
||||
let modelid = $(selector).attr('modelid') || null;
|
||||
promise = Ajax.call([{
|
||||
methodname: 'tool_analytics_potential_contexts',
|
||||
args: {
|
||||
query: query,
|
||||
modelid: modelid
|
||||
}
|
||||
}]);
|
||||
|
||||
promise[0].then(success).fail(failure);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
});
|
||||
@@ -1,113 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* This is the external API for this component.
|
||||
*
|
||||
* @package tool_analytics
|
||||
* @copyright 2019 David Monllao {@link http://www.davidmonllao.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_analytics;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once("$CFG->libdir/externallib.php");
|
||||
|
||||
use external_api;
|
||||
use external_function_parameters;
|
||||
use external_value;
|
||||
use external_single_structure;
|
||||
use external_multiple_structure;
|
||||
|
||||
/**
|
||||
* This is the external API for this component.
|
||||
*
|
||||
* @copyright 2019 David Monllao {@link http://www.davidmonllao.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class external extends external_api {
|
||||
|
||||
const MAX_CONTEXTS_RETURNED = 100;
|
||||
|
||||
/**
|
||||
* potential_contexts parameters.
|
||||
*
|
||||
* @since Moodle 3.8
|
||||
* @return external_function_parameters
|
||||
*/
|
||||
public static function potential_contexts_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'query' => new external_value(PARAM_NOTAGS, 'The model id', VALUE_DEFAULT),
|
||||
'modelid' => new external_value(PARAM_INT, 'The model id', VALUE_DEFAULT)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the contexts that match the provided query.
|
||||
*
|
||||
* @since Moodle 3.8
|
||||
* @param string|null $query
|
||||
* @param int|null $modelid
|
||||
* @return array an array of contexts
|
||||
*/
|
||||
public static function potential_contexts(?string $query = null, ?int $modelid = null) {
|
||||
|
||||
$params = self::validate_parameters(self::potential_contexts_parameters(), ['modelid' => $modelid, 'query' => $query]);
|
||||
|
||||
\core_analytics\manager::check_can_manage_models();
|
||||
|
||||
if ($params['modelid']) {
|
||||
$model = new \core_analytics\model($params['modelid']);
|
||||
$contexts = ($model->get_analyser(['notimesplitting' => true]))::potential_context_restrictions($params['query']);
|
||||
} else {
|
||||
$contexts = \core_analytics\manager::get_potential_context_restrictions(null, $params['query']);
|
||||
}
|
||||
|
||||
$contextoptions = [];
|
||||
$i = 0;
|
||||
foreach ($contexts as $contextid => $contextname) {
|
||||
|
||||
if ($i === self::MAX_CONTEXTS_RETURNED) {
|
||||
// Limited to MAX_CONTEXTS_RETURNED items.
|
||||
break;
|
||||
}
|
||||
|
||||
$contextoptions[] = ['id' => $contextid, 'name' => $contextname];
|
||||
$i++;
|
||||
}
|
||||
|
||||
return $contextoptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* potential_contexts return
|
||||
*
|
||||
* @since Moodle 3.8
|
||||
* @return external_description
|
||||
*/
|
||||
public static function potential_contexts_returns() {
|
||||
return new external_multiple_structure(
|
||||
new external_single_structure([
|
||||
'id' => new external_value(PARAM_INT, 'ID of the context'),
|
||||
'name' => new external_value(PARAM_NOTAGS, 'The context name')
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -65,15 +65,6 @@ class edit_model extends \moodleform {
|
||||
$mform->addRule('target', get_string('required'), 'required', null, 'client');
|
||||
}
|
||||
|
||||
if (!empty($this->_customdata['targetname']) && !empty($this->_customdata['targetclass'])) {
|
||||
$mform->addElement('static', 'targetname', get_string('target', 'tool_analytics'), $this->_customdata['targetname']);
|
||||
$mform->addElement('hidden', 'target',
|
||||
\tool_analytics\output\helper::class_to_option($this->_customdata['targetclass']));
|
||||
// We won't update the model's target so no worries about its format (we can't use PARAM_ALPHANUMEXT
|
||||
// because of class_to_option).
|
||||
$mform->setType('target', PARAM_TEXT);
|
||||
}
|
||||
|
||||
// Indicators.
|
||||
if (!$this->_customdata['staticmodel']) {
|
||||
$indicators = array();
|
||||
@@ -90,13 +81,6 @@ class edit_model extends \moodleform {
|
||||
}
|
||||
|
||||
// Time-splitting methods.
|
||||
if (!empty($this->_customdata['invalidcurrenttimesplitting'])) {
|
||||
$mform->addElement('html', $OUTPUT->notification(
|
||||
get_string('invalidcurrenttimesplitting', 'tool_analytics'),
|
||||
\core\output\notification::NOTIFY_WARNING)
|
||||
);
|
||||
}
|
||||
|
||||
$timesplittings = array('' => '');
|
||||
foreach ($this->_customdata['timesplittings'] as $classname => $timesplitting) {
|
||||
$optionname = \tool_analytics\output\helper::class_to_option($classname);
|
||||
@@ -105,28 +89,6 @@ class edit_model extends \moodleform {
|
||||
$mform->addElement('select', 'timesplitting', get_string('timesplittingmethod', 'analytics'), $timesplittings);
|
||||
$mform->addHelpButton('timesplitting', 'timesplittingmethod', 'analytics');
|
||||
|
||||
// Contexts restriction.
|
||||
if (!empty($this->_customdata['supportscontexts'])) {
|
||||
|
||||
$options = [
|
||||
'ajax' => 'tool_analytics/potential-contexts',
|
||||
'multiple' => true,
|
||||
'noselectionstring' => get_string('all')
|
||||
];
|
||||
|
||||
if (!empty($this->_customdata['id'])) {
|
||||
$options['modelid'] = $this->_customdata['id'];
|
||||
$contexts = $this->load_current_contexts();
|
||||
} else {
|
||||
// No need to preload any selected contexts.
|
||||
$contexts = [];
|
||||
}
|
||||
|
||||
$mform->addElement('autocomplete', 'contexts', get_string('contexts', 'tool_analytics'), $contexts, $options);
|
||||
$mform->setType('contexts', PARAM_INT);
|
||||
$mform->addHelpButton('contexts', 'contexts', 'tool_analytics');
|
||||
}
|
||||
|
||||
// Predictions processor.
|
||||
if (!$this->_customdata['staticmodel']) {
|
||||
$defaultprocessor = \core_analytics\manager::get_predictions_processor_name(
|
||||
@@ -168,35 +130,11 @@ class edit_model extends \moodleform {
|
||||
public function validation($data, $files) {
|
||||
$errors = parent::validation($data, $files);
|
||||
|
||||
$targetclass = \tool_analytics\output\helper::option_to_class($data['target']);
|
||||
$target = \core_analytics\manager::get_target($targetclass);
|
||||
|
||||
if (!empty($data['timesplitting'])) {
|
||||
$timesplittingclass = \tool_analytics\output\helper::option_to_class($data['timesplitting']);
|
||||
if (\core_analytics\manager::is_valid($timesplittingclass, '\core_analytics\local\time_splitting\base') === false) {
|
||||
$realtimesplitting = \tool_analytics\output\helper::option_to_class($data['timesplitting']);
|
||||
if (\core_analytics\manager::is_valid($realtimesplitting, '\core_analytics\local\time_splitting\base') === false) {
|
||||
$errors['timesplitting'] = get_string('errorinvalidtimesplitting', 'analytics');
|
||||
}
|
||||
|
||||
$timesplitting = \core_analytics\manager::get_time_splitting($timesplittingclass);
|
||||
if (!$target->can_use_timesplitting($timesplitting)) {
|
||||
$errors['timesplitting'] = get_string('invalidtimesplitting', 'tool_analytics');
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($data['contexts'])) {
|
||||
|
||||
$analyserclass = $target->get_analyser_class();
|
||||
if (!$potentialcontexts = $analyserclass::potential_context_restrictions()) {
|
||||
$errors['contexts'] = get_string('errornocontextrestrictions', 'analytics');
|
||||
} else {
|
||||
|
||||
// Flip the contexts array so we can just diff by key.
|
||||
$selectedcontexts = array_flip($data['contexts']);
|
||||
$invalidcontexts = array_diff_key($selectedcontexts, $potentialcontexts);
|
||||
if (!empty($invalidcontexts)) {
|
||||
$errors['contexts'] = get_string('errorinvalidcontexts', 'analytics');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->_customdata['staticmodel']) {
|
||||
@@ -218,18 +156,4 @@ class edit_model extends \moodleform {
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the currently selected context options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function load_current_contexts() {
|
||||
$contexts = [];
|
||||
foreach ($this->_customdata['contexts'] as $context) {
|
||||
$contexts[$context->id] = $context->get_context_name(true, true);
|
||||
}
|
||||
|
||||
return $contexts;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,50 +105,4 @@ class helper {
|
||||
$PAGE->reset_theme_and_output();
|
||||
$PAGE->set_context(\context_system::instance());
|
||||
}
|
||||
/**
|
||||
* Convert a list of contexts to an associative array where the value is the context name.
|
||||
*
|
||||
* @param array $contexts
|
||||
* @param \moodle_url $url
|
||||
* @param \renderer_base $output
|
||||
* @param int|null $selected
|
||||
* @param bool $includeall
|
||||
* @param bool $shortentext
|
||||
* @return \stdClass
|
||||
*/
|
||||
public static function prediction_context_selector(array $contexts, \moodle_url $url, \renderer_base $output,
|
||||
?int $selected = null, ?bool $includeall = false, ?bool $shortentext = true): \stdClass {
|
||||
|
||||
foreach ($contexts as $contextid => $unused) {
|
||||
// We prepare this to be used as single_select template options.
|
||||
$context = \context::instance_by_id($contextid);
|
||||
|
||||
// Special name for system level predictions as showing "System is not visually nice".
|
||||
if ($contextid == SYSCONTEXTID) {
|
||||
$contextname = get_string('allpredictions', 'tool_analytics');
|
||||
} else {
|
||||
if ($shortentext) {
|
||||
$contextname = shorten_text($context->get_context_name(false, true), 40);
|
||||
} else {
|
||||
$contextname = $context->get_context_name(false, true);
|
||||
}
|
||||
}
|
||||
$contexts[$contextid] = $contextname;
|
||||
}
|
||||
|
||||
if ($includeall) {
|
||||
$contexts[0] = get_string('all');
|
||||
$nothing = '';
|
||||
} else {
|
||||
$nothing = array('' => 'choosedots');
|
||||
}
|
||||
|
||||
\core_collator::asort($contexts);
|
||||
|
||||
if (!$selected) {
|
||||
$selected = '';
|
||||
}
|
||||
$singleselect = new \single_select($url, 'contextid', $contexts, $selected, $nothing);
|
||||
return $singleselect->export_for_template($output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,184 +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/>.
|
||||
|
||||
/**
|
||||
* Insights report renderable.
|
||||
*
|
||||
* @package tool_analytics
|
||||
* @copyright 2019 David Monllao {@link http://www.davidmonllao.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_analytics\output;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
/**
|
||||
* Insights report renderable.
|
||||
*
|
||||
* @package tool_analytics
|
||||
* @copyright 2019 David Monllao {@link http://www.davidmonllao.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class insights_report implements \renderable, \templatable {
|
||||
|
||||
/**
|
||||
* @var \core_analytics\model
|
||||
*/
|
||||
private $model = null;
|
||||
|
||||
/**
|
||||
* @var \context
|
||||
*/
|
||||
private $context = null;
|
||||
|
||||
/**
|
||||
* Inits the insights report renderable.
|
||||
*
|
||||
* @param \core_analytics\model $model
|
||||
* @param int|null $contextid
|
||||
* @return null
|
||||
*/
|
||||
public function __construct(\core_analytics\model $model, ?int $contextid = null) {
|
||||
$this->model = $model;
|
||||
if ($contextid) {
|
||||
$this->context = \context::instance_by_id($contextid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the data.
|
||||
*
|
||||
* @param \renderer_base $output
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output): \stdClass {
|
||||
|
||||
// Prepare the context object.
|
||||
$data = new \stdClass();
|
||||
$data->modelname = $this->model->get_name();
|
||||
|
||||
$data->charts = [];
|
||||
|
||||
$predictionactionrecords = $this->model->get_prediction_actions($this->context);
|
||||
|
||||
// Context selector.
|
||||
$predictioncontexts = $this->model->get_predictions_contexts(false);
|
||||
if ($predictioncontexts && count($predictioncontexts) > 1) {
|
||||
$url = new \moodle_url('/admin/tool/analytics/model.php', ['id' => $this->model->get_id(),
|
||||
'action' => 'insightsreport']);
|
||||
|
||||
if ($this->context) {
|
||||
$selected = $this->context->id;
|
||||
} else {
|
||||
// This is the 'all' option.
|
||||
$selected = 0;
|
||||
}
|
||||
$data->contextselect = \tool_analytics\output\helper::prediction_context_selector($predictioncontexts,
|
||||
$url, $output, $selected, true, false);
|
||||
}
|
||||
|
||||
if ($predictionactionrecords->valid()) {
|
||||
|
||||
foreach ($predictionactionrecords as $record) {
|
||||
|
||||
// Using this unusual execution flow to init the chart data because $predictionactionrecords
|
||||
// is a \moodle_recordset.
|
||||
if (empty($actionlabels)) {
|
||||
list($actionlabels, $actionvalues, $actiontypes) = $this->init_action_labels($record);
|
||||
}
|
||||
|
||||
// One value for each action.
|
||||
$actionvalues['separated'][$record->actionname]++;
|
||||
|
||||
// Grouped value.
|
||||
$actiontype = $actiontypes[$record->actionname];
|
||||
$actionvalues['grouped'][$actiontype]++;
|
||||
}
|
||||
$predictionactionrecords->close();
|
||||
|
||||
// Actions doughtnut.
|
||||
$chart = new \core\chart_pie();
|
||||
$chart->set_doughnut(true);
|
||||
$chart->set_title(get_string('actionsexecutedbyusers', 'tool_analytics'));
|
||||
$series = new \core\chart_series(get_string('actions', 'tool_analytics'),
|
||||
array_values($actionvalues['separated']));
|
||||
$chart->add_series($series);
|
||||
$chart->set_labels(array_values($actionlabels['separated']));
|
||||
$data->separatedchart = $output->render($chart);
|
||||
|
||||
// Positive/negative/neutral bar chart.
|
||||
$chart = new \core\chart_bar();
|
||||
$chart->set_title(get_string('actionexecutedgroupedusefulness', 'tool_analytics'));
|
||||
$series = new \core\chart_series(get_string('actions', 'tool_analytics'),
|
||||
array_values($actionvalues['grouped']));
|
||||
$chart->add_series($series);
|
||||
$chart->set_labels(array_values($actionlabels['grouped']));
|
||||
$data->groupedchart = $output->render($chart);
|
||||
|
||||
} else {
|
||||
$predictionactionrecords->close();
|
||||
$data->noactions = [
|
||||
'message' => get_string('noactionsfound', 'tool_analytics'),
|
||||
'announce' => true,
|
||||
];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the action labels and values in this model.
|
||||
*
|
||||
* @param \stdClass $predictionactionrecord
|
||||
* @return array Two-dimensional array with the labels and values initialised to zero.
|
||||
*/
|
||||
private function init_action_labels(\stdClass $predictionactionrecord): array {
|
||||
|
||||
$predictioncontext = \context::instance_by_id($predictionactionrecord->contextid);
|
||||
|
||||
// Just 1 result, we just want to retrieve the prediction action names.
|
||||
list ($unused, $predictions) = $this->model->get_predictions($predictioncontext, false, 0, 1);
|
||||
|
||||
// We pass 'true' for $isinsightuser so all the prediction actions available for this target are returning.
|
||||
$predictionactions = $this->model->get_target()->prediction_actions(reset($predictions), true, true);
|
||||
|
||||
$actionlabels = [];
|
||||
$actionvalues = ['separated' => [], 'grouped' => []];
|
||||
$actiontypes = [];
|
||||
foreach ($predictionactions as $action) {
|
||||
$actionlabels['separated'][$action->get_action_name()] = $action->get_text();
|
||||
$actionvalues['separated'][$action->get_action_name()] = 0;
|
||||
$actiontypes[$action->get_action_name()] = $action->get_type();
|
||||
}
|
||||
|
||||
$bulkactions = $this->model->get_target()->bulk_actions($predictions);
|
||||
foreach ($bulkactions as $action) {
|
||||
$actionlabels['separated'][$action->get_action_name()] = $action->get_text();
|
||||
$actionvalues['separated'][$action->get_action_name()] = 0;
|
||||
$actiontypes[$action->get_action_name()] = $action->get_type();
|
||||
}
|
||||
|
||||
$actionlabels['grouped'][\core_analytics\action::TYPE_POSITIVE] = get_string('useful', 'analytics');
|
||||
$actionlabels['grouped'][\core_analytics\action::TYPE_NEUTRAL] = get_string('neutral', 'analytics');
|
||||
$actionlabels['grouped'][\core_analytics\action::TYPE_NEGATIVE] = get_string('notuseful', 'analytics');
|
||||
|
||||
$actionvalues['grouped'][\core_analytics\action::TYPE_POSITIVE] = 0;
|
||||
$actionvalues['grouped'][\core_analytics\action::TYPE_NEUTRAL] = 0;
|
||||
$actionvalues['grouped'][\core_analytics\action::TYPE_NEGATIVE] = 0;
|
||||
|
||||
return [$actionlabels, $actionvalues, $actiontypes];
|
||||
}
|
||||
}
|
||||
@@ -76,8 +76,7 @@ class invalid_analysables implements \renderable, \templatable {
|
||||
|
||||
$offset = $this->page * $this->perpage;
|
||||
|
||||
$contexts = $this->model->get_contexts();
|
||||
$analysables = $this->model->get_analyser(['notimesplitting' => true])->get_analysables_iterator(null, $contexts);
|
||||
$analysables = $this->model->get_analyser(['notimesplitting' => true])->get_analysables_iterator();
|
||||
|
||||
$skipped = 0;
|
||||
$enoughresults = false;
|
||||
|
||||
@@ -97,9 +97,16 @@ class models_list implements \renderable, \templatable {
|
||||
}
|
||||
|
||||
// Evaluation options.
|
||||
$timesplittingsforevaluation = \core_analytics\manager::get_time_splitting_methods_for_evaluation(true);
|
||||
$timesplittingmethods = [
|
||||
['id' => 'all', 'text' => get_string('alltimesplittingmethods', 'tool_analytics')],
|
||||
];
|
||||
foreach (\core_analytics\manager::get_time_splitting_methods_for_evaluation(true) as $timesplitting) {
|
||||
$timesplittingmethods[] = [
|
||||
'id' => \tool_analytics\output\helper::class_to_option($timesplitting->get_id()),
|
||||
'text' => $timesplitting->get_name()->out(),
|
||||
];
|
||||
}
|
||||
|
||||
$misconfiguredmodels = [];
|
||||
$data->models = array();
|
||||
foreach ($this->models as $model) {
|
||||
$modeldata = $model->export($output);
|
||||
@@ -116,10 +123,6 @@ class models_list implements \renderable, \templatable {
|
||||
describe its purpose.", DEBUG_DEVELOPER);
|
||||
}
|
||||
|
||||
if ($model->invalid_timesplitting_selected()) {
|
||||
$misconfiguredmodels[$model->get_id()] = $model->get_name();
|
||||
}
|
||||
|
||||
// Check if there is a help icon for the indicators to show.
|
||||
if (!empty($modeldata->indicators)) {
|
||||
$indicators = array();
|
||||
@@ -153,7 +156,7 @@ class models_list implements \renderable, \templatable {
|
||||
$modeldata->timesplittinghelp = $helpicon->export_for_template($output);
|
||||
} else {
|
||||
// We really want to encourage developers to add help to their time splitting methods.
|
||||
debugging("The analysis interval '{$modeldata->timesplitting}' should include a '{$identifier}_help'
|
||||
debugging("The time splitting method '{$modeldata->timesplitting}' should include a '{$identifier}_help'
|
||||
string to describe its purpose.", DEBUG_DEVELOPER);
|
||||
}
|
||||
} else {
|
||||
@@ -163,20 +166,36 @@ class models_list implements \renderable, \templatable {
|
||||
|
||||
// Has this model generated predictions?.
|
||||
$predictioncontexts = $model->get_predictions_contexts();
|
||||
$anypredictionobtained = $model->any_prediction_obtained();
|
||||
|
||||
// Model predictions list.
|
||||
if (!$model->is_enabled()) {
|
||||
$modeldata->noinsights = get_string('disabledmodel', 'analytics');
|
||||
} else if ($model->uses_insights()) {
|
||||
if ($predictioncontexts) {
|
||||
$url = new \moodle_url('/report/insights/insights.php', array('modelid' => $model->get_id()));
|
||||
$modeldata->insights = \tool_analytics\output\helper::prediction_context_selector($predictioncontexts,
|
||||
$url, $output);
|
||||
|
||||
foreach ($predictioncontexts as $contextid => $unused) {
|
||||
// We prepare this to be used as single_select template options.
|
||||
$context = \context::instance_by_id($contextid);
|
||||
|
||||
// Special name for system level predictions as showing "System is not visually nice".
|
||||
if ($contextid == SYSCONTEXTID) {
|
||||
$contextname = get_string('allpredictions', 'tool_analytics');
|
||||
} else {
|
||||
$contextname = shorten_text($context->get_context_name(false, true), 40);
|
||||
}
|
||||
$predictioncontexts[$contextid] = $contextname;
|
||||
}
|
||||
\core_collator::asort($predictioncontexts);
|
||||
|
||||
if (!empty($predictioncontexts)) {
|
||||
$url = new \moodle_url('/report/insights/insights.php', array('modelid' => $model->get_id()));
|
||||
$singleselect = new \single_select($url, 'contextid', $predictioncontexts);
|
||||
$modeldata->insights = $singleselect->export_for_template($output);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($modeldata->insights)) {
|
||||
if ($anypredictionobtained) {
|
||||
if ($model->any_prediction_obtained()) {
|
||||
$modeldata->noinsights = get_string('noinsights', 'analytics');
|
||||
} else {
|
||||
$modeldata->noinsights = get_string('nopredictionsyet', 'analytics');
|
||||
@@ -197,11 +216,10 @@ class models_list implements \renderable, \templatable {
|
||||
|
||||
// Get predictions.
|
||||
if (!$onlycli && $modeldata->enabled && !empty($modeldata->timesplitting)) {
|
||||
$urlparams['action'] = 'scheduledanalysis';
|
||||
$url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams);
|
||||
$icon = new \action_menu_link_secondary($url,
|
||||
new \pix_icon('i/notifications', get_string('executescheduledanalysis', 'tool_analytics')),
|
||||
get_string('executescheduledanalysis', 'tool_analytics'));
|
||||
$urlparams['action'] = 'getpredictions';
|
||||
$url = new \moodle_url('model.php', $urlparams);
|
||||
$icon = new \action_menu_link_secondary($url, new \pix_icon('i/notifications',
|
||||
get_string('getpredictions', 'tool_analytics')), get_string('getpredictions', 'tool_analytics'));
|
||||
$actionsmenu->add($icon);
|
||||
}
|
||||
|
||||
@@ -213,29 +231,26 @@ class models_list implements \renderable, \templatable {
|
||||
|
||||
$actionid = 'evaluate-' . $model->get_id();
|
||||
|
||||
// Evaluation options.
|
||||
$modeltimesplittingmethods = $this->timesplittings_options_for_evaluation($model, $timesplittingsforevaluation);
|
||||
|
||||
$modeltimesplittingmethods = $timesplittingmethods;
|
||||
// Include the current time-splitting method as the default selection method the model already have one.
|
||||
if ($model->get_model_obj()->timesplitting) {
|
||||
$currenttimesplitting = ['id' => 'current', 'text' => get_string('currenttimesplitting', 'tool_analytics')];
|
||||
array_unshift($modeltimesplittingmethods, $currenttimesplitting);
|
||||
}
|
||||
|
||||
$evaluateparams = [$actionid, $trainedonlyexternally];
|
||||
$evaluateparams = [$actionid, $trainedonlyexternally, $modeltimesplittingmethods];
|
||||
$PAGE->requires->js_call_amd('tool_analytics/model', 'selectEvaluationOptions', $evaluateparams);
|
||||
$urlparams['action'] = 'evaluate';
|
||||
$url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams);
|
||||
$url = new \moodle_url('model.php', $urlparams);
|
||||
$icon = new \action_menu_link_secondary($url, new \pix_icon('i/calc', get_string('evaluate', 'tool_analytics')),
|
||||
get_string('evaluate', 'tool_analytics'), ['data-action-id' => $actionid,
|
||||
'data-timesplitting-methods' => json_encode($modeltimesplittingmethods)]);
|
||||
get_string('evaluate', 'tool_analytics'), ['data-action-id' => $actionid]);
|
||||
$actionsmenu->add($icon);
|
||||
}
|
||||
|
||||
// Machine-learning-based models evaluation log.
|
||||
if (!$model->is_static() && $model->get_logs()) {
|
||||
$urlparams['action'] = 'log';
|
||||
$url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams);
|
||||
$url = new \moodle_url('model.php', $urlparams);
|
||||
$icon = new \action_menu_link_secondary($url, new \pix_icon('i/report', get_string('viewlog', 'tool_analytics')),
|
||||
get_string('viewlog', 'tool_analytics'));
|
||||
$actionsmenu->add($icon);
|
||||
@@ -243,7 +258,7 @@ class models_list implements \renderable, \templatable {
|
||||
|
||||
// Edit model.
|
||||
$urlparams['action'] = 'edit';
|
||||
$url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams);
|
||||
$url = new \moodle_url('model.php', $urlparams);
|
||||
$icon = new \action_menu_link_secondary($url, new \pix_icon('t/edit', get_string('edit')), get_string('edit'));
|
||||
$actionsmenu->add($icon);
|
||||
|
||||
@@ -260,7 +275,7 @@ class models_list implements \renderable, \templatable {
|
||||
$icontype = 'i/checked';
|
||||
}
|
||||
$urlparams['action'] = $action;
|
||||
$url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams);
|
||||
$url = new \moodle_url('model.php', $urlparams);
|
||||
$icon = new \action_menu_link_secondary($url, new \pix_icon($icontype, $text), $text);
|
||||
$actionsmenu->add($icon);
|
||||
}
|
||||
@@ -273,7 +288,7 @@ class models_list implements \renderable, \templatable {
|
||||
|
||||
if ($fullysetup || $istrained) {
|
||||
|
||||
$url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams);
|
||||
$url = new \moodle_url('model.php', $urlparams);
|
||||
// Clear the previous action param from the URL, we will set it in JS.
|
||||
$url->remove_params('action');
|
||||
|
||||
@@ -288,31 +303,22 @@ class models_list implements \renderable, \templatable {
|
||||
}
|
||||
}
|
||||
|
||||
// Insights report.
|
||||
if (!empty($anypredictionobtained) && $model->uses_insights()) {
|
||||
$urlparams['action'] = 'insightsreport';
|
||||
$url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams);
|
||||
$pix = new \pix_icon('i/report', get_string('insightsreport', 'tool_analytics'));
|
||||
$icon = new \action_menu_link_secondary($url, $pix, get_string('insightsreport', 'tool_analytics'));
|
||||
$actionsmenu->add($icon);
|
||||
}
|
||||
|
||||
// Invalid analysables.
|
||||
$analyser = $model->get_analyser(['notimesplitting' => true]);
|
||||
if (!$analyser instanceof \core_analytics\local\analyser\sitewide) {
|
||||
$urlparams['action'] = 'invalidanalysables';
|
||||
$url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams);
|
||||
$url = new \moodle_url('model.php', $urlparams);
|
||||
$pix = new \pix_icon('i/report', get_string('invalidanalysables', 'tool_analytics'));
|
||||
$icon = new \action_menu_link_secondary($url, $pix, get_string('invalidanalysables', 'tool_analytics'));
|
||||
$actionsmenu->add($icon);
|
||||
}
|
||||
|
||||
// Clear model.
|
||||
if (!empty($anypredictionobtained) || $model->is_trained()) {
|
||||
if (!empty($predictioncontexts) || $model->is_trained()) {
|
||||
$actionid = 'clear-' . $model->get_id();
|
||||
$PAGE->requires->js_call_amd('tool_analytics/model', 'confirmAction', [$actionid, 'clear']);
|
||||
$urlparams['action'] = 'clear';
|
||||
$url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams);
|
||||
$url = new \moodle_url('model.php', $urlparams);
|
||||
$icon = new \action_menu_link_secondary($url, new \pix_icon('e/cleanup_messy_code',
|
||||
get_string('clearpredictions', 'tool_analytics')), get_string('clearpredictions', 'tool_analytics'),
|
||||
['data-action-id' => $actionid]);
|
||||
@@ -323,7 +329,7 @@ class models_list implements \renderable, \templatable {
|
||||
$actionid = 'delete-' . $model->get_id();
|
||||
$PAGE->requires->js_call_amd('tool_analytics/model', 'confirmAction', [$actionid, 'delete']);
|
||||
$urlparams['action'] = 'delete';
|
||||
$url = new \moodle_url('/admin/tool/analytics/model.php', $urlparams);
|
||||
$url = new \moodle_url('model.php', $urlparams);
|
||||
$icon = new \action_menu_link_secondary($url, new \pix_icon('t/delete',
|
||||
get_string('delete', 'tool_analytics')), get_string('delete', 'tool_analytics'),
|
||||
['data-action-id' => $actionid]);
|
||||
@@ -334,10 +340,10 @@ class models_list implements \renderable, \templatable {
|
||||
$data->models[] = $modeldata;
|
||||
}
|
||||
|
||||
$data->warnings = [];
|
||||
$data->infos = [];
|
||||
if (!$onlycli) {
|
||||
$data->warnings[] = (object)array('message' => get_string('bettercli', 'tool_analytics'), 'closebutton' => true);
|
||||
$data->warnings = array(
|
||||
(object)array('message' => get_string('bettercli', 'tool_analytics'), 'closebutton' => true)
|
||||
);
|
||||
} else {
|
||||
$url = new \moodle_url('/admin/settings.php', array('section' => 'analyticssettings'),
|
||||
'id_s_analytics_onlycli');
|
||||
@@ -346,43 +352,12 @@ class models_list implements \renderable, \templatable {
|
||||
if (is_siteadmin()) {
|
||||
$langstrid = 'clievaluationandpredictions';
|
||||
}
|
||||
$data->infos[] = (object)array('message' => get_string($langstrid, 'tool_analytics', $url->out()),
|
||||
'closebutton' => true);
|
||||
}
|
||||
|
||||
if ($misconfiguredmodels) {
|
||||
$warningstr = get_string('invalidtimesplittinginmodels', 'tool_analytics', implode(', ', $misconfiguredmodels));
|
||||
$data->warnings[] = (object)array('message' => $warningstr, 'closebutton' => true);
|
||||
$data->infos = array(
|
||||
(object)array('message' => get_string($langstrid, 'tool_analytics', $url->out()),
|
||||
'closebutton' => true)
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of time splitting methods that are available for evaluation.
|
||||
*
|
||||
* @param \core_analytics\model $model
|
||||
* @param array $timesplittingsforevaluation
|
||||
* @return array
|
||||
*/
|
||||
private function timesplittings_options_for_evaluation(\core_analytics\model $model,
|
||||
array $timesplittingsforevaluation): array {
|
||||
|
||||
$modeltimesplittingmethods = [
|
||||
['id' => 'all', 'text' => get_string('alltimesplittingmethods', 'tool_analytics')],
|
||||
];
|
||||
$potentialtimesplittingmethods = $model->get_potential_timesplittings();
|
||||
foreach ($timesplittingsforevaluation as $timesplitting) {
|
||||
if (empty($potentialtimesplittingmethods[$timesplitting->get_id()])) {
|
||||
// This time-splitting method can not be used for this model.
|
||||
continue;
|
||||
}
|
||||
$modeltimesplittingmethods[] = [
|
||||
'id' => \tool_analytics\output\helper::class_to_option($timesplitting->get_id()),
|
||||
'text' => $timesplitting->get_name()->out(),
|
||||
];
|
||||
}
|
||||
|
||||
return $modeltimesplittingmethods;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,9 +90,9 @@ class renderer extends plugin_renderer_base {
|
||||
$langstrdata = (object)array('name' => $timesplitting->get_name(), 'id' => $timesplittingid);
|
||||
|
||||
if (CLI_SCRIPT) {
|
||||
$output .= $OUTPUT->heading(get_string('scheduledanalysisresultscli', 'tool_analytics', $langstrdata), 3);
|
||||
$output .= $OUTPUT->heading(get_string('getpredictionsresultscli', 'tool_analytics', $langstrdata), 3);
|
||||
} else {
|
||||
$output .= $OUTPUT->heading(get_string('scheduledanalysisresults', 'tool_analytics', $langstrdata), 3);
|
||||
$output .= $OUTPUT->heading(get_string('getpredictionsresults', 'tool_analytics', $langstrdata), 3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,17 +208,6 @@ class renderer extends plugin_renderer_base {
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer to template.
|
||||
*
|
||||
* @param \tool_analytics\output\insights_report $insightsreport
|
||||
* @return string HTML
|
||||
*/
|
||||
protected function render_insights_report(\tool_analytics\output\insights_report $insightsreport): string {
|
||||
$data = $insightsreport->export_for_template($this);
|
||||
return parent::render_from_template('tool_analytics/insights_report', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer to template.
|
||||
*
|
||||
@@ -229,26 +218,4 @@ class renderer extends plugin_renderer_base {
|
||||
$data = $invalidanalysables->export_for_template($this);
|
||||
return parent::render_from_template('tool_analytics/invalid_analysables', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders an analytics disabled notification.
|
||||
*
|
||||
* @return string HTML
|
||||
*/
|
||||
public function render_analytics_disabled() {
|
||||
global $OUTPUT, $PAGE, $FULLME;
|
||||
|
||||
$PAGE->set_url($FULLME);
|
||||
$PAGE->set_title(get_string('pluginname', 'tool_analytics'));
|
||||
$PAGE->set_heading(get_string('pluginname', 'tool_analytics'));
|
||||
|
||||
$output = $OUTPUT->header();
|
||||
$output .= $OUTPUT->notification(get_string('analyticsdisabled', 'analytics'), \core\output\notification::NOTIFY_INFO);
|
||||
$output .= \html_writer::tag('a', get_string('continue'), ['class' => 'btn btn-primary',
|
||||
'href' => (new \moodle_url('/'))->out()]);
|
||||
$output .= $OUTPUT->footer();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -52,11 +52,6 @@ class predict_models extends \core\task\scheduled_task {
|
||||
public function execute() {
|
||||
global $OUTPUT, $PAGE;
|
||||
|
||||
if (!\core_analytics\manager::is_analytics_enabled()) {
|
||||
mtrace(get_string('analyticsdisabled', 'analytics'));
|
||||
return;
|
||||
}
|
||||
|
||||
$models = \core_analytics\manager::get_all_models(true, true);
|
||||
if (!$models) {
|
||||
mtrace(get_string('errornoenabledandtrainedmodels', 'tool_analytics'));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user