Compare commits
967 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| de301d4237 | |||
| e2c8f4ad1b | |||
| 8c1455d220 | |||
| 7b85e141da | |||
| cd744ba504 | |||
| 974c63505b | |||
| 724210c4f7 | |||
| ae9d510288 | |||
| 981f750b81 | |||
| 721d57228f | |||
| 3c25c373d9 | |||
| 17eb41c270 | |||
| af6e65f221 | |||
| 8bbc064e29 | |||
| 78b18c00bf | |||
| 4b3b4b7d78 | |||
| 557d1c8820 | |||
| 698e1f7823 | |||
| 5b4702a6b6 | |||
| 77c0b16613 | |||
| 9adef8af21 | |||
| cc45df637f | |||
| 13655cd5ea | |||
| ea3f1d19b9 | |||
| 8256ebd431 | |||
| 8ba97d0104 | |||
| 71ee378a69 | |||
| 8208453a14 | |||
| 7c6e9b37b3 | |||
| 19dc872bca | |||
| 0a51214fb3 | |||
| 6910afa56f | |||
| 5e5e82621c | |||
| 2edff57e63 | |||
| 3b8bb4d4c1 | |||
| 920763ad00 | |||
| 1acd3cac07 | |||
| 7de4119fe2 | |||
| 6fb2fa9859 | |||
| 1d54d21ec0 | |||
| c87ed01b17 | |||
| 23541c936a | |||
| b7490a205f | |||
| 8415e0461b | |||
| 9ee41118b0 | |||
| 137b10b378 | |||
| bb9e3ec1ff | |||
| 7152b05700 | |||
| 087ccaff4f | |||
| 3fb245f481 | |||
| 8de31cf961 | |||
| 88e7da61cd | |||
| 3648b629ed | |||
| 0d833e248a | |||
| 783fba428f | |||
| 514c7ee639 | |||
| fa35b9506f | |||
| 29f7630b75 | |||
| 7a2a47d9e8 | |||
| 17211224a1 | |||
| 2394a675dd | |||
| 449c835fe2 | |||
| 322afa9f4f | |||
| 1d0777dbe4 | |||
| cd94f2bc2e | |||
| e899fd5c02 | |||
| 438b2ac8c2 | |||
| f6ae03bf41 | |||
| fc52aaf319 | |||
| ef8eb8ef1a | |||
| f1c6cf8b26 | |||
| e68cea5747 | |||
| 3f797704ea | |||
| aae57db8d2 | |||
| 8c3091e5f3 | |||
| b52ad05038 | |||
| ec5d807139 | |||
| 1f00b5d9bb | |||
| 0f53bd6b8e | |||
| bf29fea4bb | |||
| 8a733bc85f | |||
| 1b87f634a8 | |||
| 9260dad3b3 | |||
| 6002a1454f | |||
| cef3216f2a | |||
| bed6bfe7d4 | |||
| 1c39517553 | |||
| e92846ce18 | |||
| 31d0ccb078 | |||
| fc7fa7f72c | |||
| 6994f63eef | |||
| c28c0ed466 | |||
| 479b0f0eaa | |||
| 7b96e8a413 | |||
| 2321fe4da9 | |||
| 3aa05048cf | |||
| 17d6ecd26d | |||
| 7d5c5fad77 | |||
| c1296560bf | |||
| 93e25f8657 | |||
| f43de821c6 | |||
| 1b0690a7f1 | |||
| e003e8a6ff | |||
| 1e8f432437 | |||
| 51d7849f08 | |||
| ede7d22dc7 | |||
| 4355451e2f | |||
| 5e102fa8c3 | |||
| 1925b641e2 | |||
| 377da86151 | |||
| 9a2db9e2ec | |||
| 844637b880 | |||
| 9e597d3658 | |||
| 0e25936c0d | |||
| 627e14727e | |||
| ffe84e977f | |||
| 7bc67e92e2 | |||
| dd96341354 | |||
| 1714cb74b3 | |||
| c94c579aa6 | |||
| 16bcd8f057 | |||
| 5e65d02eab | |||
| 1b8bfedaa9 | |||
| 7b920d2d7b | |||
| 63b0a865dd | |||
| 7766af18a5 | |||
| 14d68d98b5 | |||
| 8676a67888 | |||
| 8af16c5709 | |||
| 7f74dc1c16 | |||
| 5bdc07a3b6 | |||
| bccfc48b94 | |||
| 95c3de0877 | |||
| d833fc2131 | |||
| 6e04f9f294 | |||
| 7f45f9ab3e | |||
| 547a6dcdde | |||
| 28fff43d2b | |||
| 7565cda9c6 | |||
| 90fa490de7 | |||
| 5f9ddb348e | |||
| ff8da7e008 | |||
| a6ab91786f | |||
| 0a43bdcc6c | |||
| b1a4bd579a | |||
| 4825c139ef | |||
| d207a2ad02 | |||
| ccc6b4d00b | |||
| cc3a909810 | |||
| c93de36436 | |||
| da3ebf216e | |||
| 7c8fd0d417 | |||
| 558ace5997 | |||
| 98254ccd1a | |||
| 5be02868af | |||
| a36b3ec48f | |||
| ea4e0ae3cb | |||
| 68c3eb8aa9 | |||
| 331b9947a3 | |||
| 4e8d58374e | |||
| 86669b0564 | |||
| e80e613f65 | |||
| 81410615ed | |||
| 1d0bd0cfdf | |||
| b4f40ae78e | |||
| 556611a864 | |||
| 7ce8e4cde2 | |||
| bde7f5d734 | |||
| e08f640061 | |||
| 4f01d454a7 | |||
| 35cc7cad05 | |||
| 7b5fa603dd | |||
| 4e72b72720 | |||
| eaf24d71f2 | |||
| ed46bff4ae | |||
| 87bcff8c6e | |||
| 81c2fe97a3 | |||
| 8b53812c8f | |||
| 78aeaf17e7 | |||
| 662d20869a | |||
| f66c4fa42d | |||
| 76a830b058 | |||
| 2f9582d754 | |||
| 12d4c82f98 | |||
| 3648ffdc8e | |||
| 1194dde152 | |||
| f727dad657 | |||
| 985d5a5824 | |||
| 0210ab0005 | |||
| 99cf35e681 | |||
| 61d0134488 | |||
| 2369ad7737 | |||
| 71dcd85182 | |||
| f5d19447e0 | |||
| b276f33850 | |||
| b932b798f1 | |||
| 14cecfa4c0 | |||
| 9582b85c16 | |||
| f920fdced0 | |||
| 53836d2035 | |||
| ff2b655928 | |||
| 706f6c93ae | |||
| 6028dc3924 | |||
| fd34a36514 | |||
| 27da8851f6 | |||
| 248ab7a4b3 | |||
| fcf07d64c8 | |||
| 897cfd7c81 | |||
| 193aa32b88 | |||
| 78908d7757 | |||
| 896c962160 | |||
| 1178406516 | |||
| 409f92b75d | |||
| 6ea0b003d7 | |||
| 918b60d700 | |||
| b997786180 | |||
| 3e8447fe9a | |||
| 28a1f0943d | |||
| 7a2d0fb5dc | |||
| 28de3d7db9 | |||
| 9fa04e3f2e | |||
| 1d41237ae8 | |||
| b0a9faf1c6 | |||
| e9961085eb | |||
| 766376261a | |||
| 8e2e459daa | |||
| fedd703ce1 | |||
| a1216eb05b | |||
| e49e58a924 | |||
| 97a03ba74d | |||
| ba43374d96 | |||
| 09d078c3b8 | |||
| a8e089a8c8 | |||
| 3e8043f3f4 | |||
| 70f695d068 | |||
| e83cad80b1 | |||
| d727c1eafd | |||
| 463b232453 | |||
| 02a8be1f80 | |||
| 7bc714ac09 | |||
| 3accc543ec | |||
| 481c57cabe | |||
| c0256a7351 | |||
| f8287cb170 | |||
| 621cd70b4c | |||
| 7e2acbfb55 | |||
| c87ccd3111 | |||
| 06be826b2e | |||
| 06a4390060 | |||
| 126cbbff7c | |||
| f252b08433 | |||
| fae048b402 | |||
| 0408008fbe | |||
| 0ff5242a3c | |||
| 2488fe37ca | |||
| 4edad07619 | |||
| 6cdcee7a65 | |||
| 28fbba8b3c | |||
| 90fde2b40d | |||
| d8bfd5b747 | |||
| 0d9c49d8d6 | |||
| 4d9ffaae34 | |||
| 21cfc35074 | |||
| 5d0b569ba1 | |||
| fd7db38d8b | |||
| 2f9f0b0fcc | |||
| 14aaba1b72 | |||
| 629657363d | |||
| 498c54d1de | |||
| a3f72b3972 | |||
| 098f09b638 | |||
| 99732c4c3b | |||
| 905d3939f5 | |||
| 051cad238b | |||
| 6a4bf785cc | |||
| 223f7cc0b4 | |||
| 287ed73429 | |||
| db1368926a | |||
| ec19837b79 | |||
| 3b0d958065 | |||
| 6722a6b105 | |||
| 920b4dd6ab | |||
| 898bdfdd67 | |||
| ed7485277e | |||
| eb238722da | |||
| da1f204a0a | |||
| 5dd385d522 | |||
| dca6513b8a | |||
| 6484e89188 | |||
| 9312e7389a | |||
| 0218859c3e | |||
| 18702b5869 | |||
| d0ab1d1540 | |||
| 7d25143979 | |||
| a067cc5ada | |||
| ea68407895 | |||
| 03f5e32712 | |||
| c0b0649582 | |||
| 72cd24d3c9 | |||
| d16aa74359 | |||
| 7e52e95d8d | |||
| 42f3862b91 | |||
| 556648db0b | |||
| 6026aa7b3c | |||
| 8e5782b848 | |||
| f38e17f16f | |||
| 465cc9e91a | |||
| faa76ee29a | |||
| d6491a67c8 | |||
| 27db5c5024 | |||
| e6b274a542 | |||
| 6f317a983e | |||
| a5293c4ed8 | |||
| 66e77f8173 | |||
| 4ba58ac02f | |||
| 21f5c148fc | |||
| 2e026689c6 | |||
| 3a718d620e | |||
| beff06190a | |||
| 975081c367 | |||
| 9417cedd78 | |||
| 19343c7bd1 | |||
| 64dd473559 | |||
| 9e4a19af6c | |||
| eeba9c1dc5 | |||
| 55a465c445 | |||
| d1d52a3399 | |||
| ad7b38f3ff | |||
| a22b74872c | |||
| 1af998d32c | |||
| 4d9ab4ca48 | |||
| 55189f02ee | |||
| 115f703440 | |||
| 5cd7b5cad0 | |||
| fb81664dc3 | |||
| 8cbc470f2a | |||
| 1bc92d37f2 | |||
| 348e338a21 | |||
| bf854f5f24 | |||
| b861165753 | |||
| 3c2208cc24 | |||
| 2d1fcf6cce | |||
| 2f502066cb | |||
| 41cd0c4d3a | |||
| 0efc7095e3 | |||
| 6178388d94 | |||
| f0e9fa2a7b | |||
| c651779095 | |||
| ce5efbc1da | |||
| e9506c638b | |||
| bb3f9ee492 | |||
| 14017f40b9 | |||
| 413736095b | |||
| f78101f638 | |||
| 105e40d377 | |||
| ce2f6179cd | |||
| 47ff67ec29 | |||
| 3fb1660734 | |||
| 6e7c392d84 | |||
| 806e6bec59 | |||
| 8d7fe960a0 | |||
| 8d1cbe3a35 | |||
| 197ec7e822 | |||
| fbab65f86b | |||
| cd054d77f1 | |||
| 6168569323 | |||
| 5da2fa002e | |||
| 4b137eb20c | |||
| 34ffdc2c81 | |||
| 83d478ce93 | |||
| 565bc965b1 | |||
| e2cdcc563d | |||
| ae61985191 | |||
| 2b169e9b31 | |||
| ccbd35915c | |||
| 114d1a051e | |||
| 856c31cc32 | |||
| 25049f4f19 | |||
| 00a46671fa | |||
| d008aa7c99 | |||
| 2d462ee8bd | |||
| 3f50f83dc1 | |||
| 41121d705f | |||
| cc2faa2c90 | |||
| ae4f9b31f7 | |||
| 01f3495a46 | |||
| c4c328565d | |||
| 7961a36b76 | |||
| eda7eb44b3 | |||
| 6589c3cdd6 | |||
| eeb76ddd3f | |||
| 14ea69c07c | |||
| 9f0400b74d | |||
| f68a64d50b | |||
| d82acd309b | |||
| 22f34e807d | |||
| 31d3a656d6 | |||
| 3d41104fab | |||
| 523f308a9a | |||
| e4d03a9257 | |||
| cedf141cc3 | |||
| b4d51d67a9 | |||
| 9763c99f87 | |||
| 56be61d4f6 | |||
| 6de6fe9590 | |||
| 754440d796 | |||
| 1ddaad70ad | |||
| c954e18a99 | |||
| e0a366fa0a | |||
| 2e5daf9108 | |||
| 5281e10e77 | |||
| aae7a2b206 | |||
| 419ff44b78 | |||
| c4a8787574 | |||
| 834a1d64c5 | |||
| 496e6ac804 | |||
| 7eb0f97113 | |||
| 9f1df0f2e4 | |||
| 8fc60dd25d | |||
| 558a30dc7d | |||
| 9773b4b079 | |||
| d686ee8faa | |||
| 5cb1cf7695 | |||
| 465f3b477b | |||
| ad00d91851 | |||
| 1eed96dec7 | |||
| 2e21c78006 | |||
| aba9644393 | |||
| 4aa6b89ead | |||
| f8bce36ef2 | |||
| fce2b0008c | |||
| c2bd0a7d31 | |||
| 2d7a59d060 | |||
| 57e0a20dec | |||
| 3fe455fab4 | |||
| ca743b6a95 | |||
| 5ea37637b7 | |||
| 75bae1a55b | |||
| f3db3d30e0 | |||
| 7714ea42ec | |||
| 12c103b21a | |||
| ec157a3052 | |||
| 57bb2fdaac | |||
| e437183098 | |||
| 3af8f89e58 | |||
| 52b1184468 | |||
| 99d0308e4b | |||
| 3ae46b2a93 | |||
| 5fce0b3f5d | |||
| b3ebbb61f4 | |||
| 16689245e8 | |||
| 98280a4c8c | |||
| 171e55f304 | |||
| f1fed72bda | |||
| 07674eb12f | |||
| 2308a02324 | |||
| 1da6703d6d | |||
| 27a62292ad | |||
| 271b94ff4f | |||
| 315ec3bad6 | |||
| 4cb342ef34 | |||
| e7bb7aa9a2 | |||
| 7aca3ebb3c | |||
| 61bb2c70c2 | |||
| d84da184c5 | |||
| f612465b53 | |||
| 4727970abd | |||
| 88c700bd2c | |||
| b354694012 | |||
| a9bccc9dbc | |||
| 7c52a27375 | |||
| 300d9ca23d | |||
| 00b2219fd4 | |||
| 8b9d73dad8 | |||
| 9029eb0e71 | |||
| d54b3447e6 | |||
| 39d542eeb4 | |||
| 2cf6b7cc41 | |||
| 5651e88dc9 | |||
| 5a90580646 | |||
| c98428aab3 | |||
| dc780e3eb1 | |||
| d75844ea12 | |||
| 11e5003bd6 | |||
| a348c5f420 | |||
| 4b651226d5 | |||
| e33c554aaa | |||
| 31937c4b0e | |||
| 141216f94c | |||
| fba96f096b | |||
| 7148c9d35e | |||
| 8193ba9da9 | |||
| 6bf314500a | |||
| ee034c39e5 | |||
| 46aea33b69 | |||
| e0f9ca6787 | |||
| 976f8f0c52 | |||
| 767be5d8c1 | |||
| 94140b11e8 | |||
| a45e6838ef | |||
| ae17678a1c | |||
| 3ae39301b9 | |||
| 422fcb70ca | |||
| 29a396fe4e | |||
| af777f92a0 | |||
| 6f35d6536d | |||
| 36cde1e295 | |||
| 05a1532e88 | |||
| 91ae4ab5db | |||
| 2cc3588b77 | |||
| 222aefb456 | |||
| 94160c9ad0 | |||
| 9c7ab777d9 | |||
| 7818990010 | |||
| 17a035ac59 | |||
| abe11a9ace | |||
| bfab0d603c | |||
| 070454489f | |||
| e32a114998 | |||
| 3db28cdebd | |||
| ccd4ef8ddd | |||
| 51b0a67bd2 | |||
| b9371d7bf6 | |||
| 1ec406cbd7 | |||
| b1c1119743 | |||
| 3d45f2c083 | |||
| 1f5da975e2 | |||
| 7156a01a0c | |||
| db22846df6 | |||
| ef6e3bfd77 | |||
| ee0106f70b | |||
| 36ee886a12 | |||
| 97e0452344 | |||
| 874bdf2035 | |||
| ab43412ae9 | |||
| 3d01fc77de | |||
| 08d7552f4d | |||
| 8983d50bd1 | |||
| 9fb8221fb3 | |||
| 4b60cede1e | |||
| 4514918c33 | |||
| 86d6bdf079 | |||
| f5d75c8e24 | |||
| bfeb6f3bac | |||
| ec52cca8b1 | |||
| 6bbb402129 | |||
| 7375466f51 | |||
| 8635e2cefa | |||
| 52bad33356 | |||
| 5c155ba8f7 | |||
| ffa17ad17d | |||
| 5d6fcc67cf | |||
| a37dc94598 | |||
| 1e08e046e2 | |||
| 4ff5d5ef17 | |||
| 84ef6eb8d9 | |||
| 3b45e0db41 | |||
| 535523f21f | |||
| 9c50ccbf7e | |||
| 6c39b7890e | |||
| b676817a64 | |||
| 8eca15c5f1 | |||
| 1bb4c59adc | |||
| 2332ac5f87 | |||
| 0700b8510f | |||
| 7bc82ad672 | |||
| 92b9900d6e | |||
| 312ca07bb7 | |||
| bea621d6c6 | |||
| 28a8eb3856 | |||
| fb39317a64 | |||
| 6e7f80363b | |||
| 82bd2ff5a9 | |||
| e657192d31 | |||
| 85782cffd7 | |||
| fac004cfe9 | |||
| 221c293ac7 | |||
| 5ad20a0633 | |||
| d63bdf9bb9 | |||
| bc29f1c98a | |||
| 4830f55122 | |||
| 48508e4ecc | |||
| fbb2d6592d | |||
| 581a497189 | |||
| 3d3314d433 | |||
| a1f21bad0d | |||
| 189810269a | |||
| e592c6dd9d | |||
| 563cfa0e1e | |||
| 863fb96ffa | |||
| 10f03d2a99 | |||
| b3b04e083b | |||
| 9262b490ee | |||
| f37d0629ea | |||
| 6d9518cf56 | |||
| 0d8bf37407 | |||
| 159115b7c7 | |||
| 930dba73c3 | |||
| 22217ac42f | |||
| d46ee17722 | |||
| 5f1d9df828 | |||
| 95cc0d562b | |||
| 3584cd786a | |||
| fa92e6a809 | |||
| 1257e39d92 | |||
| 65c7339199 | |||
| 2cb720a3d2 | |||
| 138ed9c1fa | |||
| 3c7a4833e5 | |||
| 0400b5ef3f | |||
| 122ed3beaf | |||
| b58a45df37 | |||
| 2d450e9a3b | |||
| 3513964883 | |||
| fde9d44286 | |||
| ba8185cb2a | |||
| 362c598d1b | |||
| 185fc93ed5 | |||
| 8b254440d6 | |||
| 5989a94787 | |||
| e290345cd6 | |||
| 4c48bccbad | |||
| ef1bb2b193 | |||
| 9e103451e2 | |||
| 832f5f7019 | |||
| 40f92ac55d | |||
| 887efbd939 | |||
| 6305c7b83c | |||
| 6bbb4e4df2 | |||
| 79e98f6ac4 | |||
| 1c1a96981d | |||
| 6e9d203e52 | |||
| c02fc98d06 | |||
| 895e5748e1 | |||
| 96805ec18e | |||
| 010f1eff60 | |||
| a713a68af8 | |||
| 1547225e52 | |||
| cc52ff7703 | |||
| 3f51798192 | |||
| 8578e19aff | |||
| e4ffa5f3f6 | |||
| 8cc9ebea1e | |||
| 2cb5248ac3 | |||
| 43a9717a33 | |||
| 4fd5a7bfcb | |||
| 3c2c15d4dc | |||
| 7969cfb39f | |||
| f2fe8b1664 | |||
| 23dc056578 | |||
| 3e9dadc85e | |||
| 6e37e120fc | |||
| 091a6ca62e | |||
| a8cdc38272 | |||
| 2296b4b16e | |||
| 4e873c2ab6 | |||
| 130d29bb5f | |||
| 3ae4d6e824 | |||
| be1847d075 | |||
| 68810e04c6 | |||
| b8b894dd36 | |||
| a12b0aff07 | |||
| 3523edfd90 | |||
| fbaab99733 | |||
| 6408db6427 | |||
| 2cd36e8ea0 | |||
| 6a930e2c88 | |||
| 78079c3f2b | |||
| a88c706d98 | |||
| b9d20f8481 | |||
| 545b24fa52 | |||
| 2f6437ec5c | |||
| 806042d58a | |||
| 58e66823a2 | |||
| 119010b16d | |||
| c6895d7dd4 | |||
| 1f7f5e368d | |||
| b80006b600 | |||
| 9e42721660 | |||
| 0f13aee6fb | |||
| 8cc4708c2a | |||
| 507d51eebf | |||
| 89d8f73703 | |||
| f0f37cb2e7 | |||
| 62cd827dc5 | |||
| 1b682b3b6a | |||
| 5e372ecd61 | |||
| 4401c891e8 | |||
| 61a17c94be | |||
| 75911e67bd | |||
| 3a2eb35800 | |||
| 5ae88aba9d | |||
| dbd0a1dbf7 | |||
| d1e4c0fecc | |||
| 522dd18e62 | |||
| 563bfb4582 | |||
| f03d9e1aab | |||
| 454a93cbbf | |||
| a64f376595 | |||
| f620bbf2f5 | |||
| 4ddbc1ee38 | |||
| f9bd169b6e | |||
| 332fdda507 | |||
| 77f46da53a | |||
| ebacd8353f | |||
| a97c45a15d | |||
| f307dc23d7 | |||
| b21f182106 | |||
| 0991b0a091 | |||
| 54eb1f8f23 | |||
| 97df1db020 | |||
| 8c1eb6cfd3 | |||
| 4eeb1bbd8f | |||
| 5778aa1fa1 | |||
| a0c582342c | |||
| cf13f285e4 | |||
| 08d7dd1db4 | |||
| a6908c3ee8 | |||
| cc91fe0988 | |||
| f66e6749ae | |||
| f3fd372584 | |||
| e29a887814 | |||
| f1743d9179 | |||
| 73827e8eda | |||
| abb81c79d7 | |||
| 8b55712485 | |||
| f967acc533 | |||
| 61d4bf3f88 | |||
| 94dc00614c | |||
| 976ec609bc | |||
| 7cc4f8883a | |||
| 9b48e7420e | |||
| eae4f24877 | |||
| 72e24ec057 | |||
| da2cb39c15 | |||
| 695b470305 | |||
| 076bbff5a7 | |||
| 023064558f | |||
| a934784741 | |||
| 13a31a6b83 | |||
| f29c1bee74 | |||
| 3c5ba23f7f | |||
| 777c810671 | |||
| 9a642c49e1 | |||
| a5708767a0 | |||
| 1117eb6579 | |||
| f131e22bc4 | |||
| 76fd40f2f9 | |||
| 52925cb9df | |||
| 3d68237956 | |||
| b79b33c664 | |||
| 8a6b5024a1 | |||
| f51dcd3c96 | |||
| 7a4f10ddda | |||
| 2d7f517b5b | |||
| 3161583d89 | |||
| 9e3b1f2d7e | |||
| ff2d425711 | |||
| 95c4f624c8 | |||
| 7882fff01a | |||
| d68848383e | |||
| f395c5b238 | |||
| a9782addfc | |||
| d093887447 | |||
| f0be299db3 | |||
| 6a3edc34bd | |||
| 135dfe2144 | |||
| 13de4b94dc | |||
| c6ec3c048e | |||
| 6d1680998d | |||
| bbfcb91b1f | |||
| 7d1f5e81ea | |||
| 5f9d183b46 | |||
| 646ebff5dd | |||
| 8f6f312d65 | |||
| 5762e5ec3e | |||
| 52dbe51339 | |||
| dfaad3e8ca | |||
| 7da6f2675d | |||
| 9ae2623d89 | |||
| e64f37c3c5 | |||
| b39ed13500 | |||
| 532a81f846 | |||
| 2b96f7b343 | |||
| 6a07b3c08c | |||
| 744726275d | |||
| 07afdeedac | |||
| b8c3fefd02 | |||
| ac7cb0921b | |||
| 6b6a083916 | |||
| 6acd719f0f | |||
| 455e7f50d8 | |||
| f49fe84488 | |||
| 5ce4bd05df | |||
| b9f2e3d99b | |||
| 42bcf62000 | |||
| 86f5acdc88 | |||
| 45aa8db99d | |||
| d35fc78761 | |||
| d8b0be3eb3 | |||
| 12e884c5b3 | |||
| 115d6033fc | |||
| 9ffeab1ad1 | |||
| 7bad9a9f15 | |||
| 5a003a1da9 | |||
| 9e96129104 | |||
| 5068d59b13 | |||
| bf9c4ab68a | |||
| 44022305cc | |||
| 0595cfb07d | |||
| c8098c7a80 | |||
| 2e71c132fe | |||
| 7c3522f902 | |||
| 4dcb3165e7 | |||
| 4fbe8bec4a | |||
| 4a723a329e | |||
| 592b8980aa | |||
| 1e63a97698 | |||
| 9d41810bed | |||
| 8cdebcf4e0 | |||
| 9744e6e8cb | |||
| f4d6bd1188 | |||
| d8c8c75ec4 | |||
| 9eaaa8997b | |||
| ef2a7d7302 | |||
| b660b92b3f | |||
| 87ae4833c4 | |||
| 4f9d34da81 | |||
| 13ad9d1f5b | |||
| 8cf328dc54 | |||
| af1f371aa7 | |||
| 3e78b603a5 | |||
| 50da793d5b | |||
| 4affbe94be | |||
| d18eacbd35 | |||
| 3de3755281 | |||
| 04a1611139 | |||
| 0b5889d299 | |||
| aa6bf0f367 | |||
| 7164e1626e | |||
| a869415180 | |||
| b39f2de8ad | |||
| b02b1f3ea9 | |||
| 72ad5d94ea | |||
| 1c2358de43 | |||
| ba56dfb574 | |||
| da48e72353 | |||
| 3c5757b0e2 | |||
| e1a310bde7 | |||
| a040f29f03 | |||
| 3f3262c76e | |||
| 5018c4e4db | |||
| 6e5ae126af | |||
| a0b8d8c0ff | |||
| 1636ee5980 | |||
| a092131b73 | |||
| b4a73ff47f | |||
| 73c4f6c2a5 | |||
| d8a886d75a | |||
| 480f26720d | |||
| 333d17b8e1 | |||
| f78caa59d2 | |||
| 1f09dea479 | |||
| 8e619076cb | |||
| d80e9d463d | |||
| 6a17f29147 | |||
| cafc042bf6 | |||
| d2e303436b | |||
| fb0d5acf4c | |||
| 376d34142f | |||
| 8eb7f7e366 | |||
| 762e8afa6f | |||
| c3018e9ee7 | |||
| 996c94fd08 | |||
| fd7c3c4834 | |||
| c3b7f2f974 | |||
| 8589fbda8c | |||
| f1a681c983 | |||
| a17188f51c | |||
| 8a66849a57 | |||
| 20318b8b7d | |||
| d84d6f57a3 | |||
| 619e11c07a | |||
| 01ec0ee85b | |||
| 91b23a2caa | |||
| 053a433d74 | |||
| 3725a41b39 | |||
| fe5ca8e768 | |||
| b1a2e67326 | |||
| 40553ed459 | |||
| ae9e1f1888 | |||
| 9127c17778 | |||
| 8f28fbee11 | |||
| be7bda671e | |||
| c58101cde3 | |||
| 4a16804df7 | |||
| ff92024ec2 | |||
| 6e5b0b5c20 | |||
| c201456f20 | |||
| 02b3d5aacf | |||
| dde1ead9fe | |||
| 3915147b9b | |||
| 55c7fe15a0 | |||
| 82dba4d510 | |||
| 9ecff3766a | |||
| 4fb85c9c9f | |||
| 6ea5922916 | |||
| 287e8f16e6 | |||
| 846422a90f | |||
| ea6621e00e | |||
| 44ffa8a801 | |||
| a1d5911159 | |||
| c38e38d6b4 | |||
| f5b5f97f56 | |||
| 5528302282 | |||
| 995f0a3a58 | |||
| 894ebe38a2 | |||
| 0609febf16 | |||
| 1d6c1cc0ae | |||
| 50b076c4af | |||
| d783f12861 | |||
| f324c2d16c | |||
| 5486975097 | |||
| d4b6b26f4f | |||
| 996dd0b0b9 | |||
| b44588aaba | |||
| 95fbf4d8e5 | |||
| 6f78024717 | |||
| 7b2e257157 | |||
| bb344d07e7 | |||
| 959c2cb84e | |||
| ee7b438f61 | |||
| dc0241306b | |||
| 89ce4db476 | |||
| 55a1405a84 | |||
| fb21fc9274 | |||
| 57b920b8b7 | |||
| bae07c1bfb | |||
| 4f7016f2da | |||
| 7af8441403 | |||
| 7ba95339a6 | |||
| b6c37f2926 | |||
| b8408c3582 | |||
| fb625069cf | |||
| d4297993a4 | |||
| 2104324ded | |||
| 153b2cb484 | |||
| c72adaa749 | |||
| 3c2ed1533c | |||
| b9518bf811 | |||
| 4f0f1bd84f | |||
| e2ef786003 | |||
| 5b134b5de5 | |||
| 62c4da281a | |||
| 4c27f858b9 | |||
| 6ced5c26d0 | |||
| ccd504115d | |||
| 647e5d8021 | |||
| 6a7042d980 | |||
| 7532b032bb | |||
| b5c1d17da5 | |||
| 56a7d91066 | |||
| 93d636a95b | |||
| 7ca771e4ac | |||
| 6e7e7e1241 | |||
| 8b43f32f8c | |||
| a30eb7d16c |
+1
-4
@@ -19,7 +19,6 @@ lib/editor/tinymce/plugins/spellchecker/rpc.php
|
||||
lib/editor/tinymce/tiny_mce/
|
||||
lib/mlbackend/php/phpml/
|
||||
lib/adodb/
|
||||
lib/behat/axe/
|
||||
lib/bennu/
|
||||
lib/evalmath/
|
||||
lib/phpspreadsheet/
|
||||
@@ -67,9 +66,6 @@ lib/babel-polyfill/
|
||||
lib/polyfills/
|
||||
lib/emoji-data/
|
||||
lib/plist/
|
||||
lib/zipstream/
|
||||
lib/php-enum/
|
||||
lib/http-message/
|
||||
media/player/videojs/amd/src/video-lazy.js
|
||||
media/player/videojs/amd/src/Youtube-lazy.js
|
||||
media/player/videojs/videojs/
|
||||
@@ -92,4 +88,5 @@ theme/boost/amd/src/bootstrap/tab.js
|
||||
theme/boost/amd/src/bootstrap/toast.js
|
||||
theme/boost/amd/src/bootstrap/tooltip.js
|
||||
theme/boost/amd/src/bootstrap/util.js
|
||||
theme/boost/amd/src/tether.js
|
||||
theme/boost/scss/fontawesome/
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Template configuraton file for github actions CI/CD.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2020 onwards Eloy Lafuente (stronk7) {@link https://stronk7.com}
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
// This cannot be used out from a github actions workflow, so just exit.
|
||||
getenv('GITHUB_WORKFLOW') || die; // phpcs:ignore moodle.Files.MoodleInternal.MoodleInternalGlobalState
|
||||
|
||||
unset($CFG);
|
||||
global $CFG;
|
||||
$CFG = new stdClass();
|
||||
|
||||
$CFG->dbtype = getenv('dbtype');
|
||||
$CFG->dblibrary = 'native';
|
||||
$CFG->dbhost = '127.0.0.1';
|
||||
$CFG->dbname = 'test';
|
||||
$CFG->dbuser = 'test';
|
||||
$CFG->dbpass = 'test';
|
||||
$CFG->prefix = 'm_';
|
||||
$CFG->dboptions = ['dbcollation' => 'utf8mb4_bin'];
|
||||
|
||||
$host = 'localhost';
|
||||
$CFG->wwwroot = "http://{$host}";
|
||||
$CFG->dataroot = realpath(dirname(__DIR__)) . '/moodledata';
|
||||
$CFG->admin = 'admin';
|
||||
$CFG->directorypermissions = 0777;
|
||||
|
||||
// Debug options - possible to be controlled by flag in future.
|
||||
$CFG->debug = (E_ALL | E_STRICT); // DEBUG_DEVELOPER.
|
||||
$CFG->debugdisplay = 1;
|
||||
$CFG->debugstringids = 1; // Add strings=1 to url to get string ids.
|
||||
$CFG->perfdebug = 15;
|
||||
$CFG->debugpageinfo = 1;
|
||||
$CFG->allowthemechangeonurl = 1;
|
||||
$CFG->passwordpolicy = 0;
|
||||
$CFG->cronclionly = 0;
|
||||
$CFG->pathtophp = getenv('pathtophp');
|
||||
|
||||
$CFG->phpunit_dataroot = realpath(dirname(__DIR__)) . '/phpunitdata';
|
||||
$CFG->phpunit_prefix = 't_';
|
||||
|
||||
define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://localhost:8080');
|
||||
define('TEST_EXTERNAL_FILES_HTTPS_URL', 'http://localhost:8080');
|
||||
|
||||
define('TEST_SESSION_REDIS_HOST', 'localhost');
|
||||
define('TEST_CACHESTORE_REDIS_TESTSERVERS', 'localhost');
|
||||
|
||||
// TODO: add others (solr, mongodb, memcached, ldap...).
|
||||
|
||||
// Too much for now: define('PHPUNIT_LONGTEST', true); // Only leaves a few tests out and they are run later by CI.
|
||||
|
||||
require_once(__DIR__ . '/lib/setup.php');
|
||||
@@ -0,0 +1,103 @@
|
||||
name: Core
|
||||
|
||||
on: [push]
|
||||
|
||||
env:
|
||||
php: 7.4
|
||||
|
||||
jobs:
|
||||
Grunt:
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
steps:
|
||||
- name: Checking out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Configuring node & npm
|
||||
shell: bash -l {0}
|
||||
run: nvm install
|
||||
|
||||
- name: Installing node stuff
|
||||
run: npm install
|
||||
|
||||
- name: Running grunt
|
||||
run: npx grunt
|
||||
|
||||
- name: Looking for uncommitted changes
|
||||
# Add all files to the git index and then run diff --cached to see all changes.
|
||||
# This ensures that we get the status of all files, including new files.
|
||||
# We ignore npm-shrinkwrap.json to make the tasks immune to npm changes.
|
||||
run: |
|
||||
git add .
|
||||
git reset -- npm-shrinkwrap.json
|
||||
git diff --cached --exit-code
|
||||
|
||||
PHPUnit:
|
||||
runs-on: ${{ matrix.os }}
|
||||
services:
|
||||
exttests:
|
||||
image: moodlehq/moodle-exttests
|
||||
ports:
|
||||
- 8080:80
|
||||
redis:
|
||||
image: redis
|
||||
ports:
|
||||
- 6379:6379
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-18.04
|
||||
php: 7.2
|
||||
db: mysqli
|
||||
- os: ubuntu-18.04
|
||||
php: 7.4
|
||||
db: pgsql
|
||||
|
||||
steps:
|
||||
- name: Setting up DB mysql
|
||||
if: ${{ matrix.db == 'mysqli' }}
|
||||
uses: johanmeiring/mysql-action@tmpfs-patch
|
||||
with:
|
||||
collation server: utf8mb4_bin
|
||||
mysql version: 5.7
|
||||
mysql database: test
|
||||
mysql user: test
|
||||
mysql password: test
|
||||
use tmpfs: true
|
||||
|
||||
- name: Setting up DB pgsql
|
||||
if: ${{ matrix.db == 'pgsql' }}
|
||||
uses: m4nu56/postgresql-action@v1
|
||||
with:
|
||||
postgresql version: 9.6
|
||||
postgresql db: test
|
||||
postgresql user: test
|
||||
postgresql password: test
|
||||
|
||||
- name: Configuring git vars
|
||||
uses: rlespinasse/github-slug-action@v3.x
|
||||
|
||||
- name: Setting up PHP ${{ matrix.php }}
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
coverage: none
|
||||
|
||||
- name: Checking out code from ${{ env.GITHUB_REF_SLUG }}
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setting up PHPUnit
|
||||
env:
|
||||
dbtype: ${{ matrix.db }}
|
||||
run: |
|
||||
echo "pathtophp=$(which php)" >> $GITHUB_ENV # Inject installed pathtophp to env. The template config needs it.
|
||||
cp .github/workflows/config-template.php config.php
|
||||
mkdir ../moodledata
|
||||
sudo locale-gen en_AU.UTF-8
|
||||
php admin/tool/phpunit/cli/init.php --no-composer-self-update
|
||||
|
||||
- name: Running PHPUnit tests
|
||||
env:
|
||||
dbtype: ${{ matrix.db }}
|
||||
run: vendor/bin/phpunit -v
|
||||
@@ -33,7 +33,6 @@ CVS
|
||||
/.project
|
||||
/.buildpath
|
||||
/.cache
|
||||
.phpunit.result.cache
|
||||
phpunit.xml
|
||||
# Composer support. Do not ignore composer.json, or composer.lock. These should be shipped by us.
|
||||
composer.phar
|
||||
@@ -45,4 +44,3 @@ composer.phar
|
||||
/lib/yuilib/*/*/*-coverage.js
|
||||
atlassian-ide-plugin.xml
|
||||
/node_modules/
|
||||
/.vscode/
|
||||
|
||||
+1
-4
@@ -20,7 +20,6 @@ lib/editor/tinymce/plugins/spellchecker/rpc.php
|
||||
lib/editor/tinymce/tiny_mce/
|
||||
lib/mlbackend/php/phpml/
|
||||
lib/adodb/
|
||||
lib/behat/axe/
|
||||
lib/bennu/
|
||||
lib/evalmath/
|
||||
lib/phpspreadsheet/
|
||||
@@ -68,9 +67,6 @@ lib/babel-polyfill/
|
||||
lib/polyfills/
|
||||
lib/emoji-data/
|
||||
lib/plist/
|
||||
lib/zipstream/
|
||||
lib/php-enum/
|
||||
lib/http-message/
|
||||
media/player/videojs/amd/src/video-lazy.js
|
||||
media/player/videojs/amd/src/Youtube-lazy.js
|
||||
media/player/videojs/videojs/
|
||||
@@ -93,4 +89,5 @@ theme/boost/amd/src/bootstrap/tab.js
|
||||
theme/boost/amd/src/bootstrap/toast.js
|
||||
theme/boost/amd/src/bootstrap/tooltip.js
|
||||
theme/boost/amd/src/bootstrap/util.js
|
||||
theme/boost/amd/src/tether.js
|
||||
theme/boost/scss/fontawesome/
|
||||
+30
-72
@@ -16,31 +16,9 @@ services:
|
||||
- mysql
|
||||
- docker
|
||||
|
||||
php:
|
||||
# We only run the highest and lowest supported versions to reduce the load on travis-ci.org.
|
||||
- 7.4
|
||||
- 7.2
|
||||
|
||||
addons:
|
||||
postgresql: "9.6"
|
||||
|
||||
env:
|
||||
# Although we want to run these jobs and see failures as quickly as possible, we also want to get the slowest job to
|
||||
# start first so that the total run time is not too high.
|
||||
#
|
||||
# We only run MySQL on PHP 7.2, so run that first.
|
||||
# CI Tests should be second-highest in priority as these only take <= 60 seconds to run under normal circumstances.
|
||||
# Postgres is significantly is pretty reasonable in its run-time.
|
||||
|
||||
# Run CI Tests without running PHPUnit.
|
||||
- DB=none TASK=CITEST
|
||||
|
||||
# Run unit tests on Postgres
|
||||
- DB=pgsql TASK=PHPUNIT
|
||||
|
||||
# Perform an upgrade test too.
|
||||
- DB=pgsql TASK=UPGRADE
|
||||
|
||||
jobs:
|
||||
# Enable fast finish.
|
||||
# This will fail the build if a single job fails (except those in allow_failures).
|
||||
@@ -48,12 +26,35 @@ jobs:
|
||||
fast_finish: true
|
||||
|
||||
include:
|
||||
# Run mysql only on highest - it's just too slow
|
||||
- php: 7.4
|
||||
# First all the lowest php ones (7.2)
|
||||
- php: 7.2
|
||||
env: DB=none TASK=CITEST
|
||||
- php: 7.2
|
||||
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
|
||||
|
||||
- if: env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present
|
||||
php: 7.2
|
||||
env: DB=pgsql TASK=PHPUNIT
|
||||
|
||||
- if: env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all"
|
||||
php: 7.2
|
||||
env: DB=mysqli TASK=PHPUNIT
|
||||
|
||||
# Then, conditionally, all the highest php ones (7.4)
|
||||
- if: env(MOODLE_PHP) = "all"
|
||||
php: 7.4
|
||||
env: DB=none TASK=CITEST
|
||||
- if: env(MOODLE_PHP) = "all"
|
||||
php: 7.4
|
||||
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
|
||||
|
||||
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "pgsql" OR env(MOODLE_DATABASE) = "all" OR env(MOODLE_DATABASE) IS NOT present)
|
||||
php: 7.4
|
||||
env: DB=pgsql TASK=PHPUNIT
|
||||
|
||||
- if: env(MOODLE_PHP) = "all" AND (env(MOODLE_DATABASE) = "mysqli" OR env(MOODLE_DATABASE) = "all")
|
||||
php: 7.4
|
||||
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
|
||||
env: DB=none TASK=GRUNT NVM_VERSION='lts/carbon'
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@@ -113,7 +114,7 @@ install:
|
||||
before_script:
|
||||
- phpenv config-rm xdebug.ini
|
||||
- >
|
||||
if [ "$TASK" = 'PHPUNIT' -o "$TASK" = 'UPGRADE' ];
|
||||
if [ "$TASK" = 'PHPUNIT' ];
|
||||
then
|
||||
# Copy generic configuration in place.
|
||||
cp config-dist.php config.php ;
|
||||
@@ -213,7 +214,7 @@ before_script:
|
||||
# We need the official upstream for comparison
|
||||
git remote add upstream https://github.com/moodle/moodle.git;
|
||||
|
||||
git fetch upstream MOODLE_310_STABLE;
|
||||
git fetch upstream MOODLE_39_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`
|
||||
@@ -224,32 +225,6 @@ before_script:
|
||||
export phpcmd=`which php`;
|
||||
fi
|
||||
|
||||
########################################################################
|
||||
# Upgrade test
|
||||
########################################################################
|
||||
- >
|
||||
if [ "$TASK" = 'UPGRADE' ];
|
||||
then
|
||||
# We need the official upstream.
|
||||
git remote add upstream https://github.com/moodle/moodle.git;
|
||||
|
||||
# Checkout 30 STABLE branch (the first version compatible with PHP 7.x)
|
||||
git fetch upstream MOODLE_30_STABLE;
|
||||
git checkout MOODLE_30_STABLE;
|
||||
|
||||
# Perform the upgrade
|
||||
php admin/cli/install_database.php --agree-license --adminpass=Password --adminemail=admin@example.com --fullname="Upgrade test" --shortname=Upgrade;
|
||||
|
||||
# Return to the previous commit
|
||||
git checkout -;
|
||||
|
||||
# Perform the upgrade
|
||||
php admin/cli/upgrade.php --non-interactive --allow-unstable ;
|
||||
|
||||
# The local_ci repository can be used to check upgrade savepoints.
|
||||
git clone https://github.com/moodlehq/moodle-local_ci.git local/ci ;
|
||||
fi
|
||||
|
||||
script:
|
||||
- >
|
||||
if [ "$TASK" = 'PHPUNIT' ];
|
||||
@@ -275,23 +250,6 @@ script:
|
||||
git diff --cached --exit-code ;
|
||||
fi
|
||||
|
||||
########################################################################
|
||||
# Upgrade test
|
||||
########################################################################
|
||||
- >
|
||||
if [ "$TASK" = 'UPGRADE' ];
|
||||
then
|
||||
cp local/ci/check_upgrade_savepoints/check_upgrade_savepoints.php ./check_upgrade_savepoints.php
|
||||
result=`php check_upgrade_savepoints.php`;
|
||||
# Check if there are problems
|
||||
count=`echo "$result" | grep -P "ERROR|WARN" | wc -l` ;
|
||||
if (($count > 0));
|
||||
then
|
||||
echo "$result"
|
||||
exit 1 ;
|
||||
fi
|
||||
fi
|
||||
|
||||
after_script:
|
||||
- >
|
||||
if [ "$TASK" = 'PHPUNIT' ];
|
||||
|
||||
+18
-25
@@ -15,41 +15,34 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Clientside filter base.
|
||||
* Admin settings search form
|
||||
*
|
||||
* @package tool_usertours
|
||||
* @copyright 2020 The Open University
|
||||
* @package admin
|
||||
* @copyright 2016 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_usertours\local\clientside_filter;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use stdClass;
|
||||
use tool_usertours\local\filter\base;
|
||||
use tool_usertours\tour;
|
||||
require_once $CFG->libdir.'/formslib.php';
|
||||
|
||||
/**
|
||||
* Clientside filter base.
|
||||
* Admin settings search form
|
||||
*
|
||||
* @copyright 2020 The Open University
|
||||
* @package admin
|
||||
* @copyright 2016 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
abstract class clientside_filter extends base {
|
||||
/**
|
||||
* Returns the filter values needed for client side filtering.
|
||||
*
|
||||
* @param tour $tour The tour to find the filter values for
|
||||
* @return stdClass
|
||||
*/
|
||||
public static function get_client_side_values(tour $tour): stdClass {
|
||||
$data = (object) [];
|
||||
class admin_settings_search_form extends moodleform {
|
||||
function definition () {
|
||||
$mform = $this->_form;
|
||||
|
||||
if (is_a(static::class, clientside_filter::class, true)) {
|
||||
$data->filterdata = $tour->get_filter_values(static::get_filter_name());
|
||||
}
|
||||
|
||||
return $data;
|
||||
//$mform->addElement('header', 'settingsheader', get_string('search', 'admin'));
|
||||
$elements = [];
|
||||
$elements[] = $mform->createElement('text', 'query', get_string('query', 'admin'));
|
||||
$elements[] = $mform->createElement('submit', 'search', get_string('search'));
|
||||
$mform->addGroup($elements);
|
||||
$mform->setType('query', PARAM_RAW);
|
||||
$mform->setDefault('query', optional_param('query', '', PARAM_RAW));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ class testoutgoingmailconf_form extends \moodleform {
|
||||
$mform = $this->_form;
|
||||
|
||||
// Recipient.
|
||||
$options = ['maxlength' => '100', 'size' => '25', 'autocomplete' => 'email'];
|
||||
$options = ['maxlength' => '100', 'size' => '25'];
|
||||
$mform->addElement('text', 'recipient', get_string('testoutgoingmailconf_toemail', 'admin'), $options);
|
||||
$mform->setType('recipient', PARAM_EMAIL);
|
||||
$mform->addRule('recipient', get_string('required'), 'required');
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* External admin page class that allows a callback to be provided to determine whether page can be accessed
|
||||
*
|
||||
* @package core_admin
|
||||
* @copyright 2019 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_admin\local\externalpage;
|
||||
|
||||
use admin_externalpage;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once("{$CFG->libdir}/adminlib.php");
|
||||
|
||||
/**
|
||||
* Admin externalpage class
|
||||
*
|
||||
* @package core_admin
|
||||
* @copyright 2019 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class accesscallback extends admin_externalpage {
|
||||
|
||||
/** @var callable $accesscheckcallback */
|
||||
protected $accesscheckcallback;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $visiblename
|
||||
* @param string $url
|
||||
* @param callable $accesscheckcallback The callback method that will be executed to check whether user has access to
|
||||
* this page. The setting instance ($this) is passed as an argument to the callback. Should return boolean value
|
||||
* @param bool $hidden
|
||||
*/
|
||||
public function __construct(string $name, string $visiblename, string $url, callable $accesscheckcallback,
|
||||
bool $hidden = false) {
|
||||
|
||||
$this->accesscheckcallback = $accesscheckcallback;
|
||||
|
||||
parent::__construct($name, $visiblename, $url, [], $hidden);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the current user has access to this external page based on access callback
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function check_access() {
|
||||
return ($this->accesscheckcallback)($this);
|
||||
}
|
||||
}
|
||||
@@ -1,206 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Auto complete admin setting.
|
||||
*
|
||||
* @package core_admin
|
||||
* @copyright 2020 The Open University
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_admin\local\settings;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/adminlib.php');
|
||||
/**
|
||||
* Auto complete setting class.
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @copyright 2020 The Open University
|
||||
*/
|
||||
class autocomplete extends \admin_setting_configmultiselect {
|
||||
/** @var boolean Should we allow typing new entries to the field? */
|
||||
protected $tags = false;
|
||||
/** @var string Name of an AMD module to send/process ajax requests. */
|
||||
protected $ajax = '';
|
||||
/** @var string Placeholder text for an empty list. */
|
||||
protected $placeholder = '';
|
||||
/** @var bool Whether the search has to be case-sensitive. */
|
||||
protected $casesensitive = false;
|
||||
/** @var bool Show suggestions by default - but this can be turned off. */
|
||||
protected $showsuggestions = true;
|
||||
/** @var string String that is shown when there are no selections. */
|
||||
protected $noselectionstring = '';
|
||||
/** @var string Delimiter to store values in database. */
|
||||
protected $delimiter = ',';
|
||||
/** @var string Should be multiple choices? */
|
||||
protected $multiple = true;
|
||||
/** @var string The link to manage choices. */
|
||||
protected $manageurl = true;
|
||||
/** @var string The text to display in manage link. */
|
||||
protected $managetext = true;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $name unique ascii name, either 'mysetting' for settings that in config, or 'myplugin/mysetting'
|
||||
* for ones in config_plugins.
|
||||
* @param string $visiblename localised
|
||||
* @param string $description long localised info
|
||||
* @param array $defaultsetting array of selected items
|
||||
* @param array $choices options for autocomplete field
|
||||
* @param array $attributes settings for autocomplete field
|
||||
*/
|
||||
public function __construct($name, $visiblename, $description, $defaultsetting, $choices, $attributes = null) {
|
||||
|
||||
if ($attributes === null) {
|
||||
$attributes = [];
|
||||
}
|
||||
|
||||
$this->placeholder = get_string('search');
|
||||
$this->noselectionstring = get_string('noselection', 'form');
|
||||
$defaultattributes = [
|
||||
'tags',
|
||||
'showsuggestions',
|
||||
'placeholder',
|
||||
'noselectionstring',
|
||||
'ajax',
|
||||
'casesensitive',
|
||||
'delimiter',
|
||||
'multiple',
|
||||
'manageurl',
|
||||
'managetext'
|
||||
];
|
||||
|
||||
foreach ($defaultattributes as $attributename) {
|
||||
if (isset($attributes[$attributename])) {
|
||||
$this->$attributename = $attributes[$attributename];
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($name, $visiblename, $description, $defaultsetting, $choices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the select setting(s)
|
||||
*
|
||||
* @return mixed null or array. Null if no settings else array of setting(s)
|
||||
*/
|
||||
public function get_setting() {
|
||||
$result = $this->config_read($this->name);
|
||||
if (is_null($result)) {
|
||||
return null;
|
||||
}
|
||||
if ($result === '') {
|
||||
return [];
|
||||
}
|
||||
return explode($this->delimiter, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves setting(s) provided through $data
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function write_setting($data) {
|
||||
if (!is_array($data)) {
|
||||
return ''; // Ignore it.
|
||||
}
|
||||
if (!$this->load_choices() || empty($this->choices)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
unset($data['xxxxx']);
|
||||
|
||||
$save = [];
|
||||
foreach ($data as $value) {
|
||||
if (!array_key_exists($value, $this->choices)) {
|
||||
continue; // Ignore it.
|
||||
}
|
||||
$save[] = $value;
|
||||
}
|
||||
|
||||
return ($this->config_write($this->name, implode($this->delimiter, $save)) ? '' : get_string('errorsetting', 'admin'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns XHTML autocomplete field
|
||||
*
|
||||
* @param array $data Array of values to select by default
|
||||
* @param string $query
|
||||
* @return string XHTML autocomplete field
|
||||
*/
|
||||
public function output_html($data, $query = '') {
|
||||
global $OUTPUT;
|
||||
|
||||
if (!$this->load_choices() or empty($this->choices)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$default = $this->get_defaultsetting();
|
||||
if (empty($default)) {
|
||||
$default = [];
|
||||
}
|
||||
|
||||
if (is_null($data)) {
|
||||
$data = [];
|
||||
}
|
||||
|
||||
$context = [
|
||||
'id' => $this->get_id(),
|
||||
'name' => $this->get_full_name()
|
||||
];
|
||||
|
||||
$defaults = [];
|
||||
$options = [];
|
||||
$template = 'core_admin/local/settings/autocomplete';
|
||||
|
||||
foreach ($this->choices as $value => $name) {
|
||||
if (in_array($value, $default)) {
|
||||
$defaults[] = $name;
|
||||
}
|
||||
$options[] = [
|
||||
'value' => $value,
|
||||
'text' => $name,
|
||||
'selected' => in_array($value, $data),
|
||||
'disabled' => false
|
||||
];
|
||||
}
|
||||
|
||||
$context['options'] = $options;
|
||||
$context['tags'] = $this->tags;
|
||||
$context['placeholder'] = $this->placeholder;
|
||||
$context['casesensitive'] = $this->casesensitive;
|
||||
$context['multiple'] = $this->multiple;
|
||||
$context['showsuggestions'] = $this->showsuggestions;
|
||||
$context['manageurl'] = $this->manageurl;
|
||||
$context['managetext'] = $this->managetext;
|
||||
|
||||
if (is_null($default)) {
|
||||
$defaultinfo = null;
|
||||
} if (!empty($defaults)) {
|
||||
$defaultinfo = implode(', ', $defaults);
|
||||
} else {
|
||||
$defaultinfo = get_string('none');
|
||||
}
|
||||
|
||||
$element = $OUTPUT->render_from_template($template, $context);
|
||||
|
||||
return format_admin_setting($this, $this->visiblename, $element, $this->description, true, '', $defaultinfo, $query);
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Payment gateway admin setting.
|
||||
*
|
||||
* @package core_admin
|
||||
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_admin\local\settings;
|
||||
|
||||
/**
|
||||
* Generic class for managing plugins in a table that allows re-ordering and enable/disable of each plugin.
|
||||
*/
|
||||
class manage_payment_gateway_plugins extends \admin_setting_manage_plugins {
|
||||
/**
|
||||
* Get the admin settings section title (use get_string).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_section_title() {
|
||||
return get_string('type_paygw_plural', 'plugin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of plugin to manage.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_plugin_type() {
|
||||
return 'paygw';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the second column.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_info_column_name() {
|
||||
return get_string('supportedcurrencies', 'core_payment');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of plugin to manage.
|
||||
*
|
||||
* @param plugininfo The plugin info class.
|
||||
* @return string
|
||||
*/
|
||||
public function get_info_column($plugininfo) {
|
||||
$codes = $plugininfo->get_supported_currencies();
|
||||
|
||||
$currencies = [];
|
||||
foreach ($codes as $c) {
|
||||
$currencies[$c] = new \lang_string($c, 'core_currencies');
|
||||
}
|
||||
|
||||
return implode(get_string('listsep', 'langconfig') . ' ', $currencies);
|
||||
}
|
||||
}
|
||||
@@ -57,8 +57,6 @@ class task_log_table extends \table_sql {
|
||||
'userid' => get_string('user', 'admin'),
|
||||
'timestart' => get_string('task_starttime', 'admin'),
|
||||
'duration' => get_string('task_duration', 'admin'),
|
||||
'hostname' => get_string('hostname', 'tool_task'),
|
||||
'pid' => get_string('pid', 'tool_task'),
|
||||
'db' => get_string('task_dbstats', 'admin'),
|
||||
'result' => get_string('task_result', 'admin'),
|
||||
'actions' => '',
|
||||
@@ -134,7 +132,6 @@ class task_log_table extends \table_sql {
|
||||
|
||||
$sql = "SELECT
|
||||
tl.id, tl.type, tl.component, tl.classname, tl.userid, tl.timestart, tl.timeend,
|
||||
tl.hostname, tl.pid,
|
||||
tl.dbreads, tl.dbwrites, tl.result,
|
||||
tl.dbreads + tl.dbwrites AS db,
|
||||
tl.timeend - tl.timestart AS duration,
|
||||
|
||||
@@ -37,13 +37,11 @@ list($options, $unrecognized) = cli_get_params(
|
||||
'showsql' => false,
|
||||
'showdebugging' => false,
|
||||
'ignorelimits' => false,
|
||||
'force' => false,
|
||||
], [
|
||||
'h' => 'help',
|
||||
'e' => 'execute',
|
||||
'k' => 'keep-alive',
|
||||
'i' => 'ignorelimits',
|
||||
'f' => 'force',
|
||||
]
|
||||
);
|
||||
|
||||
@@ -63,7 +61,6 @@ Options:
|
||||
-e, --execute Run all queued adhoc tasks
|
||||
-k, --keep-alive=N Keep this script alive for N seconds and poll for new adhoc tasks
|
||||
-i --ignorelimits Ignore task_adhoc_concurrency_limit and task_adhoc_max_runtime limits
|
||||
-f, --force Run even if cron is disabled
|
||||
|
||||
Example:
|
||||
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --execute
|
||||
@@ -95,12 +92,6 @@ if (moodle_needs_upgrading()) {
|
||||
if (empty($options['execute'])) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!get_config('core', 'cron_enabled') && !$options['force']) {
|
||||
mtrace('Cron is disabled. Use --force to override.');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (empty($options['keep-alive'])) {
|
||||
$options['keep-alive'] = 0;
|
||||
}
|
||||
|
||||
+6
-105
@@ -36,23 +36,14 @@ require_once($CFG->libdir.'/cronlib.php');
|
||||
|
||||
// now get cli options
|
||||
list($options, $unrecognized) = cli_get_params(
|
||||
[
|
||||
array(
|
||||
'help' => false,
|
||||
'stop' => false,
|
||||
'list' => false,
|
||||
'force' => false,
|
||||
'enable' => false,
|
||||
'disable' => false,
|
||||
'disable-wait' => false,
|
||||
], [
|
||||
),
|
||||
array(
|
||||
'h' => 'help',
|
||||
's' => 'stop',
|
||||
'l' => 'list',
|
||||
'f' => 'force',
|
||||
'e' => 'enable',
|
||||
'd' => 'disable',
|
||||
'w' => 'disable-wait',
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
if ($unrecognized) {
|
||||
@@ -65,13 +56,8 @@ if ($options['help']) {
|
||||
"Execute periodic cron actions.
|
||||
|
||||
Options:
|
||||
-h, --help Print out this help
|
||||
-s, --stop Notify all other running cron processes to stop after the current task
|
||||
-l, --list Show the list of currently running tasks and how long they have been running
|
||||
-f, --force Execute task even if cron is disabled
|
||||
-e, --enable Enable cron
|
||||
-d, --disable Disable cron
|
||||
-w, --disable-wait=600 Disable cron and wait until all tasks finished or fail after N seconds (optional param)
|
||||
-h, --help Print out this help
|
||||
-s, --stop Notify all other running cron processes to stop after the current task
|
||||
|
||||
Example:
|
||||
\$sudo -u www-data /usr/bin/php admin/cli/cron.php
|
||||
@@ -88,91 +74,6 @@ if ($options['stop']) {
|
||||
die;
|
||||
}
|
||||
|
||||
if ($options['enable']) {
|
||||
set_config('cron_enabled', 1);
|
||||
mtrace('Cron has been enabled for the site.');
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($options['disable']) {
|
||||
set_config('cron_enabled', 0);
|
||||
\core\task\manager::clear_static_caches();
|
||||
mtrace('Cron has been disabled for the site.');
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($options['list']) {
|
||||
$tasks = \core\task\manager::get_running_tasks();
|
||||
mtrace('The list of currently running tasks:');
|
||||
$format = "%7s %-12s %-9s %-20s %-52s\n";
|
||||
printf ($format,
|
||||
'PID',
|
||||
'HOST',
|
||||
'TYPE',
|
||||
'TIME',
|
||||
'CLASSNAME'
|
||||
);
|
||||
foreach ($tasks as $task) {
|
||||
printf ($format,
|
||||
$task->pid,
|
||||
substr($task->hostname, 0, 12),
|
||||
$task->type,
|
||||
format_time(time() - $task->timestarted),
|
||||
substr($task->classname, 0, 52)
|
||||
);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($wait = $options['disable-wait']) {
|
||||
$started = time();
|
||||
if (true === $wait) {
|
||||
// Default waiting time.
|
||||
$waitsec = 600;
|
||||
} else {
|
||||
$waitsec = $wait;
|
||||
$wait = true;
|
||||
}
|
||||
|
||||
set_config('cron_enabled', 0);
|
||||
\core\task\manager::clear_static_caches();
|
||||
mtrace('Cron has been disabled for the site.');
|
||||
mtrace('Allocating '. format_time($waitsec) . ' for the tasks to finish.');
|
||||
|
||||
$lastcount = 0;
|
||||
while ($wait) {
|
||||
$tasks = \core\task\manager::get_running_tasks();
|
||||
|
||||
if (count($tasks) == 0) {
|
||||
mtrace('');
|
||||
mtrace('All scheduled and adhoc tasks finished.');
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (time() - $started >= $waitsec) {
|
||||
mtrace('');
|
||||
mtrace('Wait time ('. format_time($waitsec) . ') elapsed, but ' . count($tasks) . ' task(s) still running.');
|
||||
mtrace('Exiting with code 1.');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (count($tasks) !== $lastcount) {
|
||||
mtrace('');
|
||||
mtrace(count($tasks) . " tasks currently running.", '');
|
||||
$lastcount = count($tasks);
|
||||
} else {
|
||||
mtrace('.', '');
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!get_config('core', 'cron_enabled') && !$options['force']) {
|
||||
mtrace('Cron is disabled. Use --force to override.');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
\core\local\cli\shutdown::script_supports_graceful_exit();
|
||||
|
||||
cron_run();
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* This script allows to restore a course from CLI.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage cli
|
||||
* @copyright 2020 Catalyst IT
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('CLI_SCRIPT', 1);
|
||||
|
||||
require(__DIR__ . '/../../config.php');
|
||||
require_once($CFG->libdir . '/clilib.php');
|
||||
require_once($CFG->dirroot . "/backup/util/includes/restore_includes.php");
|
||||
|
||||
list($options, $unrecognized) = cli_get_params([
|
||||
'file' => '',
|
||||
'categoryid' => '',
|
||||
'showdebugging' => false,
|
||||
'help' => false,
|
||||
], [
|
||||
'f' => 'file',
|
||||
'c' => 'categoryid',
|
||||
's' => 'showdebugging',
|
||||
'h' => 'help',
|
||||
]);
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
|
||||
}
|
||||
|
||||
if ($options['help'] || !($options['file']) || !($options['categoryid'])) {
|
||||
$help = <<<EOL
|
||||
Restore backup into provided category.
|
||||
|
||||
Options:
|
||||
-f, --file=STRING Path to the backup file.
|
||||
-c, --categoryid=INT ID of the category to restore too.
|
||||
-s, --showdebugging Show developer level debugging information
|
||||
-h, --help Print out this help.
|
||||
|
||||
Example:
|
||||
\$sudo -u www-data /usr/bin/php admin/cli/restore_backup.php --file=/path/to/backup/file.mbz --categoryid=1\n
|
||||
EOL;
|
||||
|
||||
echo $help;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ($options['showdebugging']) {
|
||||
set_debugging(DEBUG_DEVELOPER, true);
|
||||
}
|
||||
|
||||
if (!$admin = get_admin()) {
|
||||
print_error('noadmins');
|
||||
}
|
||||
|
||||
if (!file_exists($options['file'])) {
|
||||
print_error('filenotfound');
|
||||
}
|
||||
|
||||
if (!$category = $DB->get_record('course_categories', ['id' => $options['categoryid']], 'id')) {
|
||||
print_error('invalidcategoryid');
|
||||
}
|
||||
|
||||
$backupdir = "restore_" . uniqid();
|
||||
$path = $CFG->tempdir . DIRECTORY_SEPARATOR . "backup" . DIRECTORY_SEPARATOR . $backupdir;
|
||||
|
||||
cli_heading(get_string('extractingbackupfileto', 'backup', $path));
|
||||
$fp = get_file_packer('application/vnd.moodle.backup');
|
||||
$fp->extract_to_pathname($options['file'], $path);
|
||||
|
||||
cli_heading(get_string('preprocessingbackupfile'));
|
||||
try {
|
||||
list($fullname, $shortname) = restore_dbops::calculate_course_names(0, get_string('restoringcourse', 'backup'),
|
||||
get_string('restoringcourseshortname', 'backup'));
|
||||
|
||||
$courseid = restore_dbops::create_new_course($fullname, $shortname, $category->id);
|
||||
|
||||
$rc = new restore_controller($backupdir, $courseid, backup::INTERACTIVE_NO,
|
||||
backup::MODE_GENERAL, $admin->id, backup::TARGET_NEW_COURSE);
|
||||
$rc->execute_precheck();
|
||||
$rc->execute_plan();
|
||||
$rc->destroy();
|
||||
} catch (Exception $e) {
|
||||
cli_heading(get_string('cleaningtempdata'));
|
||||
fulldelete($path);
|
||||
print_error('generalexceptionmessage', 'error', '', $e->getMessage());
|
||||
}
|
||||
|
||||
cli_heading(get_string('restoredcourseid', 'backup', $courseid));
|
||||
exit(0);
|
||||
@@ -30,17 +30,8 @@ require_once("$CFG->libdir/clilib.php");
|
||||
require_once("$CFG->libdir/cronlib.php");
|
||||
|
||||
list($options, $unrecognized) = cli_get_params(
|
||||
[
|
||||
'help' => false,
|
||||
'list' => false,
|
||||
'execute' => false,
|
||||
'showsql' => false,
|
||||
'showdebugging' => false,
|
||||
'force' => false,
|
||||
], [
|
||||
'h' => 'help',
|
||||
'f' => 'force',
|
||||
]
|
||||
array('help' => false, 'list' => false, 'execute' => false, 'showsql' => false, 'showdebugging' => false),
|
||||
array('h' => 'help')
|
||||
);
|
||||
|
||||
if ($unrecognized) {
|
||||
@@ -58,7 +49,6 @@ if ($options['help'] or (!$options['list'] and !$options['execute'])) {
|
||||
--showsql Show sql queries before they are executed
|
||||
--showdebugging Show developer level debugging information
|
||||
-h, --help Print out this help
|
||||
-f, --force Execute task even if cron is disabled
|
||||
|
||||
Example:
|
||||
\$sudo -u www-data /usr/bin/php admin/cli/scheduled_task.php --execute=\\core\\task\\session_cleanup_task
|
||||
@@ -131,13 +121,6 @@ if ($execute = $options['execute']) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!get_config('core', 'cron_enabled') && !$options['force']) {
|
||||
mtrace('Cron is disabled. Use --force to override.');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
\core\task\manager::scheduled_task_starting($task);
|
||||
|
||||
// Increase memory limit.
|
||||
raise_memory_limit(MEMORY_EXTRA);
|
||||
|
||||
|
||||
@@ -38,17 +38,17 @@ if ($unrecognized) {
|
||||
}
|
||||
|
||||
// If necessary add files that should be ignored - such as in 3rd party plugins.
|
||||
$ignorelist = array();
|
||||
$blacklist = array();
|
||||
$path = $options['path'];
|
||||
if (!file_exists($path)) {
|
||||
cli_error("Invalid path $path");
|
||||
}
|
||||
|
||||
if ($options['ie9fix']) {
|
||||
core_admin_recurse_svgs($path, '', 'core_admin_svgtool_ie9fix', $ignorelist);
|
||||
core_admin_recurse_svgs($path, '', 'core_admin_svgtool_ie9fix', $blacklist);
|
||||
|
||||
} else if ($options['noaspectratio']) {
|
||||
core_admin_recurse_svgs($path, '', 'core_admin_svgtool_noaspectratio', $ignorelist);
|
||||
core_admin_recurse_svgs($path, '', 'core_admin_svgtool_noaspectratio', $blacklist);
|
||||
|
||||
} else {
|
||||
$help =
|
||||
@@ -153,9 +153,9 @@ function core_admin_svgtool_noaspectratio($file) {
|
||||
* @param string $base
|
||||
* @param string $sub
|
||||
* @param string $filecallback
|
||||
* @param array $ignorelist List of files to be ignored and skipped.
|
||||
* @param array $blacklist
|
||||
*/
|
||||
function core_admin_recurse_svgs($base, $sub, $filecallback, $ignorelist) {
|
||||
function core_admin_recurse_svgs($base, $sub, $filecallback, $blacklist) {
|
||||
if (is_dir("$base/$sub")) {
|
||||
$items = new DirectoryIterator("$base/$sub");
|
||||
foreach ($items as $item) {
|
||||
@@ -163,7 +163,7 @@ function core_admin_recurse_svgs($base, $sub, $filecallback, $ignorelist) {
|
||||
continue;
|
||||
}
|
||||
$file = $item->getFilename();
|
||||
core_admin_recurse_svgs("$base/$sub", $file, $filecallback, $ignorelist);
|
||||
core_admin_recurse_svgs("$base/$sub", $file, $filecallback, $blacklist);
|
||||
}
|
||||
unset($item);
|
||||
unset($items);
|
||||
@@ -174,7 +174,7 @@ function core_admin_recurse_svgs($base, $sub, $filecallback, $ignorelist) {
|
||||
return;
|
||||
}
|
||||
$file = realpath("$base/$sub");
|
||||
if (in_array($file, $ignorelist)) {
|
||||
if (in_array($file, $blacklist)) {
|
||||
return;
|
||||
}
|
||||
$filecallback($file);
|
||||
|
||||
@@ -3344,4 +3344,186 @@
|
||||
</CUSTOM_CHECK>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
<MOODLE version="3.11" requires="3.6">
|
||||
<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="14.0" />
|
||||
<VENDOR name="oracle" version="11.2" />
|
||||
</DATABASE>
|
||||
<PHP version="7.3.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_EXTENSION name="sodium" 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>
|
||||
|
||||
@@ -536,7 +536,7 @@ class core_role_privacy_testcase extends provider_testcase {
|
||||
$user1->id,
|
||||
$admin->id
|
||||
];
|
||||
$this->assertEqualsCanonicalizing($expected, $userlist2->get_userids());
|
||||
$this->assertEquals($expected, $userlist2->get_userids(), '', 0.0, 10, true);
|
||||
|
||||
// The user list for coursecontext1 should user1, user2 and admin (role creator).
|
||||
$userlist3 = new \core_privacy\local\request\userlist($coursecontext1, $component);
|
||||
@@ -547,7 +547,7 @@ class core_role_privacy_testcase extends provider_testcase {
|
||||
$user2->id,
|
||||
$admin->id
|
||||
];
|
||||
$this->assertEqualsCanonicalizing($expected, $userlist3->get_userids());
|
||||
$this->assertEquals($expected, $userlist3->get_userids(), '', 0.0, 10, true);
|
||||
|
||||
// The user list for coursecatcontext should user2 and admin (role creator).
|
||||
$userlist4 = new \core_privacy\local\request\userlist($coursecatcontext, $component);
|
||||
@@ -557,7 +557,7 @@ class core_role_privacy_testcase extends provider_testcase {
|
||||
$user2->id,
|
||||
$admin->id
|
||||
];
|
||||
$this->assertEqualsCanonicalizing($expected, $userlist4->get_userids());
|
||||
$this->assertEquals($expected, $userlist4->get_userids(), '', 0.0, 10, true);
|
||||
|
||||
// The user list for systemcontext should user1 and admin (role creator).
|
||||
$userlist6 = new \core_privacy\local\request\userlist($systemcontext, $component);
|
||||
@@ -567,7 +567,7 @@ class core_role_privacy_testcase extends provider_testcase {
|
||||
$user1->id,
|
||||
$admin->id
|
||||
];
|
||||
$this->assertEqualsCanonicalizing($expected, $userlist6->get_userids());
|
||||
$this->assertEquals($expected, $userlist6->get_userids(), '', 0.0, 10, true);
|
||||
|
||||
// The user list for cmcontext should user1, user2 and admin (role creator).
|
||||
$userlist7 = new \core_privacy\local\request\userlist($cmcontext, $component);
|
||||
@@ -578,7 +578,7 @@ class core_role_privacy_testcase extends provider_testcase {
|
||||
$user2->id,
|
||||
$admin->id
|
||||
];
|
||||
$this->assertEqualsCanonicalizing($expected, $userlist7->get_userids());
|
||||
$this->assertEquals($expected, $userlist7->get_userids(), '', 0.0, 10, true);
|
||||
|
||||
// The user list for blockcontext should user1 and admin (role creator).
|
||||
$userlist8 = new \core_privacy\local\request\userlist($blockcontext, $component);
|
||||
@@ -588,7 +588,7 @@ class core_role_privacy_testcase extends provider_testcase {
|
||||
$user1->id,
|
||||
$admin->id
|
||||
];
|
||||
$this->assertEqualsCanonicalizing($expected, $userlist8->get_userids());
|
||||
$this->assertEquals($expected, $userlist8->get_userids(), '', 0.0, 10, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -744,4 +744,4 @@ class core_role_privacy_testcase extends provider_testcase {
|
||||
}
|
||||
return $rolesnames;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-10
@@ -68,16 +68,9 @@ if ($errormsg !== '') {
|
||||
$showsettingslinks = true;
|
||||
|
||||
if ($hassiteconfig) {
|
||||
$data = [
|
||||
'action' => new moodle_url('/admin/search.php'),
|
||||
'btnclass' => 'btn-primary',
|
||||
'inputname' => 'query',
|
||||
'searchstring' => get_string('search'),
|
||||
'query' => $query,
|
||||
'extraclasses' => 'd-flex justify-content-center'
|
||||
];
|
||||
echo $OUTPUT->render_from_template('core/search_input', $data);
|
||||
|
||||
require_once("admin_settings_search_form.php");
|
||||
$form = new admin_settings_search_form();
|
||||
$form->display();
|
||||
echo '<hr>';
|
||||
if ($query) {
|
||||
echo admin_search_settings_html($query);
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use core_admin\local\settings\filesize;
|
||||
|
||||
$capabilities = array(
|
||||
'moodle/backup:backupcourse',
|
||||
'moodle/category:manage',
|
||||
@@ -77,17 +75,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
$temp->add(new admin_setting_configselect('moodlecourse/visible', new lang_string('visible'), new lang_string('visible_help'),
|
||||
1, $choices));
|
||||
|
||||
// Enable/disable download course content.
|
||||
$choices = [
|
||||
DOWNLOAD_COURSE_CONTENT_DISABLED => new lang_string('no'),
|
||||
DOWNLOAD_COURSE_CONTENT_ENABLED => new lang_string('yes'),
|
||||
];
|
||||
$downloadcontentsitedefault = new admin_setting_configselect('moodlecourse/downloadcontentsitedefault',
|
||||
new lang_string('enabledownloadcoursecontent', 'course'),
|
||||
new lang_string('downloadcoursecontent_help', 'course'), 0, $choices);
|
||||
$downloadcontentsitedefault->add_dependent_on('downloadcoursecontentallowed');
|
||||
$temp->add($downloadcontentsitedefault);
|
||||
|
||||
// Course format.
|
||||
$temp->add(new admin_setting_heading('courseformathdr', new lang_string('type_format', 'plugin'), ''));
|
||||
|
||||
@@ -174,21 +161,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
|
||||
$ADMIN->add('courses', $temp);
|
||||
|
||||
// Download course content.
|
||||
$downloadcoursedefaulturl = new moodle_url('/admin/settings.php', ['section' => 'coursesettings']);
|
||||
$temp = new admin_settingpage('downloadcoursecontent', new lang_string('downloadcoursecontent', 'course'));
|
||||
$temp->add(new admin_setting_configcheckbox('downloadcoursecontentallowed',
|
||||
new lang_string('downloadcoursecontentallowed', 'admin'),
|
||||
new lang_string('downloadcoursecontentallowed_desc', 'admin', $downloadcoursedefaulturl->out()), 0));
|
||||
|
||||
// 50MB default maximum size per file when downloading course content.
|
||||
$defaultmaxdownloadsize = 50 * filesize::UNIT_MB;
|
||||
$temp->add(new filesize('maxsizeperdownloadcoursefile', new lang_string('maxsizeperdownloadcoursefile', 'admin'),
|
||||
new lang_string('maxsizeperdownloadcoursefile_desc', 'admin'), $defaultmaxdownloadsize, filesize::UNIT_MB));
|
||||
$temp->hide_if('maxsizeperdownloadcoursefile', 'downloadcoursecontentallowed');
|
||||
|
||||
$ADMIN->add('courses', $temp);
|
||||
|
||||
// "courserequests" settingpage.
|
||||
$temp = new admin_settingpage('courserequest', new lang_string('courserequest'));
|
||||
$temp->add(new admin_setting_configcheckbox('enablecourserequests',
|
||||
@@ -212,7 +184,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
// Add a category for the Activity Chooser.
|
||||
$ADMIN->add('courses', new admin_category('activitychooser', new lang_string('activitychoosercategory', 'course')));
|
||||
$temp = new admin_settingpage('activitychoosersettings', new lang_string('activitychoosersettings', 'course'));
|
||||
// Tab mode for the activity chooser.
|
||||
$temp->add(
|
||||
new admin_setting_configselect(
|
||||
'activitychoosertabmode',
|
||||
@@ -226,31 +197,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
]
|
||||
)
|
||||
);
|
||||
|
||||
// Build a list of plugins that use the footer callback.
|
||||
$pluginswithfunction = get_plugins_with_function('custom_chooser_footer', 'lib.php');
|
||||
$pluginsoptions = [];
|
||||
$pluginsoptions[COURSE_CHOOSER_FOOTER_NONE] = get_string('activitychooserhidefooter', 'course');
|
||||
if ($pluginswithfunction) {
|
||||
foreach ($pluginswithfunction as $plugintype => $plugins) {
|
||||
foreach ($plugins as $pluginname => $pluginfunction) {
|
||||
$plugin = $plugintype.'_'.$pluginname;
|
||||
$pluginsoptions[$plugin] = get_string('pluginname', $plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Select what plugin to show in the footer.
|
||||
$temp->add(
|
||||
new admin_setting_configselect(
|
||||
'activitychooseractivefooter',
|
||||
new lang_string('activitychooseractivefooter', 'course'),
|
||||
new lang_string('activitychooseractivefooter_desc', 'course'),
|
||||
COURSE_CHOOSER_FOOTER_NONE,
|
||||
$pluginsoptions
|
||||
)
|
||||
);
|
||||
|
||||
$ADMIN->add('activitychooser', $temp);
|
||||
$ADMIN->add('activitychooser',
|
||||
new admin_externalpage('activitychooserrecommended', new lang_string('activitychooserrecommendations', 'course'),
|
||||
@@ -313,9 +259,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
['value' => 1, 'locked' => 0])
|
||||
);
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_general_legacyfiles',
|
||||
new lang_string('generallegacyfiles', 'backup'),
|
||||
new lang_string('configlegacyfiles', 'backup'), array('value' => 1, 'locked' => 0)));
|
||||
$ADMIN->add('backups', $temp);
|
||||
|
||||
// Create a page for general import configuration and defaults.
|
||||
@@ -342,9 +285,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
new lang_string('configgeneralcontentbankcontent', 'backup'),
|
||||
['value' => 1, 'locked' => 0])
|
||||
);
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('backup/backup_import_legacyfiles',
|
||||
new lang_string('generallegacyfiles', 'backup'),
|
||||
new lang_string('configlegacyfiles', 'backup'), array('value' => 1, 'locked' => 0)));
|
||||
|
||||
$ADMIN->add('backups', $temp);
|
||||
|
||||
@@ -471,10 +411,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
1)
|
||||
);
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('backup/backup_auto_legacyfiles',
|
||||
new lang_string('generallegacyfiles', 'backup'),
|
||||
new lang_string('configlegacyfiles', 'backup'), 1));
|
||||
|
||||
//$temp->add(new admin_setting_configcheckbox('backup/backup_auto_messages', new lang_string('messages', 'message'), new lang_string('backupmessageshelp','message'), 0));
|
||||
//$temp->add(new admin_setting_configcheckbox('backup/backup_auto_blogs', new lang_string('blogs', 'blog'), new lang_string('backupblogshelp','blog'), 0));
|
||||
|
||||
@@ -537,9 +473,6 @@ if ($hassiteconfig or has_any_capability($capabilities, $systemcontext)) {
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('restore/restore_general_contentbankcontent',
|
||||
new lang_string('generalcontentbankcontent', 'backup'),
|
||||
new lang_string('configrestorecontentbankcontent', 'backup'), array('value' => 1, 'locked' => 0)));
|
||||
$temp->add(new admin_setting_configcheckbox_with_lock('restore/restore_general_legacyfiles',
|
||||
new lang_string('generallegacyfiles', 'backup'),
|
||||
new lang_string('configlegacyfiles', 'backup'), array('value' => 1, 'locked' => 0)));
|
||||
|
||||
// Restore defaults when merging into another course.
|
||||
$temp->add(new admin_setting_heading('mergerestoredefaults', new lang_string('mergerestoredefaults', 'backup'), ''));
|
||||
|
||||
@@ -41,13 +41,6 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$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('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_configselect('debugsqltrace',
|
||||
new lang_string('debugsqltrace', 'admin'),
|
||||
new lang_string('debugsqltrace_desc', 'admin'), 0, array(
|
||||
0 => new lang_string('disabled', 'admin'),
|
||||
1 => new lang_string('debugsqltrace1', 'admin'),
|
||||
2 => new lang_string('debugsqltrace2', 'admin'),
|
||||
100 => new lang_string('debugsqltrace100', 'admin'))));
|
||||
$temp->add(new admin_setting_configcheckbox('debugvalidators', new lang_string('debugvalidators', 'admin'), new lang_string('configdebugvalidators', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('debugpageinfo', new lang_string('debugpageinfo', 'admin'), new lang_string('configdebugpageinfo', 'admin'), 0));
|
||||
$ADMIN->add('development', $temp);
|
||||
|
||||
@@ -8,8 +8,6 @@ if ($hassiteconfig) {
|
||||
$temp = new admin_settingpage('langsettings', new lang_string('languagesettings', 'admin'));
|
||||
$temp->add(new admin_setting_configcheckbox('autolang', new lang_string('autolang', 'admin'), new lang_string('configautolang', 'admin'), 1));
|
||||
$temp->add(new admin_setting_configselect('lang', new lang_string('lang', 'admin'), new lang_string('configlang', 'admin'), current_language(), get_string_manager()->get_list_of_translations())); // $CFG->lang might be set in installer already, default en is in setup.php
|
||||
$temp->add(new admin_setting_configcheckbox('autolangusercreation', new lang_string('autolangusercreation', 'admin'),
|
||||
new lang_string('configautolangusercreation', 'admin'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('langmenu', new lang_string('langmenu', 'admin'), new lang_string('configlangmenu', 'admin'), 1));
|
||||
$temp->add(new admin_setting_langlist());
|
||||
$temp->add(new admin_setting_configcheckbox('langcache', new lang_string('langcache', 'admin'), new lang_string('langcache_desc', 'admin'), 1));
|
||||
|
||||
@@ -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/>.
|
||||
|
||||
/**
|
||||
* Adds payments links to the admin tree
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2020 Marina Glancy
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$ADMIN->add('payment', new admin_externalpage(
|
||||
'paymentaccounts',
|
||||
new lang_string('paymentaccounts', 'payment'),
|
||||
new moodle_url("/payment/accounts.php"),
|
||||
['moodle/payment:manageaccounts', 'moodle/payment:viewpayments']));
|
||||
+2
-105
@@ -167,42 +167,6 @@ if ($hassiteconfig) {
|
||||
$ADMIN->add('modules', new admin_category('antivirussettings', new lang_string('antiviruses', 'antivirus')));
|
||||
$temp = new admin_settingpage('manageantiviruses', new lang_string('antivirussettings', 'antivirus'));
|
||||
$temp->add(new admin_setting_manageantiviruses());
|
||||
|
||||
// Common settings.
|
||||
$temp->add(new admin_setting_heading('antiviruscommonsettings', new lang_string('antiviruscommonsettings', 'antivirus'), ''));
|
||||
|
||||
// Alert email.
|
||||
$temp->add(
|
||||
new admin_setting_configtext(
|
||||
'antivirus/notifyemail',
|
||||
new lang_string('notifyemail', 'antivirus'),
|
||||
new lang_string('notifyemail_help', 'antivirus'),
|
||||
'',
|
||||
PARAM_EMAIL
|
||||
)
|
||||
);
|
||||
|
||||
// Enable quarantine.
|
||||
$temp->add(
|
||||
new admin_setting_configcheckbox(
|
||||
'antivirus/enablequarantine',
|
||||
new lang_string('enablequarantine', 'antivirus'),
|
||||
new lang_string('enablequarantine_help', 'antivirus',
|
||||
\core\antivirus\quarantine::DEFAULT_QUARANTINE_FOLDER),
|
||||
0
|
||||
)
|
||||
);
|
||||
|
||||
// Quarantine time.
|
||||
$temp->add(
|
||||
new admin_setting_configduration(
|
||||
'antivirus/quarantinetime',
|
||||
new lang_string('quarantinetime', 'antivirus'),
|
||||
new lang_string('quarantinetime_desc', 'antivirus'),
|
||||
\core\antivirus\quarantine::DEFAULT_QUARANTINE_TIME
|
||||
)
|
||||
);
|
||||
|
||||
$ADMIN->add('antivirussettings', $temp);
|
||||
$plugins = core_plugin_manager::instance()->get_plugins_of_type('antivirus');
|
||||
core_collator::asort_objects_by_property($plugins, 'displayname');
|
||||
@@ -280,25 +244,6 @@ if ($hassiteconfig) {
|
||||
$plugin->load_settings($ADMIN, 'mediaplayers', $hassiteconfig);
|
||||
}
|
||||
|
||||
// Payment gateway plugins.
|
||||
$ADMIN->add('modules', new admin_category('paymentgateways', new lang_string('type_paygw_plural', 'plugin')));
|
||||
$temp = new admin_settingpage('managepaymentgateways', new lang_string('type_paygwmanage', 'plugin'));
|
||||
$temp->add(new \core_admin\local\settings\manage_payment_gateway_plugins());
|
||||
$temp->add(new admin_setting_description(
|
||||
'managepaymentgatewayspostfix',
|
||||
'',
|
||||
new lang_string('gotopaymentaccounts', 'payment',
|
||||
html_writer::link(new moodle_url('/payment/accounts.php'), get_string('paymentaccounts', 'payment')))
|
||||
));
|
||||
$ADMIN->add('paymentgateways', $temp);
|
||||
|
||||
$plugins = core_plugin_manager::instance()->get_plugins_of_type('paygw');
|
||||
core_collator::asort_objects_by_property($plugins, 'displayname');
|
||||
foreach ($plugins as $plugin) {
|
||||
/** @var \core\plugininfo\paygw $plugin */
|
||||
$plugin->load_settings($ADMIN, 'paymentgateways', $hassiteconfig);
|
||||
}
|
||||
|
||||
// Data format settings.
|
||||
$ADMIN->add('modules', new admin_category('dataformatsettings', new lang_string('dataformats')));
|
||||
$temp = new admin_settingpage('managedataformats', new lang_string('managedataformats'));
|
||||
@@ -604,19 +549,8 @@ if ($hassiteconfig) {
|
||||
|
||||
// Search engine selection.
|
||||
$temp->add(new admin_setting_heading('searchengineheading', new lang_string('searchengine', 'admin'), ''));
|
||||
$searchengineselect = new admin_setting_configselect('searchengine',
|
||||
new lang_string('selectsearchengine', 'admin'), '', 'simpledb', $engines);
|
||||
$searchengineselect->set_validate_function(function(string $value): string {
|
||||
global $CFG;
|
||||
|
||||
// Check nobody's setting the indexing and query-only server to the same one.
|
||||
if (isset($CFG->searchenginequeryonly) && $CFG->searchenginequeryonly === $value) {
|
||||
return get_string('searchenginequeryonlysame', 'admin');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
$temp->add($searchengineselect);
|
||||
$temp->add(new admin_setting_configselect('searchengine',
|
||||
new lang_string('selectsearchengine', 'admin'), '', 'simpledb', $engines));
|
||||
$temp->add(new admin_setting_heading('searchoptionsheading', new lang_string('searchoptions', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configcheckbox('searchindexwhendisabled',
|
||||
new lang_string('searchindexwhendisabled', 'admin'), new lang_string('searchindexwhendisabled_desc', 'admin'),
|
||||
@@ -656,43 +590,6 @@ if ($hassiteconfig) {
|
||||
new lang_string('searchhideallcategory_desc', 'admin'),
|
||||
0));
|
||||
|
||||
$temp->add(new admin_setting_heading('searchmanagement', new lang_string('searchmanagement', 'admin'),
|
||||
new lang_string('searchmanagement_desc', 'admin')));
|
||||
|
||||
// Get list of search engines including those with alternate settings.
|
||||
$searchenginequeryonlyselect = new admin_setting_configselect('searchenginequeryonly',
|
||||
new lang_string('searchenginequeryonly', 'admin'),
|
||||
new lang_string('searchenginequeryonly_desc', 'admin'), '', function() use($engines) {
|
||||
$options = ['' => new lang_string('searchenginequeryonly_none', 'admin')];
|
||||
foreach ($engines as $name => $display) {
|
||||
$options[$name] = $display;
|
||||
|
||||
$classname = '\search_' . $name . '\engine';
|
||||
$engine = new $classname;
|
||||
if ($engine->has_alternate_configuration()) {
|
||||
$options[$name . '-alternate'] =
|
||||
new lang_string('searchenginealternatesettings', 'admin', $display);
|
||||
}
|
||||
}
|
||||
return $options;
|
||||
});
|
||||
$searchenginequeryonlyselect->set_validate_function(function(string $value): string {
|
||||
global $CFG;
|
||||
|
||||
// Check nobody's setting the indexing and query-only server to the same one.
|
||||
if (isset($CFG->searchengine) && $CFG->searchengine === $value) {
|
||||
return get_string('searchenginequeryonlysame', 'admin');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
});
|
||||
$temp->add($searchenginequeryonlyselect);
|
||||
$temp->add(new admin_setting_configcheckbox('searchbannerenable',
|
||||
new lang_string('searchbannerenable', 'admin'), new lang_string('searchbannerenable_desc', 'admin'),
|
||||
0));
|
||||
$temp->add(new admin_setting_confightmleditor('searchbanner',
|
||||
new lang_string('searchbanner', 'admin'), '', ''));
|
||||
|
||||
$ADMIN->add('searchplugins', $temp);
|
||||
$ADMIN->add('searchplugins', new admin_externalpage('searchareas', new lang_string('searchareas', 'admin'),
|
||||
new moodle_url('/admin/searchareas.php')));
|
||||
|
||||
@@ -160,23 +160,6 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$temp->add(new admin_setting_configportlist('curlsecurityallowedport',
|
||||
new lang_string('curlsecurityallowedport', 'admin'),
|
||||
new lang_string('curlsecurityallowedportsyntax', 'admin'), ""));
|
||||
|
||||
// HTTP Header referrer policy settings.
|
||||
$referreroptions = [
|
||||
'default' => get_string('referrernone', 'admin'),
|
||||
'no-referrer' => 'no-referrer',
|
||||
'no-referrer-when-downgrade' => 'no-referrer-when-downgrade',
|
||||
'origin' => 'origin',
|
||||
'origin-when-cross-origin' => 'origin-when-cross-origin',
|
||||
'same-origin' => 'same-origin',
|
||||
'strict-origin' => 'strict-origin',
|
||||
'strict-origin-when-cross-origin' => 'strict-origin-when-cross-origin',
|
||||
'unsafe-url' => 'unsafe-url',
|
||||
];
|
||||
$temp->add(new admin_setting_configselect('referrerpolicy',
|
||||
new lang_string('referrerpolicy', 'admin'),
|
||||
new lang_string('referrerpolicydesc', 'admin'), 'default', $referreroptions));
|
||||
|
||||
$ADMIN->add('security', $temp);
|
||||
|
||||
// "notifications" settingpage
|
||||
|
||||
+316
-458
@@ -1,225 +1,162 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Defines settingpages and externalpages under the "server" category.
|
||||
*
|
||||
* @package core
|
||||
* @category admin
|
||||
* @copyright 2006 Martin Dougiamas
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
// This file defines settingpages and externalpages under the "server" category
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
if ($hassiteconfig) {
|
||||
// System paths.
|
||||
$temp = new admin_settingpage('systempaths', new lang_string('systempaths', 'admin'));
|
||||
$temp->add(new admin_setting_configexecutable('pathtophp', new lang_string('pathtophp', 'admin'),
|
||||
new lang_string('configpathtophp', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configexecutable('pathtodu', new lang_string('pathtodu', 'admin'),
|
||||
new lang_string('configpathtodu', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configexecutable('aspellpath', new lang_string('aspellpath', 'admin'),
|
||||
new lang_string('edhelpaspellpath'), ''));
|
||||
$temp->add(new admin_setting_configexecutable('pathtodot', new lang_string('pathtodot', 'admin'),
|
||||
new lang_string('pathtodot_help', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configexecutable('pathtogs', new lang_string('pathtogs', 'admin'),
|
||||
new lang_string('pathtogs_help', 'admin'), '/usr/bin/gs'));
|
||||
$temp->add(new admin_setting_configexecutable('pathtopython', new lang_string('pathtopython', 'admin'),
|
||||
new lang_string('pathtopythondesc', 'admin'), ''));
|
||||
$ADMIN->add('server', $temp);
|
||||
// "systempaths" settingpage
|
||||
$temp = new admin_settingpage('systempaths', new lang_string('systempaths','admin'));
|
||||
$temp->add(new admin_setting_configexecutable('pathtophp', new lang_string('pathtophp', 'admin'),
|
||||
new lang_string('configpathtophp', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configexecutable('pathtodu', new lang_string('pathtodu', 'admin'), new lang_string('configpathtodu', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configexecutable('aspellpath', new lang_string('aspellpath', 'admin'), new lang_string('edhelpaspellpath'), ''));
|
||||
$temp->add(new admin_setting_configexecutable('pathtodot', new lang_string('pathtodot', 'admin'), new lang_string('pathtodot_help', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configexecutable('pathtogs', new lang_string('pathtogs', 'admin'), new lang_string('pathtogs_help', 'admin'), '/usr/bin/gs'));
|
||||
$temp->add(new admin_setting_configexecutable('pathtopython', new lang_string('pathtopython', 'admin'),
|
||||
new lang_string('pathtopythondesc', 'admin'), ''));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
// Support contact.
|
||||
$temp = new admin_settingpage('supportcontact', new lang_string('supportcontact', 'admin'));
|
||||
$primaryadmin = get_admin();
|
||||
if ($primaryadmin) {
|
||||
$primaryadminemail = $primaryadmin->email;
|
||||
$primaryadminname = fullname($primaryadmin, true);
|
||||
} else {
|
||||
// No defaults during installation - admin user must be created first.
|
||||
$primaryadminemail = null;
|
||||
$primaryadminname = null;
|
||||
}
|
||||
$temp->add(new admin_setting_configtext('supportname', new lang_string('supportname', 'admin'),
|
||||
new lang_string('configsupportname', 'admin'), $primaryadminname, PARAM_NOTAGS));
|
||||
$setting = new admin_setting_configtext('supportemail', new lang_string('supportemail', 'admin'),
|
||||
new lang_string('configsupportemail', 'admin'), $primaryadminemail, PARAM_EMAIL);
|
||||
$setting->set_force_ltr(true);
|
||||
$temp->add($setting);
|
||||
$temp->add(new admin_setting_configtext('supportpage', new lang_string('supportpage', 'admin'),
|
||||
new lang_string('configsupportpage', 'admin'), '', PARAM_URL));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
// Session handling.
|
||||
$temp = new admin_settingpage('sessionhandling', new lang_string('sessionhandling', 'admin'));
|
||||
if (empty($CFG->session_handler_class) and $DB->session_lock_supported()) {
|
||||
$temp->add(new admin_setting_configcheckbox('dbsessions', new lang_string('dbsessions', 'admin'),
|
||||
new lang_string('configdbsessions', 'admin'), 0));
|
||||
}
|
||||
|
||||
$temp->add(new admin_setting_configduration('sessiontimeout', new lang_string('sessiontimeout', 'admin'),
|
||||
new lang_string('configsessiontimeout', 'admin'), 8 * 60 * 60));
|
||||
// "supportcontact" settingpage
|
||||
$temp = new admin_settingpage('supportcontact', new lang_string('supportcontact','admin'));
|
||||
$primaryadmin = get_admin();
|
||||
if ($primaryadmin) {
|
||||
$primaryadminemail = $primaryadmin->email;
|
||||
$primaryadminname = fullname($primaryadmin, true);
|
||||
} else {
|
||||
// no defaults during installation - admin user must be created first
|
||||
$primaryadminemail = NULL;
|
||||
$primaryadminname = NULL;
|
||||
}
|
||||
$temp->add(new admin_setting_configtext('supportname', new lang_string('supportname', 'admin'),
|
||||
new lang_string('configsupportname', 'admin'), $primaryadminname, PARAM_NOTAGS));
|
||||
$setting = new admin_setting_configtext('supportemail', new lang_string('supportemail', 'admin'),
|
||||
new lang_string('configsupportemail', 'admin'), $primaryadminemail, PARAM_EMAIL);
|
||||
$setting->set_force_ltr(true);
|
||||
$temp->add($setting);
|
||||
$temp->add(new admin_setting_configtext('supportpage', new lang_string('supportpage', 'admin'), new lang_string('configsupportpage', 'admin'), '', PARAM_URL));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
$temp->add(new admin_setting_configtext('sessioncookie', new lang_string('sessioncookie', 'admin'),
|
||||
new lang_string('configsessioncookie', 'admin'), '', PARAM_ALPHANUM));
|
||||
$temp->add(new admin_setting_configtext('sessioncookiepath', new lang_string('sessioncookiepath', 'admin'),
|
||||
new lang_string('configsessioncookiepath', 'admin'), '', PARAM_RAW));
|
||||
$temp->add(new admin_setting_configtext('sessioncookiedomain', new lang_string('sessioncookiedomain', 'admin'),
|
||||
new lang_string('configsessioncookiedomain', 'admin'), '', PARAM_RAW, 50));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
// Statistics.
|
||||
$temp = new admin_settingpage('stats', new lang_string('stats'), 'moodle/site:config', empty($CFG->enablestats));
|
||||
$temp->add(new admin_setting_configselect('statsfirstrun', new lang_string('statsfirstrun', 'admin'),
|
||||
new lang_string('configstatsfirstrun', 'admin'), 'none',
|
||||
[
|
||||
'none' => new lang_string('none'),
|
||||
60 * 60 * 24 * 7 => new lang_string('numweeks', 'moodle', 1),
|
||||
60 * 60 * 24 * 14 => new lang_string('numweeks', 'moodle', 2),
|
||||
60 * 60 * 24 * 21 => new lang_string('numweeks', 'moodle', 3),
|
||||
60 * 60 * 24 * 28 => new lang_string('nummonths', 'moodle', 1),
|
||||
60 * 60 * 24 * 56 => new lang_string('nummonths', 'moodle', 2),
|
||||
60 * 60 * 24 * 84 => new lang_string('nummonths', 'moodle', 3),
|
||||
60 * 60 * 24 * 112 => new lang_string('nummonths', 'moodle', 4),
|
||||
60 * 60 * 24 * 140 => new lang_string('nummonths', 'moodle', 5),
|
||||
60 * 60 * 24 * 168 => new lang_string('nummonths', 'moodle', 6),
|
||||
'all' => new lang_string('all')
|
||||
]
|
||||
));
|
||||
$temp->add(new admin_setting_configselect('statsmaxruntime', new lang_string('statsmaxruntime', 'admin'),
|
||||
new lang_string('configstatsmaxruntime3', 'admin'), 0,
|
||||
[
|
||||
0 => new lang_string('untilcomplete'),
|
||||
60 * 30 => '10 ' . new lang_string('minutes'),
|
||||
60 * 30 => '30 ' . new lang_string('minutes'),
|
||||
60 * 60 => '1 ' . new lang_string('hour'),
|
||||
60 * 60 * 2 => '2 ' . new lang_string('hours'),
|
||||
60 * 60 * 3 => '3 ' . new lang_string('hours'),
|
||||
60 * 60 * 4 => '4 ' . new lang_string('hours'),
|
||||
60 * 60 * 5 => '5 ' . new lang_string('hours'),
|
||||
60 * 60 * 6 => '6 ' . new lang_string('hours'),
|
||||
60 * 60 * 7 => '7 ' . new lang_string('hours'),
|
||||
60 * 60 * 8 => '8 ' . new lang_string('hours'),
|
||||
]
|
||||
));
|
||||
$temp->add(new admin_setting_configtext('statsruntimedays', new lang_string('statsruntimedays', 'admin'),
|
||||
new lang_string('configstatsruntimedays', 'admin'), 31, PARAM_INT));
|
||||
$temp->add(new admin_setting_configtext('statsuserthreshold', new lang_string('statsuserthreshold', 'admin'),
|
||||
new lang_string('configstatsuserthreshold', 'admin'), 0, PARAM_INT));
|
||||
$ADMIN->add('server', $temp);
|
||||
// "sessionhandling" settingpage
|
||||
$temp = new admin_settingpage('sessionhandling', new lang_string('sessionhandling', 'admin'));
|
||||
if (empty($CFG->session_handler_class) and $DB->session_lock_supported()) {
|
||||
$temp->add(new admin_setting_configcheckbox('dbsessions', new lang_string('dbsessions', 'admin'), new lang_string('configdbsessions', 'admin'), 0));
|
||||
}
|
||||
|
||||
// HTTP.
|
||||
$temp = new admin_settingpage('http', new lang_string('http', 'admin'));
|
||||
$temp->add(new admin_setting_configcheckbox('slasharguments', new lang_string('slasharguments', 'admin'),
|
||||
new lang_string('configslasharguments', 'admin'), 1));
|
||||
$temp->add(new admin_setting_heading('reverseproxy', new lang_string('reverseproxy', 'admin'), '', ''));
|
||||
$options = [
|
||||
0 => 'HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, REMOTE_ADDR',
|
||||
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_HTTP_X_FORWARDED_FOR | GETREMOTEADDR_SKIP_HTTP_CLIENT_IP, $options));
|
||||
$temp->add(new admin_setting_configtext('reverseproxyignore', new lang_string('reverseproxyignore', 'admin'),
|
||||
new lang_string('configreverseproxyignore', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configduration('sessiontimeout', new lang_string('sessiontimeout', 'admin'),
|
||||
new lang_string('configsessiontimeout', 'admin'), 8 * 60 * 60));
|
||||
|
||||
$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));
|
||||
$temp->add(new admin_setting_configtext('proxyport', new lang_string('proxyport', 'admin'),
|
||||
new lang_string('configproxyport', 'admin'), 0, PARAM_INT));
|
||||
$options = ['HTTP' => 'HTTP'];
|
||||
if (defined('CURLPROXY_SOCKS5')) {
|
||||
$options['SOCKS5'] = 'SOCKS5';
|
||||
}
|
||||
$temp->add(new admin_setting_configselect('proxytype', new lang_string('proxytype', 'admin'),
|
||||
new lang_string('configproxytype', 'admin'), 'HTTP', $options));
|
||||
$temp->add(new admin_setting_configtext('proxyuser', new lang_string('proxyuser', 'admin'),
|
||||
new lang_string('configproxyuser', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configpasswordunmask('proxypassword', new lang_string('proxypassword', 'admin'),
|
||||
new lang_string('configproxypassword', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configtext('proxybypass', new lang_string('proxybypass', 'admin'),
|
||||
new lang_string('configproxybypass', 'admin'), 'localhost, 127.0.0.1'));
|
||||
$ADMIN->add('server', $temp);
|
||||
$temp->add(new admin_setting_configtext('sessioncookie', new lang_string('sessioncookie', 'admin'), new lang_string('configsessioncookie', 'admin'), '', PARAM_ALPHANUM));
|
||||
$temp->add(new admin_setting_configtext('sessioncookiepath', new lang_string('sessioncookiepath', 'admin'), new lang_string('configsessioncookiepath', 'admin'), '', PARAM_RAW));
|
||||
$temp->add(new admin_setting_configtext('sessioncookiedomain', new lang_string('sessioncookiedomain', 'admin'), new lang_string('configsessioncookiedomain', 'admin'), '', PARAM_RAW, 50));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
$temp = new admin_settingpage('maintenancemode', new lang_string('sitemaintenancemode', 'admin'));
|
||||
$options = [0 => new lang_string('disable'), 1 => new lang_string('enable')];
|
||||
$temp->add(new admin_setting_configselect('maintenance_enabled', new lang_string('sitemaintenancemode', 'admin'),
|
||||
new lang_string('helpsitemaintenance', 'admin'), 0, $options));
|
||||
$temp->add(new admin_setting_confightmleditor('maintenance_message', new lang_string('optionalmaintenancemessage', 'admin'),
|
||||
'', ''));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
// Cleanup.
|
||||
$temp = new admin_settingpage('cleanup', new lang_string('cleanup', 'admin'));
|
||||
$temp->add(new admin_setting_configselect('deleteunconfirmed', new lang_string('deleteunconfirmed', 'admin'),
|
||||
new lang_string('configdeleteunconfirmed', 'admin'), 168,
|
||||
[
|
||||
0 => new lang_string('never'),
|
||||
168 => new lang_string('numdays', '', 7),
|
||||
144 => new lang_string('numdays', '', 6),
|
||||
120 => new lang_string('numdays', '', 5),
|
||||
96 => new lang_string('numdays', '', 4),
|
||||
72 => new lang_string('numdays', '', 3),
|
||||
48 => new lang_string('numdays', '', 2),
|
||||
24 => new lang_string('numdays', '', 1),
|
||||
12 => new lang_string('numhours', '', 12),
|
||||
6 => new lang_string('numhours', '', 6),
|
||||
1 => new lang_string('numhours', '', 1),
|
||||
]
|
||||
));
|
||||
// "stats" settingpage
|
||||
$temp = new admin_settingpage('stats', new lang_string('stats'), 'moodle/site:config', empty($CFG->enablestats));
|
||||
$temp->add(new admin_setting_configselect('statsfirstrun', new lang_string('statsfirstrun', 'admin'), new lang_string('configstatsfirstrun', 'admin'), 'none', array('none' => new lang_string('none'),
|
||||
60*60*24*7 => new lang_string('numweeks','moodle',1),
|
||||
60*60*24*14 => new lang_string('numweeks','moodle',2),
|
||||
60*60*24*21 => new lang_string('numweeks','moodle',3),
|
||||
60*60*24*28 => new lang_string('nummonths','moodle',1),
|
||||
60*60*24*56 => new lang_string('nummonths','moodle',2),
|
||||
60*60*24*84 => new lang_string('nummonths','moodle',3),
|
||||
60*60*24*112 => new lang_string('nummonths','moodle',4),
|
||||
60*60*24*140 => new lang_string('nummonths','moodle',5),
|
||||
60*60*24*168 => new lang_string('nummonths','moodle',6),
|
||||
'all' => new lang_string('all') )));
|
||||
$temp->add(new admin_setting_configselect('statsmaxruntime', new lang_string('statsmaxruntime', 'admin'), new lang_string('configstatsmaxruntime3', 'admin'), 0, array(0 => new lang_string('untilcomplete'),
|
||||
60*30 => '10 '.new lang_string('minutes'),
|
||||
60*30 => '30 '.new lang_string('minutes'),
|
||||
60*60 => '1 '.new lang_string('hour'),
|
||||
60*60*2 => '2 '.new lang_string('hours'),
|
||||
60*60*3 => '3 '.new lang_string('hours'),
|
||||
60*60*4 => '4 '.new lang_string('hours'),
|
||||
60*60*5 => '5 '.new lang_string('hours'),
|
||||
60*60*6 => '6 '.new lang_string('hours'),
|
||||
60*60*7 => '7 '.new lang_string('hours'),
|
||||
60*60*8 => '8 '.new lang_string('hours') )));
|
||||
$temp->add(new admin_setting_configtext('statsruntimedays', new lang_string('statsruntimedays', 'admin'), new lang_string('configstatsruntimedays', 'admin'), 31, PARAM_INT));
|
||||
$temp->add(new admin_setting_configtext('statsuserthreshold', new lang_string('statsuserthreshold', 'admin'), new lang_string('configstatsuserthreshold', 'admin'), 0, PARAM_INT));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
$temp->add(new admin_setting_configselect('deleteincompleteusers', new lang_string('deleteincompleteusers', 'admin'),
|
||||
new lang_string('configdeleteincompleteusers', 'admin'), 0,
|
||||
[
|
||||
0 => new lang_string('never'),
|
||||
168 => new lang_string('numdays', '', 7),
|
||||
144 => new lang_string('numdays', '', 6),
|
||||
120 => new lang_string('numdays', '', 5),
|
||||
96 => new lang_string('numdays', '', 4),
|
||||
72 => new lang_string('numdays', '', 3),
|
||||
48 => new lang_string('numdays', '', 2),
|
||||
24 => new lang_string('numdays', '', 1),
|
||||
]
|
||||
));
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('disablegradehistory', new lang_string('disablegradehistory', 'grades'),
|
||||
new lang_string('disablegradehistory_help', 'grades'), 0));
|
||||
// "http" settingpage
|
||||
$temp = new admin_settingpage('http', new lang_string('http', 'admin'));
|
||||
$temp->add(new admin_setting_configcheckbox('slasharguments', new lang_string('slasharguments', 'admin'), new lang_string('configslasharguments', 'admin'), 1));
|
||||
$temp->add(new admin_setting_heading('reverseproxy', new lang_string('reverseproxy', 'admin'), '', ''));
|
||||
$options = array(
|
||||
0 => 'HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, REMOTE_ADDR',
|
||||
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('gradehistorylifetime', new lang_string('gradehistorylifetime', 'grades'),
|
||||
new lang_string('gradehistorylifetime_help', 'grades'), 0,
|
||||
[
|
||||
0 => new lang_string('neverdeletehistory', 'grades'),
|
||||
1000 => new lang_string('numdays', '', 1000),
|
||||
365 => new lang_string('numdays', '', 365),
|
||||
180 => new lang_string('numdays', '', 180),
|
||||
150 => new lang_string('numdays', '', 150),
|
||||
120 => new lang_string('numdays', '', 120),
|
||||
90 => new lang_string('numdays', '', 90),
|
||||
60 => new lang_string('numdays', '', 60),
|
||||
30 => new lang_string('numdays', '', 30),
|
||||
]
|
||||
));
|
||||
$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));
|
||||
$temp->add(new admin_setting_configtext('proxyport', new lang_string('proxyport', 'admin'), new lang_string('configproxyport', 'admin'), 0, PARAM_INT));
|
||||
$options = array('HTTP'=>'HTTP');
|
||||
if (defined('CURLPROXY_SOCKS5')) {
|
||||
$options['SOCKS5'] = 'SOCKS5';
|
||||
}
|
||||
$temp->add(new admin_setting_configselect('proxytype', new lang_string('proxytype', 'admin'), new lang_string('configproxytype','admin'), 'HTTP', $options));
|
||||
$temp->add(new admin_setting_configtext('proxyuser', new lang_string('proxyuser', 'admin'), new lang_string('configproxyuser', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configpasswordunmask('proxypassword', new lang_string('proxypassword', 'admin'), new lang_string('configproxypassword', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configtext('proxybypass', new lang_string('proxybypass', 'admin'), new lang_string('configproxybypass', 'admin'), 'localhost, 127.0.0.1'));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
$temp->add(new admin_setting_configselect('tempdatafoldercleanup', new lang_string('tempdatafoldercleanup', 'admin'),
|
||||
new lang_string('configtempdatafoldercleanup', 'admin'), 168,
|
||||
[
|
||||
$temp = new admin_settingpage('maintenancemode', new lang_string('sitemaintenancemode', 'admin'));
|
||||
$options = array(0=>new lang_string('disable'), 1=>new lang_string('enable'));
|
||||
$temp->add(new admin_setting_configselect('maintenance_enabled', new lang_string('sitemaintenancemode', 'admin'),
|
||||
new lang_string('helpsitemaintenance', 'admin'), 0, $options));
|
||||
$temp->add(new admin_setting_confightmleditor('maintenance_message', new lang_string('optionalmaintenancemessage', 'admin'),
|
||||
'', ''));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
$temp = new admin_settingpage('cleanup', new lang_string('cleanup', 'admin'));
|
||||
$temp->add(new admin_setting_configselect('deleteunconfirmed', new lang_string('deleteunconfirmed', 'admin'), new lang_string('configdeleteunconfirmed', 'admin'), 168, array(0 => new lang_string('never'),
|
||||
168 => new lang_string('numdays', '', 7),
|
||||
144 => new lang_string('numdays', '', 6),
|
||||
120 => new lang_string('numdays', '', 5),
|
||||
96 => new lang_string('numdays', '', 4),
|
||||
72 => new lang_string('numdays', '', 3),
|
||||
48 => new lang_string('numdays', '', 2),
|
||||
24 => new lang_string('numdays', '', 1),
|
||||
12 => new lang_string('numhours', '', 12),
|
||||
6 => new lang_string('numhours', '', 6),
|
||||
1 => new lang_string('numhours', '', 1))));
|
||||
|
||||
$temp->add(new admin_setting_configselect('deleteincompleteusers', new lang_string('deleteincompleteusers', 'admin'), new lang_string('configdeleteincompleteusers', 'admin'), 0, array(0 => new lang_string('never'),
|
||||
168 => new lang_string('numdays', '', 7),
|
||||
144 => new lang_string('numdays', '', 6),
|
||||
120 => new lang_string('numdays', '', 5),
|
||||
96 => new lang_string('numdays', '', 4),
|
||||
72 => new lang_string('numdays', '', 3),
|
||||
48 => new lang_string('numdays', '', 2),
|
||||
24 => new lang_string('numdays', '', 1))));
|
||||
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('disablegradehistory', new lang_string('disablegradehistory', 'grades'),
|
||||
new lang_string('disablegradehistory_help', 'grades'), 0));
|
||||
|
||||
$temp->add(new admin_setting_configselect('gradehistorylifetime', new lang_string('gradehistorylifetime', 'grades'),
|
||||
new lang_string('gradehistorylifetime_help', 'grades'), 0, array(0 => new lang_string('neverdeletehistory', 'grades'),
|
||||
1000 => new lang_string('numdays', '', 1000),
|
||||
365 => new lang_string('numdays', '', 365),
|
||||
180 => new lang_string('numdays', '', 180),
|
||||
150 => new lang_string('numdays', '', 150),
|
||||
120 => new lang_string('numdays', '', 120),
|
||||
90 => new lang_string('numdays', '', 90),
|
||||
60 => new lang_string('numdays', '', 60),
|
||||
30 => new lang_string('numdays', '', 30))));
|
||||
|
||||
$temp->add(new admin_setting_configselect('tempdatafoldercleanup', new lang_string('tempdatafoldercleanup', 'admin'),
|
||||
new lang_string('configtempdatafoldercleanup', 'admin'), 168, array(
|
||||
1 => new lang_string('numhours', '', 1),
|
||||
3 => new lang_string('numhours', '', 3),
|
||||
6 => new lang_string('numhours', '', 6),
|
||||
@@ -229,303 +166,224 @@ if ($hassiteconfig) {
|
||||
24 => new lang_string('numhours', '', 24),
|
||||
48 => new lang_string('numdays', '', 2),
|
||||
168 => new lang_string('numdays', '', 7),
|
||||
]
|
||||
));
|
||||
)));
|
||||
|
||||
$ADMIN->add('server', $temp);
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
$temp->add(new admin_setting_configduration('filescleanupperiod',
|
||||
new lang_string('filescleanupperiod', 'admin'),
|
||||
new lang_string('filescleanupperiod_help', 'admin'),
|
||||
86400));
|
||||
|
||||
// Environment.
|
||||
$ADMIN->add('server', new admin_externalpage('environment', new lang_string('environment', 'admin'),
|
||||
"{$CFG->wwwroot}/{$CFG->admin}/environment.php"));
|
||||
$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"));
|
||||
$ADMIN->add('server', new admin_externalpage('testoutgoingmailconf', new lang_string('testoutgoingmailconf', 'admin'),
|
||||
new moodle_url("$CFG->wwwroot/$CFG->admin/testoutgoingmailconf.php"), 'moodle/site:config', true));
|
||||
|
||||
// PHP info.
|
||||
$ADMIN->add('server', new admin_externalpage('phpinfo', new lang_string('phpinfo'),
|
||||
"{$CFG->wwwroot}/{$CFG->admin}/phpinfo.php"));
|
||||
|
||||
// Test outgoing mail configuration (hidden, accessed via direct link from the settings page).
|
||||
$ADMIN->add('server', new admin_externalpage('testoutgoingmailconf', new lang_string('testoutgoingmailconf', 'admin'),
|
||||
new moodle_url('/admin/testoutgoingmailconf.php'), 'moodle/site:config', true));
|
||||
// "performance" settingpage
|
||||
$temp = new admin_settingpage('performance', new lang_string('performance', 'admin'));
|
||||
|
||||
// Performance.
|
||||
$temp = new admin_settingpage('performance', new lang_string('performance', 'admin'));
|
||||
// Memory limit options for large administration tasks.
|
||||
$memoryoptions = array(
|
||||
'64M' => '64M',
|
||||
'128M' => '128M',
|
||||
'256M' => '256M',
|
||||
'512M' => '512M',
|
||||
'1024M' => '1024M',
|
||||
'2048M' => '2048M');
|
||||
|
||||
// Memory limit options for large administration tasks.
|
||||
$memoryoptions = [
|
||||
'64M' => '64M',
|
||||
'128M' => '128M',
|
||||
'256M' => '256M',
|
||||
'512M' => '512M',
|
||||
'1024M' => '1024M',
|
||||
'2048M' => '2048M',
|
||||
];
|
||||
// Allow larger memory usage for 64-bit sites only.
|
||||
if (PHP_INT_SIZE === 8) {
|
||||
$memoryoptions['3072M'] = '3072M';
|
||||
$memoryoptions['4096M'] = '4096M';
|
||||
}
|
||||
|
||||
// Allow larger memory usage for 64-bit sites only.
|
||||
if (PHP_INT_SIZE === 8) {
|
||||
$memoryoptions['3072M'] = '3072M';
|
||||
$memoryoptions['4096M'] = '4096M';
|
||||
}
|
||||
|
||||
$temp->add(new admin_setting_configselect('extramemorylimit', new lang_string('extramemorylimit', 'admin'),
|
||||
new lang_string('configextramemorylimit', 'admin'), '512M', $memoryoptions));
|
||||
|
||||
$temp->add(new admin_setting_configtext('maxtimelimit', new lang_string('maxtimelimit', 'admin'),
|
||||
$temp->add(new admin_setting_configselect('extramemorylimit', new lang_string('extramemorylimit', 'admin'),
|
||||
new lang_string('configextramemorylimit', 'admin'), '512M',
|
||||
$memoryoptions));
|
||||
$temp->add(new admin_setting_configtext('maxtimelimit', new lang_string('maxtimelimit', 'admin'),
|
||||
new lang_string('maxtimelimit_desc', 'admin'), 0, PARAM_INT));
|
||||
|
||||
$temp->add(new admin_setting_configtext('curlcache', new lang_string('curlcache', 'admin'),
|
||||
new lang_string('configcurlcache', 'admin'), 120, PARAM_INT));
|
||||
$temp->add(new admin_setting_configtext('curlcache', new lang_string('curlcache', 'admin'),
|
||||
new lang_string('configcurlcache', 'admin'), 120, PARAM_INT));
|
||||
|
||||
$temp->add(new admin_setting_configtext('curltimeoutkbitrate', new lang_string('curltimeoutkbitrate', 'admin'),
|
||||
new lang_string('curltimeoutkbitrate_help', 'admin'), 56, PARAM_INT));
|
||||
$temp->add(new admin_setting_configtext('curltimeoutkbitrate', new lang_string('curltimeoutkbitrate', 'admin'),
|
||||
new lang_string('curltimeoutkbitrate_help', 'admin'), 56, PARAM_INT));
|
||||
|
||||
$ADMIN->add('server', $temp);
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
// Tasks.
|
||||
$ADMIN->add('server', new admin_category('taskconfig', new lang_string('taskadmintitle', 'admin')));
|
||||
|
||||
// Task processing.
|
||||
$temp = new admin_settingpage('taskprocessing', new lang_string('taskprocessing', 'admin'));
|
||||
$ADMIN->add('server', new admin_category('taskconfig', new lang_string('taskadmintitle', 'admin')));
|
||||
$temp = new admin_settingpage('taskprocessing', new lang_string('taskprocessing','admin'));
|
||||
$temp->add(
|
||||
new admin_setting_configtext(
|
||||
'task_scheduled_concurrency_limit',
|
||||
new lang_string('task_scheduled_concurrency_limit', 'admin'),
|
||||
new lang_string('task_scheduled_concurrency_limit_desc', 'admin'),
|
||||
3,
|
||||
PARAM_INT
|
||||
)
|
||||
);
|
||||
|
||||
$setting = new admin_setting_configcheckbox(
|
||||
'cron_enabled',
|
||||
new lang_string('cron_enabled', 'admin'),
|
||||
new lang_string('cron_enabled_desc', 'admin'),
|
||||
$temp->add(
|
||||
new admin_setting_configduration(
|
||||
'task_scheduled_max_runtime',
|
||||
new lang_string('task_scheduled_max_runtime', 'admin'),
|
||||
new lang_string('task_scheduled_max_runtime_desc', 'admin'),
|
||||
30 * MINSECS
|
||||
)
|
||||
);
|
||||
|
||||
$temp->add(
|
||||
new admin_setting_configtext(
|
||||
'task_adhoc_concurrency_limit',
|
||||
new lang_string('task_adhoc_concurrency_limit', 'admin'),
|
||||
new lang_string('task_adhoc_concurrency_limit_desc', 'admin'),
|
||||
3,
|
||||
PARAM_INT
|
||||
)
|
||||
);
|
||||
|
||||
$temp->add(
|
||||
new admin_setting_configduration(
|
||||
'task_adhoc_max_runtime',
|
||||
new lang_string('task_adhoc_max_runtime', 'admin'),
|
||||
new lang_string('task_adhoc_max_runtime_desc', 'admin'),
|
||||
30 * MINSECS
|
||||
)
|
||||
);
|
||||
$ADMIN->add('taskconfig', $temp);
|
||||
|
||||
$temp = new admin_settingpage('tasklogging', new lang_string('tasklogging','admin'));
|
||||
$temp->add(
|
||||
new admin_setting_configselect(
|
||||
'task_logmode',
|
||||
new lang_string('task_logmode', 'admin'),
|
||||
new lang_string('task_logmode_desc', 'admin'),
|
||||
\core\task\logmanager::MODE_ALL,
|
||||
[
|
||||
\core\task\logmanager::MODE_ALL => new lang_string('task_logmode_all', 'admin'),
|
||||
\core\task\logmanager::MODE_FAILONLY => new lang_string('task_logmode_failonly', 'admin'),
|
||||
\core\task\logmanager::MODE_NONE => new lang_string('task_logmode_none', 'admin'),
|
||||
]
|
||||
)
|
||||
);
|
||||
$temp->add(
|
||||
new admin_setting_configcheckbox(
|
||||
'task_logtostdout',
|
||||
new lang_string('task_logtostdout', 'admin'),
|
||||
new lang_string('task_logtostdout_desc', 'admin'),
|
||||
1
|
||||
);
|
||||
$setting->set_updatedcallback('theme_reset_static_caches');
|
||||
$temp->add($setting);
|
||||
|
||||
$temp->add(
|
||||
new admin_setting_configtext(
|
||||
'task_scheduled_concurrency_limit',
|
||||
new lang_string('task_scheduled_concurrency_limit', 'admin'),
|
||||
new lang_string('task_scheduled_concurrency_limit_desc', 'admin'),
|
||||
3,
|
||||
PARAM_INT
|
||||
)
|
||||
);
|
||||
)
|
||||
);
|
||||
|
||||
if (\core\task\logmanager::uses_standard_settings()) {
|
||||
$temp->add(
|
||||
new admin_setting_configduration(
|
||||
'task_scheduled_max_runtime',
|
||||
new lang_string('task_scheduled_max_runtime', 'admin'),
|
||||
new lang_string('task_scheduled_max_runtime_desc', 'admin'),
|
||||
30 * MINSECS
|
||||
'task_logretention',
|
||||
new \lang_string('task_logretention', 'admin'),
|
||||
new \lang_string('task_logretention_desc', 'admin'),
|
||||
28 * DAYSECS
|
||||
)
|
||||
);
|
||||
|
||||
$temp->add(
|
||||
new admin_setting_configtext(
|
||||
'task_adhoc_concurrency_limit',
|
||||
new lang_string('task_adhoc_concurrency_limit', 'admin'),
|
||||
new lang_string('task_adhoc_concurrency_limit_desc', 'admin'),
|
||||
3,
|
||||
'task_logretainruns',
|
||||
new \lang_string('task_logretainruns', 'admin'),
|
||||
new \lang_string('task_logretainruns_desc', 'admin'),
|
||||
20,
|
||||
PARAM_INT
|
||||
)
|
||||
);
|
||||
}
|
||||
$ADMIN->add('taskconfig', $temp);
|
||||
|
||||
$temp->add(
|
||||
new admin_setting_configduration(
|
||||
'task_adhoc_max_runtime',
|
||||
new lang_string('task_adhoc_max_runtime', 'admin'),
|
||||
new lang_string('task_adhoc_max_runtime_desc', 'admin'),
|
||||
30 * MINSECS
|
||||
)
|
||||
);
|
||||
$ADMIN->add('taskconfig', $temp);
|
||||
if (\core\task\logmanager::uses_standard_settings()) {
|
||||
$ADMIN->add('taskconfig', new admin_externalpage(
|
||||
'tasklogs',
|
||||
new lang_string('tasklogs','admin'),
|
||||
"{$CFG->wwwroot}/{$CFG->admin}/tasklogs.php"
|
||||
));
|
||||
}
|
||||
|
||||
// Task log configuration.
|
||||
$temp = new admin_settingpage('tasklogging', new lang_string('tasklogging', 'admin'));
|
||||
$temp->add(
|
||||
new admin_setting_configselect(
|
||||
'task_logmode',
|
||||
new lang_string('task_logmode', 'admin'),
|
||||
new lang_string('task_logmode_desc', 'admin'),
|
||||
\core\task\logmanager::MODE_ALL,
|
||||
[
|
||||
\core\task\logmanager::MODE_ALL => new lang_string('task_logmode_all', 'admin'),
|
||||
\core\task\logmanager::MODE_FAILONLY => new lang_string('task_logmode_failonly', 'admin'),
|
||||
\core\task\logmanager::MODE_NONE => new lang_string('task_logmode_none', 'admin'),
|
||||
]
|
||||
)
|
||||
);
|
||||
$temp->add(
|
||||
new admin_setting_configcheckbox(
|
||||
'task_logtostdout',
|
||||
new lang_string('task_logtostdout', 'admin'),
|
||||
new lang_string('task_logtostdout_desc', 'admin'),
|
||||
1
|
||||
)
|
||||
);
|
||||
// E-mail settings.
|
||||
$ADMIN->add('server', new admin_category('email', new lang_string('categoryemail', 'admin')));
|
||||
|
||||
if (\core\task\logmanager::uses_standard_settings()) {
|
||||
$temp->add(
|
||||
new admin_setting_configduration(
|
||||
'task_logretention',
|
||||
new \lang_string('task_logretention', 'admin'),
|
||||
new \lang_string('task_logretention_desc', 'admin'),
|
||||
28 * DAYSECS
|
||||
)
|
||||
);
|
||||
$temp = new admin_settingpage('outgoingmailconfig', new lang_string('outgoingmailconfig', 'admin'));
|
||||
|
||||
$temp->add(
|
||||
new admin_setting_configtext(
|
||||
'task_logretainruns',
|
||||
new \lang_string('task_logretainruns', 'admin'),
|
||||
new \lang_string('task_logretainruns_desc', 'admin'),
|
||||
20,
|
||||
PARAM_INT
|
||||
)
|
||||
);
|
||||
}
|
||||
$ADMIN->add('taskconfig', $temp);
|
||||
|
||||
// Task logs.
|
||||
if (\core\task\logmanager::uses_standard_settings()) {
|
||||
$ADMIN->add('taskconfig', new admin_externalpage(
|
||||
'tasklogs',
|
||||
new lang_string('tasklogs', 'admin'),
|
||||
"{$CFG->wwwroot}/{$CFG->admin}/tasklogs.php"
|
||||
));
|
||||
}
|
||||
|
||||
// Email.
|
||||
$ADMIN->add('server', new admin_category('email', new lang_string('categoryemail', 'admin')));
|
||||
|
||||
// Outgoing mail configuration.
|
||||
$temp = new admin_settingpage('outgoingmailconfig', new lang_string('outgoingmailconfig', 'admin'));
|
||||
|
||||
$temp->add(new admin_setting_heading('smtpheading', new lang_string('smtp', 'admin'),
|
||||
new lang_string('smtpdetail', 'admin')));
|
||||
|
||||
$temp->add(new admin_setting_configtext('smtphosts', new lang_string('smtphosts', 'admin'),
|
||||
new lang_string('configsmtphosts', 'admin'), '', PARAM_RAW));
|
||||
|
||||
$options = [
|
||||
'' => new lang_string('none', 'admin'),
|
||||
'ssl' => 'SSL',
|
||||
'tls' => 'TLS',
|
||||
];
|
||||
|
||||
$temp->add(new admin_setting_configselect('smtpsecure', new lang_string('smtpsecure', 'admin'),
|
||||
new lang_string('configsmtpsecure', 'admin'), '', $options));
|
||||
|
||||
$authtypeoptions = [
|
||||
'LOGIN' => 'LOGIN',
|
||||
'PLAIN' => 'PLAIN',
|
||||
'NTLM' => 'NTLM',
|
||||
'CRAM-MD5' => 'CRAM-MD5',
|
||||
];
|
||||
|
||||
$temp->add(new admin_setting_configselect('smtpauthtype', new lang_string('smtpauthtype', 'admin'),
|
||||
new lang_string('configsmtpauthtype', 'admin'), 'LOGIN', $authtypeoptions));
|
||||
|
||||
$temp->add(new admin_setting_configtext('smtpuser', new lang_string('smtpuser', 'admin'),
|
||||
new lang_string('configsmtpuser', 'admin'), '', PARAM_NOTAGS));
|
||||
|
||||
$temp->add(new admin_setting_configpasswordunmask('smtppass', new lang_string('smtppass', 'admin'),
|
||||
new lang_string('configsmtpuser', 'admin'), ''));
|
||||
|
||||
$temp->add(new admin_setting_configtext('smtpmaxbulk', new lang_string('smtpmaxbulk', 'admin'),
|
||||
new lang_string('configsmtpmaxbulk', 'admin'), 1, PARAM_INT));
|
||||
|
||||
$temp->add(new admin_setting_heading('noreplydomainheading', new lang_string('noreplydomain', 'admin'),
|
||||
$temp->add(new admin_setting_heading('smtpheading', new lang_string('smtp', 'admin'),
|
||||
new lang_string('smtpdetail', 'admin')));
|
||||
$temp->add(new admin_setting_configtext('smtphosts', new lang_string('smtphosts', 'admin'),
|
||||
new lang_string('configsmtphosts', 'admin'), '', PARAM_RAW));
|
||||
$options = array('' => new lang_string('none', 'admin'), 'ssl' => 'SSL', 'tls' => 'TLS');
|
||||
$temp->add(new admin_setting_configselect('smtpsecure', new lang_string('smtpsecure', 'admin'),
|
||||
new lang_string('configsmtpsecure', 'admin'), '', $options));
|
||||
$authtypeoptions = array('LOGIN' => 'LOGIN', 'PLAIN' => 'PLAIN', 'NTLM' => 'NTLM', 'CRAM-MD5' => 'CRAM-MD5');
|
||||
$temp->add(new admin_setting_configselect('smtpauthtype', new lang_string('smtpauthtype', 'admin'),
|
||||
new lang_string('configsmtpauthtype', 'admin'), 'LOGIN', $authtypeoptions));
|
||||
$temp->add(new admin_setting_configtext('smtpuser', new lang_string('smtpuser', 'admin'),
|
||||
new lang_string('configsmtpuser', 'admin'), '', PARAM_NOTAGS));
|
||||
$temp->add(new admin_setting_configpasswordunmask('smtppass', new lang_string('smtppass', 'admin'),
|
||||
new lang_string('configsmtpuser', 'admin'), ''));
|
||||
$temp->add(new admin_setting_configtext('smtpmaxbulk', new lang_string('smtpmaxbulk', 'admin'),
|
||||
new lang_string('configsmtpmaxbulk', 'admin'), 1, PARAM_INT));
|
||||
$temp->add(new admin_setting_heading('noreplydomainheading', new lang_string('noreplydomain', 'admin'),
|
||||
new lang_string('noreplydomaindetail', 'admin')));
|
||||
|
||||
$temp->add(new admin_setting_configtext('noreplyaddress', new lang_string('noreplyaddress', 'admin'),
|
||||
new lang_string('confignoreplyaddress', 'admin'), 'noreply@' . get_host_from_url($CFG->wwwroot), PARAM_EMAIL));
|
||||
|
||||
$temp->add(new admin_setting_configtextarea('allowedemaildomains',
|
||||
$temp->add(new admin_setting_configtext('noreplyaddress', new lang_string('noreplyaddress', 'admin'),
|
||||
new lang_string('confignoreplyaddress', 'admin'), 'noreply@' . get_host_from_url($CFG->wwwroot), PARAM_EMAIL));
|
||||
$temp->add(new admin_setting_configtextarea('allowedemaildomains',
|
||||
new lang_string('allowedemaildomains', 'admin'),
|
||||
new lang_string('configallowedemaildomains', 'admin'),
|
||||
''));
|
||||
|
||||
$temp->add(new admin_setting_heading('divertallemailsheading', new lang_string('divertallemails', 'admin'),
|
||||
new lang_string('divertallemailsdetail', 'admin')));
|
||||
$temp->add(new admin_setting_configtext('divertallemailsto',
|
||||
new lang_string('divertallemailsto', 'admin'),
|
||||
new lang_string('divertallemailsto_desc', 'admin'),
|
||||
''));
|
||||
$temp->add(new admin_setting_configtextarea('divertallemailsexcept',
|
||||
new lang_string('divertallemailsexcept', 'admin'),
|
||||
new lang_string('divertallemailsexcept_desc', 'admin'),
|
||||
'', PARAM_RAW, '50', '4'));
|
||||
|
||||
$noreplyaddress = isset($CFG->noreplyaddress) ? $CFG->noreplyaddress : 'noreply@example.com';
|
||||
$dkimdomain = substr(strrchr($noreplyaddress, "@"), 1);
|
||||
$dkimselector = empty($CFG->emaildkimselector) ? '[selector]' : $CFG->emaildkimselector;
|
||||
$pempath = "\$CFG->dataroot/dkim/{$dkimdomain}/{$dkimselector}.private";
|
||||
$temp->add(new admin_setting_heading('emaildkim', new lang_string('emaildkim', 'admin'),
|
||||
new lang_string('emaildkiminfo', 'admin', ['path' => $pempath, 'docs' => \get_docs_url('Mail_configuration#DKIM')])));
|
||||
$temp->add(new admin_setting_configtext('emaildkimselector', new lang_string('emaildkimselector', 'admin'),
|
||||
new lang_string('configemaildkimselector', 'admin'), '', PARAM_FILE));
|
||||
|
||||
$url = new moodle_url('/admin/testoutgoingmailconf.php');
|
||||
$link = html_writer::link($url, get_string('testoutgoingmailconf', 'admin'));
|
||||
$temp->add(new admin_setting_heading('testoutgoinmailc', new lang_string('testoutgoingmailconf', 'admin'),
|
||||
$url = new moodle_url('/admin/testoutgoingmailconf.php');
|
||||
$link = html_writer::link($url, get_string('testoutgoingmailconf', 'admin'));
|
||||
$temp->add(new admin_setting_heading('testoutgoinmailc', new lang_string('testoutgoingmailconf', 'admin'),
|
||||
new lang_string('testoutgoingmaildetail', 'admin', $link)));
|
||||
|
||||
$temp->add(new admin_setting_heading('emaildoesnotfit', new lang_string('doesnotfit', 'admin'),
|
||||
$temp->add(new admin_setting_heading('emaildoesnotfit', new lang_string('doesnotfit', 'admin'),
|
||||
new lang_string('doesnotfitdetail', 'admin')));
|
||||
$charsets = get_list_of_charsets();
|
||||
unset($charsets['UTF-8']); // Not needed here.
|
||||
$options = array();
|
||||
$options['0'] = 'UTF-8';
|
||||
$options = array_merge($options, $charsets);
|
||||
$temp->add(new admin_setting_configselect('sitemailcharset', new lang_string('sitemailcharset', 'admin'),
|
||||
new lang_string('configsitemailcharset','admin'), '0', $options));
|
||||
$temp->add(new admin_setting_configcheckbox('allowusermailcharset', new lang_string('allowusermailcharset', 'admin'),
|
||||
new lang_string('configallowusermailcharset', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('allowattachments', new lang_string('allowattachments', 'admin'),
|
||||
new lang_string('configallowattachments', 'admin'), 1));
|
||||
$options = array('LF' => 'LF', 'CRLF' => 'CRLF');
|
||||
$temp->add(new admin_setting_configselect('mailnewline', new lang_string('mailnewline', 'admin'),
|
||||
new lang_string('configmailnewline', 'admin'), 'LF', $options));
|
||||
|
||||
$charsets = get_list_of_charsets();
|
||||
unset($charsets['UTF-8']);
|
||||
$options = [
|
||||
'0' => 'UTF-8',
|
||||
];
|
||||
$options = array_merge($options, $charsets);
|
||||
$temp->add(new admin_setting_configselect('sitemailcharset', new lang_string('sitemailcharset', 'admin'),
|
||||
new lang_string('configsitemailcharset', 'admin'), '0', $options));
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('allowusermailcharset', new lang_string('allowusermailcharset', 'admin'),
|
||||
new lang_string('configallowusermailcharset', 'admin'), 0));
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('allowattachments', new lang_string('allowattachments', 'admin'),
|
||||
new lang_string('configallowattachments', 'admin'), 1));
|
||||
|
||||
$options = [
|
||||
'LF' => 'LF',
|
||||
'CRLF' => 'CRLF',
|
||||
];
|
||||
$temp->add(new admin_setting_configselect('mailnewline', new lang_string('mailnewline', 'admin'),
|
||||
new lang_string('configmailnewline', 'admin'), 'LF', $options));
|
||||
|
||||
$choices = [
|
||||
new lang_string('never', 'admin'),
|
||||
new lang_string('always', 'admin'),
|
||||
new lang_string('onlynoreply', 'admin'),
|
||||
];
|
||||
$temp->add(new admin_setting_configselect('emailfromvia', new lang_string('emailfromvia', 'admin'),
|
||||
new lang_string('configemailfromvia', 'admin'), 1, $choices));
|
||||
|
||||
$choices = array(new lang_string('never', 'admin'),
|
||||
new lang_string('always', 'admin'),
|
||||
new lang_string('onlynoreply', 'admin'));
|
||||
$temp->add(new admin_setting_configselect('emailfromvia', new lang_string('emailfromvia', 'admin'),
|
||||
new lang_string('configemailfromvia', 'admin'), 1, $choices));
|
||||
$temp->add(new admin_setting_configtext('emailsubjectprefix', new lang_string('emailsubjectprefix', 'admin'),
|
||||
new lang_string('configemailsubjectprefix', 'admin'), '', PARAM_RAW));
|
||||
|
||||
$temp->add(new admin_setting_configtextarea('emailheaders', new lang_string('emailheaders', 'admin'),
|
||||
new lang_string('configemailheaders', 'admin'), '', PARAM_RAW, '50', '3'));
|
||||
$ADMIN->add('email', $temp);
|
||||
|
||||
$ADMIN->add('email', $temp);
|
||||
|
||||
// Update notifications.
|
||||
if (empty($CFG->disableupdatenotifications)) {
|
||||
$temp = new admin_settingpage('updatenotifications', new lang_string('updatenotifications', 'core_admin'));
|
||||
$temp->add(new admin_setting_configcheckbox('updateautocheck', new lang_string('updateautocheck', 'core_admin'),
|
||||
new lang_string('updateautocheck_desc', 'core_admin'), 1));
|
||||
$temp->add(new admin_setting_configselect('updateminmaturity', new lang_string('updateminmaturity', 'core_admin'),
|
||||
new lang_string('updateminmaturity_desc', 'core_admin'), MATURITY_STABLE,
|
||||
[
|
||||
MATURITY_ALPHA => new lang_string('maturity'.MATURITY_ALPHA, 'core_admin'),
|
||||
MATURITY_BETA => new lang_string('maturity'.MATURITY_BETA, 'core_admin'),
|
||||
MATURITY_RC => new lang_string('maturity'.MATURITY_RC, 'core_admin'),
|
||||
MATURITY_STABLE => new lang_string('maturity'.MATURITY_STABLE, 'core_admin'),
|
||||
]
|
||||
));
|
||||
$temp->add(new admin_setting_configcheckbox('updatenotifybuilds', new lang_string('updatenotifybuilds', 'core_admin'),
|
||||
new lang_string('updatenotifybuilds_desc', 'core_admin'), 0));
|
||||
$ADMIN->add('server', $temp);
|
||||
}
|
||||
// "update notifications" settingpage
|
||||
if (empty($CFG->disableupdatenotifications)) {
|
||||
$temp = new admin_settingpage('updatenotifications', new lang_string('updatenotifications', 'core_admin'));
|
||||
$temp->add(new admin_setting_configcheckbox('updateautocheck', new lang_string('updateautocheck', 'core_admin'),
|
||||
new lang_string('updateautocheck_desc', 'core_admin'), 1));
|
||||
$temp->add(new admin_setting_configselect('updateminmaturity', new lang_string('updateminmaturity', 'core_admin'),
|
||||
new lang_string('updateminmaturity_desc', 'core_admin'), MATURITY_STABLE,
|
||||
array(
|
||||
MATURITY_ALPHA => new lang_string('maturity'.MATURITY_ALPHA, 'core_admin'),
|
||||
MATURITY_BETA => new lang_string('maturity'.MATURITY_BETA, 'core_admin'),
|
||||
MATURITY_RC => new lang_string('maturity'.MATURITY_RC, 'core_admin'),
|
||||
MATURITY_STABLE => new lang_string('maturity'.MATURITY_STABLE, 'core_admin'),
|
||||
)));
|
||||
$temp->add(new admin_setting_configcheckbox('updatenotifybuilds', new lang_string('updatenotifybuilds', 'core_admin'),
|
||||
new lang_string('updatenotifybuilds_desc', 'core_admin'), 0));
|
||||
$ADMIN->add('server', $temp);
|
||||
}
|
||||
|
||||
} // end of speedup
|
||||
|
||||
@@ -39,7 +39,6 @@ $ADMIN->add('root', new admin_category('license', new lang_string('license')));
|
||||
$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')));
|
||||
$ADMIN->add('root', new admin_category('payment', new lang_string('payments', 'payment')));
|
||||
$ADMIN->add('root', new admin_category('modules', new lang_string('plugins', 'admin')));
|
||||
$ADMIN->add('root', new admin_category('security', new lang_string('security','admin')));
|
||||
$ADMIN->add('root', new admin_category('appearance', new lang_string('appearance','admin')));
|
||||
|
||||
@@ -32,6 +32,7 @@ $result = optional_param('result', null, PARAM_INT);
|
||||
|
||||
$pageurl = new \moodle_url('/admin/tasklogs.php');
|
||||
$pageurl->param('filter', $filter);
|
||||
$pageurl->param('result', $result);
|
||||
|
||||
$PAGE->set_url($pageurl);
|
||||
$PAGE->set_context(context_system::instance());
|
||||
|
||||
@@ -1,87 +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\local\settings\autocomplete
|
||||
|
||||
Admin setting auto complete.
|
||||
|
||||
Context variables required for this template:
|
||||
* name - element name
|
||||
* id - element id
|
||||
* options - choices
|
||||
* multiple - is multiple choices?
|
||||
* manageurl - url to manage choices
|
||||
* managetext - string to display manage url
|
||||
* tags - Should we allow typing new entries to the field?
|
||||
* ajax - Name of an AMD module to send/process ajax requests
|
||||
* placeholder - Placeholder text for an empty list
|
||||
* casesensitive - Whether the search has to be case-sensitive
|
||||
* showsuggestions - Show suggestions by default - but this can be turned off
|
||||
* noselectionstring - String that is shown when there are no selections
|
||||
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"name": "name0",
|
||||
"id": "id0",
|
||||
"options": [{
|
||||
"value": "1",
|
||||
"text": "option 1",
|
||||
"selected": true,
|
||||
"disabled": false
|
||||
}],
|
||||
"multiple": true,
|
||||
"manageurl": "",
|
||||
"managetext": "",
|
||||
"tags": false,
|
||||
"ajax": "",
|
||||
"placeholder": "",
|
||||
"casesensitive": false,
|
||||
"showsuggestions": true,
|
||||
"noselectionstring": ""
|
||||
}
|
||||
}}
|
||||
{{!
|
||||
Setting autocomplete.
|
||||
}}
|
||||
|
||||
<div class="form-select defaultsnext">
|
||||
<input type="hidden" name="{{name}}[xxxxx]" value="_qf__force_multiselect_submission">
|
||||
<select class="custom-select" name="{{name}}[]"
|
||||
id="{{id}}"
|
||||
{{#multiple}}multiple{{/multiple}}>
|
||||
{{#options}}
|
||||
<option value="{{value}}" {{#selected}}selected{{/selected}}>{{{text}}}</option>
|
||||
{{/options}}
|
||||
</select>
|
||||
{{#manageurl}}
|
||||
<a href="{{manageurl}}">{{managetext}}</a>
|
||||
{{/manageurl}}
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
{{#js}}
|
||||
require(['core/form-autocomplete'], function(module) {
|
||||
module.enhance({{#quote}}#{{id}}{{/quote}},
|
||||
{{tags}},
|
||||
{{#quote}}{{ajax}}{{/quote}},
|
||||
{{#quote}}{{placeholder}}{{/quote}},
|
||||
{{casesensitive}},
|
||||
{{showsuggestions}},
|
||||
{{#quote}}{{noselectionstring}}{{/quote}});
|
||||
});
|
||||
{{/js}}
|
||||
@@ -56,7 +56,7 @@ class behat_admin extends behat_base {
|
||||
$this->execute('behat_navigation::i_select_from_flat_navigation_drawer', [get_string('administrationsite')]);
|
||||
|
||||
// Search by label.
|
||||
$this->execute('behat_forms::i_set_the_field_to', [get_string('search'), $label]);
|
||||
$this->execute('behat_forms::i_set_the_field_to', [get_string('query', 'admin'), $label]);
|
||||
$this->execute("behat_forms::press_button", get_string('search', 'admin'));
|
||||
|
||||
// Admin settings does not use the same DOM structure than other moodle forms
|
||||
|
||||
@@ -64,7 +64,7 @@ class models_list implements \renderable, \templatable {
|
||||
$data = new \stdClass();
|
||||
|
||||
$newmodelmenu = new \action_menu();
|
||||
$newmodelmenu->set_menu_trigger(get_string('newmodel', 'tool_analytics'), 'btn btn-secondary');
|
||||
$newmodelmenu->set_menu_trigger(get_string('newmodel', 'tool_analytics'), 'btn btn-default');
|
||||
$newmodelmenu->set_alignment(\action_menu::TL, \action_menu::BL);
|
||||
|
||||
$newmodelmenu->add(new \action_menu_link(
|
||||
|
||||
@@ -57,10 +57,10 @@
|
||||
{{/trainedexternally}}
|
||||
|
||||
{{! Hidden by default if #trainedexternally as the default option is trainedmodel in this case.}}
|
||||
<div id="id-evaluation-timesplitting-container" class="mt-3 {{#trainedexternally}}hidden{{/trainedexternally}}">
|
||||
<div id="id-evaluation-timesplitting-container" class="m-t-1 {{#trainedexternally}}hidden{{/trainedexternally}}">
|
||||
{{#str}} selecttimesplittingforevaluation, tool_analytics {{/str}}
|
||||
<div>
|
||||
<select id="id-evaluation-timesplitting" name="timesplitting" class="custom-select mt-3">
|
||||
<select id="id-evaluation-timesplitting" name="timesplitting" class="custom-select m-t-1">
|
||||
{{#timesplittingmethods}}
|
||||
<option value="{{id}}">{{text}}</option>
|
||||
{{/timesplittingmethods}}
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<input class="custom-control-input" type="radio" name="exportoption" id="id-mode-exportmodel" value="exportmodel" checked>
|
||||
<label class="custom-control-label" for="id-mode-exportmodel">{{#str}} exportmodel, tool_analytics {{/str}}</label>
|
||||
</div>
|
||||
<div class="custom-control custom-checkbox ml-5" id="id-includeweights-container">
|
||||
<div class="custom-control custom-checkbox m-l-2" id="id-includeweights-container">
|
||||
<input class="custom-control-input" type="checkbox" id="id-includeweights" value="1" checked>
|
||||
<label class="custom-control-label" for="id-includeweights">{{#str}} exportincludeweights, tool_analytics {{/str}}</label>
|
||||
</div>
|
||||
|
||||
@@ -66,6 +66,8 @@ class tool_analytics_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
/**
|
||||
* test_potential_contexts description
|
||||
*
|
||||
* @expectedException required_capability_exception
|
||||
*/
|
||||
public function test_potential_contexts_no_manager() {
|
||||
$this->resetAfterTest();
|
||||
@@ -73,7 +75,6 @@ class tool_analytics_external_testcase extends externallib_advanced_testcase {
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
$this->expectException(required_capability_exception::class);
|
||||
$this->assertCount(2, \tool_analytics\external::potential_contexts());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,10 +49,6 @@ list($options, $unrecognized) = cli_get_params(
|
||||
'torun' => 0,
|
||||
'optimize-runs' => '',
|
||||
'add-core-features-to-theme' => false,
|
||||
'axe' => false,
|
||||
'disable-composer' => false,
|
||||
'composer-upgrade' => true,
|
||||
'composer-self-update' => true,
|
||||
),
|
||||
array(
|
||||
'j' => 'parallel',
|
||||
@@ -68,36 +64,18 @@ $help = "
|
||||
Behat utilities to initialise behat tests
|
||||
|
||||
Usage:
|
||||
php init.php [--parallel=value [--maxruns=value] [--fromrun=value --torun=value]]
|
||||
[--axe] [-o | --optimize-runs] [-a | --add-core-features-to-theme]
|
||||
[--no-composer-self-update] [--no-composer-upgrade]
|
||||
[--disable-composer]
|
||||
[--help]
|
||||
php init.php [--parallel=value [--maxruns=value] [--fromrun=value --torun=value]] [--help]
|
||||
|
||||
Options:
|
||||
-j, --parallel Number of parallel behat run to initialise
|
||||
-m, --maxruns Max parallel processes to be executed at one time
|
||||
--fromrun Execute run starting from (Used for parallel runs on different vms)
|
||||
--torun Execute run till (Used for parallel runs on different vms)
|
||||
--axe Include axe accessibility tests
|
||||
-j, --parallel Number of parallel behat run to initialise
|
||||
-m, --maxruns Max parallel processes to be executed at one time.
|
||||
--fromrun Execute run starting from (Used for parallel runs on different vms)
|
||||
--torun Execute run till (Used for parallel runs on different vms)
|
||||
|
||||
-o, --optimize-runs
|
||||
Split features with specified tags in all parallel runs.
|
||||
-o, --optimize-runs Split features with specified tags in all parallel runs.
|
||||
-a, --add-core-features-to-theme Add all core features to specified theme's
|
||||
|
||||
-a, --add-core-features-to-theme
|
||||
Add all core features to specified theme's
|
||||
|
||||
--no-composer-self-update
|
||||
Prevent upgrade of the composer utility using its self-update command
|
||||
|
||||
--no-composer-upgrade
|
||||
Prevent update development dependencies using composer
|
||||
|
||||
--disable-composer
|
||||
A shortcut to disable composer self-update and dependency update
|
||||
Note: Installation of composer and/or dependencies will still happen as required
|
||||
|
||||
-h, --help Print out this help
|
||||
-h, --help Print out this help
|
||||
|
||||
Example from Moodle root directory:
|
||||
\$ php admin/tool/behat/cli/init.php --parallel=2
|
||||
@@ -124,10 +102,7 @@ if ($options['parallel'] && $options['parallel'] > 1) {
|
||||
}
|
||||
} else {
|
||||
// Only sanitize options for single run.
|
||||
$cmdoptionsforsinglerun = [
|
||||
'add-core-features-to-theme',
|
||||
'axe',
|
||||
];
|
||||
$cmdoptionsforsinglerun = array('add-core-features-to-theme');
|
||||
|
||||
foreach ($cmdoptionsforsinglerun as $option) {
|
||||
if (!empty($options[$option])) {
|
||||
@@ -140,15 +115,8 @@ if ($options['parallel'] && $options['parallel'] > 1) {
|
||||
$cwd = getcwd();
|
||||
$output = null;
|
||||
|
||||
if ($options['disable-composer']) {
|
||||
// Disable self-update and upgrade easily.
|
||||
// Note: Installation will still occur regardless of this setting.
|
||||
$options['composer-self-update'] = false;
|
||||
$options['composer-upgrade'] = false;
|
||||
}
|
||||
|
||||
// Install and update composer and dependencies as required.
|
||||
testing_update_composer_dependencies($options['composer-self-update'], $options['composer-upgrade']);
|
||||
// If behat dependencies not downloaded then do it first, else symfony/process can't be used.
|
||||
testing_update_composer_dependencies();
|
||||
|
||||
// Check whether the behat test environment needs to be updated.
|
||||
chdir(__DIR__);
|
||||
|
||||
@@ -54,7 +54,6 @@ list($options, $unrecognized) = cli_get_params(
|
||||
'torun' => 0,
|
||||
'optimize-runs' => '',
|
||||
'add-core-features-to-theme' => false,
|
||||
'axe' => false,
|
||||
),
|
||||
array(
|
||||
'h' => 'help',
|
||||
@@ -70,7 +69,7 @@ $help = "
|
||||
Behat utilities to manage the test environment
|
||||
|
||||
Usage:
|
||||
php util.php [--install|--drop|--enable|--disable|--diag|--updatesteps|--axe|--help] [--parallel=value [--maxruns=value]]
|
||||
php util.php [--install|--drop|--enable|--disable|--diag|--updatesteps|--help] [--parallel=value [--maxruns=value]]
|
||||
|
||||
Options:
|
||||
--install Installs the test environment for acceptance tests
|
||||
@@ -79,7 +78,6 @@ Options:
|
||||
--disable Disables test environment
|
||||
--diag Get behat test environment status code
|
||||
--updatesteps Update feature step file.
|
||||
--axe Include axe accessibility tests
|
||||
|
||||
-j, --parallel Number of parallel behat run operation
|
||||
-m, --maxruns Max parallel processes to be executed at one time.
|
||||
|
||||
@@ -49,7 +49,6 @@ list($options, $unrecognized) = cli_get_params(
|
||||
'updatesteps' => false,
|
||||
'optimize-runs' => '',
|
||||
'add-core-features-to-theme' => false,
|
||||
'axe' => false,
|
||||
),
|
||||
array(
|
||||
'h' => 'help',
|
||||
@@ -76,7 +75,6 @@ Options:
|
||||
--disable Disables test environment
|
||||
--diag Get behat test environment status code
|
||||
--updatesteps Update feature step file.
|
||||
--axe Include axe accessibility tests
|
||||
|
||||
-o, --optimize-runs Split features with specified tags in all parallel runs.
|
||||
-a, --add-core-features-to-theme Add all core features to specified theme's
|
||||
@@ -183,17 +181,11 @@ if ($options['install']) {
|
||||
behat_config_manager::set_behat_run_config_value('behatsiteenabled', 1);
|
||||
}
|
||||
|
||||
// Define whether to run Behat with axe tests.
|
||||
behat_config_manager::set_behat_run_config_value('axe', $options['axe']);
|
||||
|
||||
// Enable test mode.
|
||||
$timestart = microtime(true);
|
||||
mtrace('Creating Behat configuration ...', '');
|
||||
behat_util::start_test_mode($options['add-core-features-to-theme'], $options['optimize-runs'], $parallel, $run);
|
||||
mtrace(' done in ' . round(microtime(true) - $timestart, 2) . ' seconds.');
|
||||
|
||||
// Themes are only built in the 'enable' command.
|
||||
behat_util::build_themes(true);
|
||||
behat_util::build_themes();
|
||||
mtrace("Testing environment themes built");
|
||||
|
||||
// This is only displayed once for parallel install.
|
||||
|
||||
@@ -6,14 +6,18 @@ Feature: Edit capabilities
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
| username | firstname | lastname |
|
||||
| teacher1 | Teacher | 1 |
|
||||
| tutor | Teaching | Assistant |
|
||||
| student | Student | One |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
| fullname | shortname |
|
||||
| Course 1 | C1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| tutor | C1 | teacher |
|
||||
| student | C1 | student |
|
||||
|
||||
Scenario: Default system capabilities modification
|
||||
Given I log in as "admin"
|
||||
@@ -60,3 +64,25 @@ Feature: Edit capabilities
|
||||
Then "mod/forum:deleteanypost" capability has "Prohibit" permission
|
||||
And "mod/forum:editanypost" capability has "Prevent" permission
|
||||
And "mod/forum:addquestion" capability has "Allow" permission
|
||||
|
||||
@javascript
|
||||
Scenario: Edit permissions escapes role names correctly
|
||||
When I am on the "C1" "Course" page logged in as "admin"
|
||||
And I navigate to "Edit settings" in current page administration
|
||||
And I set the following fields to these values:
|
||||
| Your word for 'Teacher' | Teacher >= editing |
|
||||
| Your word for 'Non-editing teacher' | Teacher < "editing" |
|
||||
| Your word for 'Student' | Studier & 'learner' |
|
||||
And I press "Save and display"
|
||||
And I navigate to course participants
|
||||
Then I should see "Teacher >= editing" in the "Teacher 1" "table_row"
|
||||
And I should see "Teacher < \"editing\"" in the "Teaching Assistant" "table_row"
|
||||
And I should see "Studier & 'learner'" in the "Student One" "table_row"
|
||||
And I navigate to "Users > Permissions" in current page administration
|
||||
And I should see "Teacher >= editing" in the "mod/forum:replypost" "table_row"
|
||||
And I should see "Teacher < \"editing\"" in the "mod/forum:replypost" "table_row"
|
||||
And I should see "Studier & 'learner'" in the "mod/forum:replypost" "table_row"
|
||||
And I follow "Prohibit"
|
||||
And "Teacher >= editing" "button" in the "Prohibit role" "dialogue" should be visible
|
||||
And "Teacher < \"editing\"" "button" in the "Prohibit role" "dialogue" should be visible
|
||||
And "Studier & 'learner'" "button" in the "Prohibit role" "dialogue" should be visible
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
@tool_behat
|
||||
Feature: Verify that the inplace editable field works as expected
|
||||
In order to use behat step definitions
|
||||
As a test write
|
||||
I need to ensure that the inplace editable works in forms
|
||||
|
||||
Background:
|
||||
Given the following "course" exists:
|
||||
| fullname | Course 1 |
|
||||
| shortname | C1 |
|
||||
And the following "activities" exist:
|
||||
| activity | course | name | idnumber |
|
||||
| forum | C1 | My first forum | forum1 |
|
||||
| assign | C1 | My first assignment | assign1 |
|
||||
| quiz | C1 | My first quiz | quiz1 |
|
||||
And I log in as "admin"
|
||||
And I am on "Course 1" course homepage with editing mode on
|
||||
|
||||
@javascript
|
||||
Scenario: Using an inplace editable updates the name of an activity
|
||||
When I set the field "Edit title" in the "My first assignment" "activity" to "Coursework submission"
|
||||
Then I should see "Coursework submission"
|
||||
And I should not see "My first assignment"
|
||||
But I should see "My first forum"
|
||||
And I should see "My first quiz"
|
||||
And I set the field "Edit title" in the "Coursework submission" "activity" to "My first assignment"
|
||||
And I should not see "Coursework submission"
|
||||
But I should see "My first assignment"
|
||||
And I should see "My first forum"
|
||||
And I should see "My first quiz"
|
||||
@@ -0,0 +1,52 @@
|
||||
@tool_behat
|
||||
Feature: Verify that keyboard steps work as expected
|
||||
In order to use behat step definitions
|
||||
As a test writer
|
||||
I need to verify that the keyboard steps work as expected
|
||||
|
||||
@javascript
|
||||
Scenario: Typing keys into a field causes them to be input
|
||||
Given the following "users" exist:
|
||||
| username | email | firstname | lastname | password |
|
||||
| saffronr | saffron.rutledge@example.com | Saffron | Rutledge | flowerpower |
|
||||
Given I click on "Log in" "link"
|
||||
And I click on "Username" "field"
|
||||
When I type "saffronr"
|
||||
And I press the tab key
|
||||
And I type "flowerpower"
|
||||
And I press enter
|
||||
Then I should see "You are logged in as Saffron Rutledge"
|
||||
|
||||
@javascript
|
||||
Scenario: Using tab changes focus to the next or previous field
|
||||
Given I click on "Log in" "link"
|
||||
And I click on "Username" "field"
|
||||
And the focused element is "Username" "field"
|
||||
When I press the tab key
|
||||
Then the focused element is "Password" "field"
|
||||
|
||||
And I press the shift tab key
|
||||
And the focused element is "Username" "field"
|
||||
|
||||
@javascript
|
||||
Scenario: Using the arrow keys allows me to navigate through menus
|
||||
Given the following "users" exist:
|
||||
| username | email | firstname | lastname |
|
||||
| saffronr | saffron.rutledge@example.com | Saffron | Rutledge |
|
||||
And I log in as "saffronr"
|
||||
And I click on "Saffron Rutledge" "link" in the ".usermenu" "css_element"
|
||||
When I press the up key
|
||||
Then the focused element is "Log out" "link"
|
||||
|
||||
@javascript
|
||||
Scenario: The escape key can be used to close a dialogue
|
||||
Given the following "course" exists:
|
||||
| fullname | C1|
|
||||
| shortname | C1 |
|
||||
And I log in as "admin"
|
||||
And I am on "C1" course homepage
|
||||
And I navigate to course participants
|
||||
And I press "Enrol users"
|
||||
And "Enrol users" "dialogue" should be visible
|
||||
When I press the escape key
|
||||
Then "Enrol users" "dialogue" should not be visible
|
||||
@@ -87,7 +87,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
/**
|
||||
* Setup test.
|
||||
*/
|
||||
public function setUp(): void {
|
||||
public function setup() {
|
||||
global $CFG;
|
||||
|
||||
$this->resetAfterTest();
|
||||
@@ -165,7 +165,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
// Check contexts.
|
||||
@@ -324,7 +324,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
// Check contexts.
|
||||
@@ -368,7 +368,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
// Check contexts.
|
||||
@@ -399,7 +399,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
// Check contexts.
|
||||
@@ -428,7 +428,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
// Check contexts.
|
||||
@@ -532,7 +532,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
// Check contexts.
|
||||
@@ -611,7 +611,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
// Check contexts.
|
||||
@@ -646,7 +646,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,7 +662,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -678,7 +678,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -693,7 +693,7 @@ class tool_behat_manager_util_testcase extends advanced_testcase {
|
||||
$this->assertCount(count($paths), $suites[$themename]['paths']);
|
||||
|
||||
foreach ($paths as $key => $feature) {
|
||||
$this->assertStringContainsString($feature, $suites[$themename]['paths'][$key]);
|
||||
$this->assertContains($feature, $suites[$themename]['paths'][$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class tool_capability_events_testcase extends advanced_testcase {
|
||||
/**
|
||||
* Setup testcase.
|
||||
*/
|
||||
public function setUp(): void {
|
||||
public function setUp() {
|
||||
$this->setAdminUser();
|
||||
$this->resetAfterTest();
|
||||
}
|
||||
|
||||
admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search-debug.js
Vendored
+4
-27
@@ -53,13 +53,6 @@ SEARCH.prototype = {
|
||||
* @protected
|
||||
*/
|
||||
button: null,
|
||||
/**
|
||||
* The cancel button for the form.
|
||||
* @property button
|
||||
* @type Node
|
||||
* @protected
|
||||
*/
|
||||
cancel: null,
|
||||
/**
|
||||
* The last search node if there is one.
|
||||
* If there is a last search node then the last search term will be persisted between requests.
|
||||
@@ -83,28 +76,17 @@ SEARCH.prototype = {
|
||||
this.button = this.form.all('input[type=submit]');
|
||||
this.lastsearch = this.form.one('input[name=search]');
|
||||
|
||||
var div = Y.Node.create('<div id="capabilitysearchui" class="input-group simplesearchform mb-2"' +
|
||||
'data-fieldtype="text"></div>'),
|
||||
label = Y.Node.create('<label for="capabilitysearch"><span class="sr-only"' +
|
||||
this.get('strsearch') + '</span></label>');
|
||||
this.cancel = Y.Node.create('<a class="btn btn-clear d-none icon-no-margin">' +
|
||||
'<i class="icon fa fa-times fa-fw " aria-hidden="true"></i>' +
|
||||
'</a>');
|
||||
this.input = Y.Node.create('<input type="text" class="form-control withclear" placeholder="' +
|
||||
this.get('strsearch') + '"id="capabilitysearch" />');
|
||||
var div = Y.Node.create('<div id="capabilitysearchui" data-fieldtype="text"></div>'),
|
||||
label = Y.Node.create('<label for="capabilitysearch">' + this.get('strsearch') + '</label>');
|
||||
this.input = Y.Node.create('<input type="text" id="capabilitysearch" />');
|
||||
|
||||
div.append(label).append(this.input).append(this.cancel);
|
||||
div.append(label).append(this.input);
|
||||
|
||||
this.select.insert(div, 'before');
|
||||
|
||||
this.input.on('keyup', this.typed, this);
|
||||
this.select.on('change', this.validate, this);
|
||||
|
||||
this.cancel.on('click', function() {
|
||||
this.input.set('value', '');
|
||||
this.typed();
|
||||
}, this);
|
||||
|
||||
if (this.lastsearch) {
|
||||
this.input.set('value', this.lastsearch.get('value'));
|
||||
this.typed();
|
||||
@@ -151,11 +133,6 @@ SEARCH.prototype = {
|
||||
last.set('selected', true);
|
||||
}
|
||||
}
|
||||
if (search !== '') {
|
||||
this.cancel.removeClass("d-none");
|
||||
} else {
|
||||
this.cancel.addClass("d-none");
|
||||
}
|
||||
this.validate();
|
||||
}
|
||||
};
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
YUI.add("moodle-tool_capability-search",function(s,t){var e=function(){e.superclass.constructor.apply(this,arguments)};e.prototype={form:null,select:null,selectoptions:{},input:null,button:null,cancel:null,lastsearch:null,initializer:function(){this.form=s.one("#capability-overview-form"),this.select=this.form.one("select[data-search=capability]"),this.select.setStyle("minWidth",this.select.get("offsetWidth")),this.select.get("options").each(function(t){var e=t.get("value");this.selectoptions[e]=t},this),this.button=this.form.all("input[type=submit]"),this.lastsearch=this.form.one("input[name=search]");var t=s.Node.create('<div id="capabilitysearchui" class="input-group simplesearchform mb-2"data-fieldtype="text"></div>'),e=s.Node.create('<label for="capabilitysearch"><span class="sr-only"'+this.get("strsearch")+"</span></label>");this.cancel=s.Node.create('<a class="btn btn-clear d-none icon-no-margin"><i class="icon fa fa-times fa-fw " aria-hidden="true"></i></a>'),this.input=s.Node.create('<input type="text" class="form-control withclear" placeholder="'+this.get("strsearch")+'"id="capabilitysearch" />'),t.append(e).append(this.input).append(this.cancel),this.select.insert(t,"before"),this.input.on("keyup",this.typed,this),this.select.on("change",this.validate,this),this.cancel.on("click",function(){this.input.set("value",""),this.typed()},this),this.lastsearch&&(this.input.set("value",this.lastsearch.get("value")),this.typed(),this.select.one("option[selected]")&&this.select.set("scrollTop",this.select.one("option[selected]").get("getX"))),this.validate()},validate:function(){this.button.set("disabled",""===this.select.get("value"))},typed:function(){var t,e=this.input.get("value"),s=0,i=null;for(t in this.lastsearch&&this.lastsearch.set("value",e),this.select.all("option").remove(),this.selectoptions)0<=t.indexOf(e)&&(s++,i=this.selectoptions[t],this.select.append(this.selectoptions[t]));0===s?this.input.addClass("error"):(this.input.removeClass("error"),1===s&&i.set("selected",!0)),""!==e?this.cancel.removeClass("d-none"):this.cancel.addClass("d-none"),this.validate()}},s.extend(e,s.Base,e.prototype,{NAME:"tool_capability-search",ATTRS:{strsearch:{}}}),M.tool_capability=M.tool_capability||{},M.tool_capability.init_capability_search=function(t){new e(t)}},"@VERSION@",{requires:["base","node"]});
|
||||
YUI.add("moodle-tool_capability-search",function(i,t){var e=function(){e.superclass.constructor.apply(this,arguments)};e.prototype={form:null,select:null,selectoptions:{},input:null,button:null,lastsearch:null,initializer:function(){this.form=i.one("#capability-overview-form"),this.select=this.form.one("select[data-search=capability]"),this.select.setStyle("minWidth",this.select.get("offsetWidth")),this.select.get("options").each(function(t){var e=t.get("value");this.selectoptions[e]=t},this),this.button=this.form.all("input[type=submit]"),this.lastsearch=this.form.one("input[name=search]");var t=i.Node.create('<div id="capabilitysearchui" data-fieldtype="text"></div>'),e=i.Node.create('<label for="capabilitysearch">'+this.get("strsearch")+"</label>");this.input=i.Node.create('<input type="text" id="capabilitysearch" />'),t.append(e).append(this.input),this.select.insert(t,"before"),this.input.on("keyup",this.typed,this),this.select.on("change",this.validate,this),this.lastsearch&&(this.input.set("value",this.lastsearch.get("value")),this.typed(),this.select.one("option[selected]")&&this.select.set("scrollTop",this.select.one("option[selected]").get("getX"))),this.validate()},validate:function(){this.button.set("disabled",""===this.select.get("value"))},typed:function(){var t,e=this.input.get("value"),i=0,s=null;for(t in this.lastsearch&&this.lastsearch.set("value",e),this.select.all("option").remove(),this.selectoptions)0<=t.indexOf(e)&&(i++,s=this.selectoptions[t],this.select.append(this.selectoptions[t]));0===i?this.input.addClass("error"):(this.input.removeClass("error"),1===i&&s.set("selected",!0)),this.validate()}},i.extend(e,i.Base,e.prototype,{NAME:"tool_capability-search",ATTRS:{strsearch:{}}}),M.tool_capability=M.tool_capability||{},M.tool_capability.init_capability_search=function(t){new e(t)}},"@VERSION@",{requires:["base","node"]});
|
||||
Vendored
+4
-27
@@ -53,13 +53,6 @@ SEARCH.prototype = {
|
||||
* @protected
|
||||
*/
|
||||
button: null,
|
||||
/**
|
||||
* The cancel button for the form.
|
||||
* @property button
|
||||
* @type Node
|
||||
* @protected
|
||||
*/
|
||||
cancel: null,
|
||||
/**
|
||||
* The last search node if there is one.
|
||||
* If there is a last search node then the last search term will be persisted between requests.
|
||||
@@ -83,28 +76,17 @@ SEARCH.prototype = {
|
||||
this.button = this.form.all('input[type=submit]');
|
||||
this.lastsearch = this.form.one('input[name=search]');
|
||||
|
||||
var div = Y.Node.create('<div id="capabilitysearchui" class="input-group simplesearchform mb-2"' +
|
||||
'data-fieldtype="text"></div>'),
|
||||
label = Y.Node.create('<label for="capabilitysearch"><span class="sr-only"' +
|
||||
this.get('strsearch') + '</span></label>');
|
||||
this.cancel = Y.Node.create('<a class="btn btn-clear d-none icon-no-margin">' +
|
||||
'<i class="icon fa fa-times fa-fw " aria-hidden="true"></i>' +
|
||||
'</a>');
|
||||
this.input = Y.Node.create('<input type="text" class="form-control withclear" placeholder="' +
|
||||
this.get('strsearch') + '"id="capabilitysearch" />');
|
||||
var div = Y.Node.create('<div id="capabilitysearchui" data-fieldtype="text"></div>'),
|
||||
label = Y.Node.create('<label for="capabilitysearch">' + this.get('strsearch') + '</label>');
|
||||
this.input = Y.Node.create('<input type="text" id="capabilitysearch" />');
|
||||
|
||||
div.append(label).append(this.input).append(this.cancel);
|
||||
div.append(label).append(this.input);
|
||||
|
||||
this.select.insert(div, 'before');
|
||||
|
||||
this.input.on('keyup', this.typed, this);
|
||||
this.select.on('change', this.validate, this);
|
||||
|
||||
this.cancel.on('click', function() {
|
||||
this.input.set('value', '');
|
||||
this.typed();
|
||||
}, this);
|
||||
|
||||
if (this.lastsearch) {
|
||||
this.input.set('value', this.lastsearch.get('value'));
|
||||
this.typed();
|
||||
@@ -151,11 +133,6 @@ SEARCH.prototype = {
|
||||
last.set('selected', true);
|
||||
}
|
||||
}
|
||||
if (search !== '') {
|
||||
this.cancel.removeClass("d-none");
|
||||
} else {
|
||||
this.cancel.addClass("d-none");
|
||||
}
|
||||
this.validate();
|
||||
}
|
||||
};
|
||||
|
||||
+4
-27
@@ -51,13 +51,6 @@ SEARCH.prototype = {
|
||||
* @protected
|
||||
*/
|
||||
button: null,
|
||||
/**
|
||||
* The cancel button for the form.
|
||||
* @property button
|
||||
* @type Node
|
||||
* @protected
|
||||
*/
|
||||
cancel: null,
|
||||
/**
|
||||
* The last search node if there is one.
|
||||
* If there is a last search node then the last search term will be persisted between requests.
|
||||
@@ -81,28 +74,17 @@ SEARCH.prototype = {
|
||||
this.button = this.form.all('input[type=submit]');
|
||||
this.lastsearch = this.form.one('input[name=search]');
|
||||
|
||||
var div = Y.Node.create('<div id="capabilitysearchui" class="input-group simplesearchform mb-2"' +
|
||||
'data-fieldtype="text"></div>'),
|
||||
label = Y.Node.create('<label for="capabilitysearch"><span class="sr-only"' +
|
||||
this.get('strsearch') + '</span></label>');
|
||||
this.cancel = Y.Node.create('<a class="btn btn-clear d-none icon-no-margin">' +
|
||||
'<i class="icon fa fa-times fa-fw " aria-hidden="true"></i>' +
|
||||
'</a>');
|
||||
this.input = Y.Node.create('<input type="text" class="form-control withclear" placeholder="' +
|
||||
this.get('strsearch') + '"id="capabilitysearch" />');
|
||||
var div = Y.Node.create('<div id="capabilitysearchui" data-fieldtype="text"></div>'),
|
||||
label = Y.Node.create('<label for="capabilitysearch">' + this.get('strsearch') + '</label>');
|
||||
this.input = Y.Node.create('<input type="text" id="capabilitysearch" />');
|
||||
|
||||
div.append(label).append(this.input).append(this.cancel);
|
||||
div.append(label).append(this.input);
|
||||
|
||||
this.select.insert(div, 'before');
|
||||
|
||||
this.input.on('keyup', this.typed, this);
|
||||
this.select.on('change', this.validate, this);
|
||||
|
||||
this.cancel.on('click', function() {
|
||||
this.input.set('value', '');
|
||||
this.typed();
|
||||
}, this);
|
||||
|
||||
if (this.lastsearch) {
|
||||
this.input.set('value', this.lastsearch.get('value'));
|
||||
this.typed();
|
||||
@@ -149,11 +131,6 @@ SEARCH.prototype = {
|
||||
last.set('selected', true);
|
||||
}
|
||||
}
|
||||
if (search !== '') {
|
||||
this.cancel.removeClass("d-none");
|
||||
} else {
|
||||
this.cancel.addClass("d-none");
|
||||
}
|
||||
this.validate();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ class tool_cohortroles_api_testcase extends advanced_testcase {
|
||||
/**
|
||||
* Setup function- we will create a course and add an assign instance to it.
|
||||
*/
|
||||
protected function setUp(): void {
|
||||
protected function setUp() {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Create some users.
|
||||
@@ -60,6 +60,9 @@ class tool_cohortroles_api_testcase extends advanced_testcase {
|
||||
cohort_add_member($this->cohort->id, $this->userassignover->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException required_capability_exception
|
||||
*/
|
||||
public function test_create_cohort_role_assignment_without_permission() {
|
||||
$this->setUser($this->userassignto);
|
||||
$params = (object) array(
|
||||
@@ -67,10 +70,12 @@ class tool_cohortroles_api_testcase extends advanced_testcase {
|
||||
'roleid' => $this->roleid,
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
$this->expectException(required_capability_exception::class);
|
||||
api::create_cohort_role_assignment($params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException core_competency\invalid_persistent_exception
|
||||
*/
|
||||
public function test_create_cohort_role_assignment_with_invalid_data() {
|
||||
$this->setAdminUser();
|
||||
$params = (object) array(
|
||||
@@ -78,7 +83,6 @@ class tool_cohortroles_api_testcase extends advanced_testcase {
|
||||
'roleid' => -8,
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
$this->expectException(\core_competency\invalid_persistent_exception::class);
|
||||
api::create_cohort_role_assignment($params);
|
||||
}
|
||||
|
||||
@@ -96,6 +100,9 @@ class tool_cohortroles_api_testcase extends advanced_testcase {
|
||||
$this->assertEquals($result->get('cohortid'), $this->cohort->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException required_capability_exception
|
||||
*/
|
||||
public function test_delete_cohort_role_assignment_without_permission() {
|
||||
$this->setAdminUser();
|
||||
$params = (object) array(
|
||||
@@ -105,10 +112,12 @@ class tool_cohortroles_api_testcase extends advanced_testcase {
|
||||
);
|
||||
$result = api::create_cohort_role_assignment($params);
|
||||
$this->setUser($this->userassignto);
|
||||
$this->expectException(required_capability_exception::class);
|
||||
api::delete_cohort_role_assignment($result->get('id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException dml_missing_record_exception
|
||||
*/
|
||||
public function test_delete_cohort_role_assignment_with_invalid_data() {
|
||||
$this->setAdminUser();
|
||||
$params = (object) array(
|
||||
@@ -117,7 +126,6 @@ class tool_cohortroles_api_testcase extends advanced_testcase {
|
||||
'cohortid' => $this->cohort->id
|
||||
);
|
||||
$result = api::create_cohort_role_assignment($params);
|
||||
$this->expectException(dml_missing_record_exception::class);
|
||||
api::delete_cohort_role_assignment($result->get('id') + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ class tool_cohortroles_privacy_testcase extends \core_privacy\tests\provider_tes
|
||||
/**
|
||||
* Overriding setUp() function to always reset after tests.
|
||||
*/
|
||||
public function setUp(): void {
|
||||
public function setUp() {
|
||||
$this->resetAfterTest(true);
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ class tool_cohortroles_privacy_testcase extends \core_privacy\tests\provider_tes
|
||||
CONTEXT_COURSECAT
|
||||
];
|
||||
// Test the User's contexts equal the system and course category context.
|
||||
$this->assertEqualsCanonicalizing($expected, $contextlevels);
|
||||
$this->assertEquals($expected, $contextlevels, '', 0, 10, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,68 +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/>.
|
||||
|
||||
/**
|
||||
* Creates Formular for customlang file export
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2020 Thomas Wedekind <Thomas.Wedekind@univie.ac.at>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace tool_customlang\form;
|
||||
|
||||
use tool_customlang_utils;
|
||||
|
||||
/**
|
||||
* Formular for customlang file export
|
||||
*
|
||||
* @copyright 2020 Thomas Wedekind <Thomas.Wedekind@univie.ac.at>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class export extends \moodleform {
|
||||
|
||||
/**
|
||||
* Add elements to form
|
||||
*/
|
||||
public function definition() {
|
||||
$lng = $this->_customdata['lng'];
|
||||
$mform = $this->_form;
|
||||
|
||||
$langdir = tool_customlang_utils::get_localpack_location($lng);
|
||||
|
||||
// The export button only appears if a local lang is present.
|
||||
if (!check_dir_exists($langdir) || !count(glob("$langdir/*"))) {
|
||||
print_error('nolocallang', 'tool_customlang');
|
||||
}
|
||||
|
||||
$langfiles = scandir($langdir);
|
||||
$fileoptions = [];
|
||||
foreach ($langfiles as $file) {
|
||||
if (substr($file, 0, 1) != '.') {
|
||||
$fileoptions[$file] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
$mform->addElement('hidden', 'lng', $lng);
|
||||
$mform->setType('lng', PARAM_LANG);
|
||||
|
||||
$select = $mform->addElement('select', 'files', get_string('exportfilter', 'tool_customlang'), $fileoptions);
|
||||
$select->setMultiple(true);
|
||||
$mform->addRule('files', get_string('required'), 'required', null, 'client');
|
||||
$mform->setDefault('files', $fileoptions);
|
||||
|
||||
$this->add_action_buttons(true, get_string('export', 'tool_customlang'));
|
||||
}
|
||||
}
|
||||
@@ -1,68 +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/>.
|
||||
|
||||
/**
|
||||
* Upload a zip of custom lang php files.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_customlang\form;
|
||||
|
||||
use tool_customlang\local\importer;
|
||||
|
||||
/**
|
||||
* Upload a zip/php of custom lang php files.
|
||||
*
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class import extends \moodleform {
|
||||
|
||||
/**
|
||||
* Form definition.
|
||||
*/
|
||||
public function definition() {
|
||||
$mform = $this->_form;
|
||||
$mform->addElement('header', 'settingsheader', get_string('import', 'tool_customlang'));
|
||||
|
||||
$mform->addElement('hidden', 'lng');
|
||||
$mform->setType('lng', PARAM_LANG);
|
||||
$mform->setDefault('lng', $this->_customdata['lng']);
|
||||
|
||||
$filemanageroptions = array(
|
||||
'accepted_types' => array('.php', '.zip'),
|
||||
'maxbytes' => 0,
|
||||
'maxfiles' => 1,
|
||||
'subdirs' => 0
|
||||
);
|
||||
|
||||
$mform->addElement('filepicker', 'pack', get_string('langpack', 'tool_customlang'),
|
||||
null, $filemanageroptions);
|
||||
$mform->addRule('pack', null, 'required');
|
||||
|
||||
$modes = [
|
||||
importer::IMPORTALL => get_string('import_all', 'tool_customlang'),
|
||||
importer::IMPORTUPDATE => get_string('import_update', 'tool_customlang'),
|
||||
importer::IMPORTNEW => get_string('import_new', 'tool_customlang'),
|
||||
];
|
||||
$mform->addElement('select', 'importmode', get_string('import_mode', 'tool_customlang'), $modes);
|
||||
|
||||
$mform->addElement('submit', 'importcustomstrings', get_string('importfile', 'tool_customlang'));
|
||||
}
|
||||
}
|
||||
@@ -1,268 +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/>.
|
||||
|
||||
/**
|
||||
* Custom lang importer.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_customlang\local;
|
||||
|
||||
use tool_customlang\local\mlang\phpparser;
|
||||
use tool_customlang\local\mlang\logstatus;
|
||||
use tool_customlang\local\mlang\langstring;
|
||||
use core\output\notification;
|
||||
use stored_file;
|
||||
use coding_exception;
|
||||
use moodle_exception;
|
||||
use core_component;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class containing tha custom lang importer
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class importer {
|
||||
|
||||
/** @var int imports will only create new customizations */
|
||||
public const IMPORTNEW = 1;
|
||||
/** @var int imports will only update the current customizations */
|
||||
public const IMPORTUPDATE = 2;
|
||||
/** @var int imports all strings */
|
||||
public const IMPORTALL = 3;
|
||||
|
||||
/**
|
||||
* @var string the language name
|
||||
*/
|
||||
protected $lng;
|
||||
|
||||
/**
|
||||
* @var int the importation mode (new, update, all)
|
||||
*/
|
||||
protected $importmode;
|
||||
|
||||
/**
|
||||
* @var string request folder path
|
||||
*/
|
||||
private $folder;
|
||||
|
||||
/**
|
||||
* @var array import log messages
|
||||
*/
|
||||
private $log;
|
||||
|
||||
/**
|
||||
* Constructor for the importer class.
|
||||
*
|
||||
* @param string $lng the current language to import.
|
||||
* @param int $importmode the import method (IMPORTALL, IMPORTNEW, IMPORTUPDATE).
|
||||
*/
|
||||
public function __construct(string $lng, int $importmode = self::IMPORTALL) {
|
||||
$this->lng = $lng;
|
||||
$this->importmode = $importmode;
|
||||
$this->log = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last parse log.
|
||||
*
|
||||
* @return logstatus[] mlang logstatus with the messages
|
||||
*/
|
||||
public function get_log(): array {
|
||||
return $this->log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import customlang files.
|
||||
*
|
||||
* @param stored_file[] $files array of files to import
|
||||
*/
|
||||
public function import(array $files): void {
|
||||
// Create a temporal folder to store the files.
|
||||
$this->folder = make_request_directory(false);
|
||||
|
||||
$langfiles = $this->deploy_files($files);
|
||||
|
||||
$this->process_files($langfiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploy all files into a request folder.
|
||||
*
|
||||
* @param stored_file[] $files array of files to deploy
|
||||
* @return string[] of file paths
|
||||
*/
|
||||
private function deploy_files(array $files): array {
|
||||
$result = [];
|
||||
// Desploy all files.
|
||||
foreach ($files as $file) {
|
||||
if ($file->get_mimetype() == 'application/zip') {
|
||||
$result = array_merge($result, $this->unzip_file($file));
|
||||
} else {
|
||||
$path = $this->folder.'/'.$file->get_filename();
|
||||
$file->copy_content_to($path);
|
||||
$result = array_merge($result, [$path]);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unzip a file into the request folder.
|
||||
*
|
||||
* @param stored_file $file the zip file to unzip
|
||||
* @return string[] of zip content paths
|
||||
*/
|
||||
private function unzip_file(stored_file $file): array {
|
||||
$fp = get_file_packer('application/zip');
|
||||
$zipcontents = $fp->extract_to_pathname($file, $this->folder);
|
||||
if (!$zipcontents) {
|
||||
throw new moodle_exception("Error Unzipping file", 1);
|
||||
}
|
||||
$result = [];
|
||||
foreach ($zipcontents as $contentname => $success) {
|
||||
if ($success) {
|
||||
$result[] = $this->folder.'/'.$contentname;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import strings from a list of langfiles.
|
||||
*
|
||||
* @param string[] $langfiles an array with file paths
|
||||
*/
|
||||
private function process_files(array $langfiles): void {
|
||||
$parser = phpparser::get_instance();
|
||||
foreach ($langfiles as $filepath) {
|
||||
$component = $this->component_from_filepath($filepath);
|
||||
if ($component) {
|
||||
$strings = $parser->parse(file_get_contents($filepath));
|
||||
$this->import_strings($strings, $component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get the component from a filepath.
|
||||
*
|
||||
* @param string $filepath the filepath
|
||||
* @return stdCalss|null the DB record of that component
|
||||
*/
|
||||
private function component_from_filepath(string $filepath) {
|
||||
global $DB;
|
||||
|
||||
// Get component from filename.
|
||||
$pathparts = pathinfo($filepath);
|
||||
if (empty($pathparts['filename'])) {
|
||||
throw new coding_exception("Cannot get filename from $filepath", 1);
|
||||
}
|
||||
$filename = $pathparts['filename'];
|
||||
|
||||
$normalized = core_component::normalize_component($filename);
|
||||
if (count($normalized) == 1 || empty($normalized[1])) {
|
||||
$componentname = $normalized[0];
|
||||
} else {
|
||||
$componentname = implode('_', $normalized);
|
||||
}
|
||||
|
||||
$result = $DB->get_record('tool_customlang_components', ['name' => $componentname]);
|
||||
|
||||
if (!$result) {
|
||||
$this->log[] = new logstatus('notice_missingcomponent', notification::NOTIFY_ERROR, null, $componentname);
|
||||
return null;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import an array of strings into the customlang tables.
|
||||
*
|
||||
* @param langstring[] $strings the langstring to set
|
||||
* @param stdClass $component the target component
|
||||
*/
|
||||
private function import_strings(array $strings, stdClass $component): void {
|
||||
global $DB;
|
||||
|
||||
foreach ($strings as $newstring) {
|
||||
// Check current DB entry.
|
||||
$customlang = $DB->get_record('tool_customlang', [
|
||||
'componentid' => $component->id,
|
||||
'stringid' => $newstring->id,
|
||||
'lang' => $this->lng,
|
||||
]);
|
||||
if (!$customlang) {
|
||||
$customlang = null;
|
||||
}
|
||||
|
||||
if ($this->can_save_string($customlang, $newstring, $component)) {
|
||||
$customlang->local = $newstring->text;
|
||||
$customlang->timecustomized = $newstring->timemodified;
|
||||
$customlang->outdated = 0;
|
||||
$customlang->modified = 1;
|
||||
$DB->update_record('tool_customlang', $customlang);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a specific string can be saved based on the current importmode.
|
||||
*
|
||||
* @param stdClass $customlang customlang original record
|
||||
* @param langstring $newstring the new strign to store
|
||||
* @param stdClass $component the component target
|
||||
* @return bool if the string can be stored
|
||||
*/
|
||||
private function can_save_string(?stdClass $customlang, langstring $newstring, stdClass $component): bool {
|
||||
$result = false;
|
||||
$message = 'notice_success';
|
||||
if (empty($customlang)) {
|
||||
$message = 'notice_inexitentstring';
|
||||
$this->log[] = new logstatus($message, notification::NOTIFY_ERROR, null, $component->name, $newstring);
|
||||
return $result;
|
||||
}
|
||||
|
||||
switch ($this->importmode) {
|
||||
case self::IMPORTNEW:
|
||||
$result = empty($customlang->local);
|
||||
$warningmessage = 'notice_ignoreupdate';
|
||||
break;
|
||||
case self::IMPORTUPDATE:
|
||||
$result = !empty($customlang->local);
|
||||
$warningmessage = 'notice_ignorenew';
|
||||
break;
|
||||
case self::IMPORTALL:
|
||||
$result = true;
|
||||
break;
|
||||
}
|
||||
if ($result) {
|
||||
$errorlevel = notification::NOTIFY_SUCCESS;
|
||||
} else {
|
||||
$errorlevel = notification::NOTIFY_ERROR;
|
||||
$message = $warningmessage;
|
||||
}
|
||||
$this->log[] = new logstatus($message, $errorlevel, null, $component->name, $newstring);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -1,177 +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/>.
|
||||
|
||||
/**
|
||||
* Language string based on David Mudrak langstring from local_amos.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_customlang\local\mlang;
|
||||
|
||||
use moodle_exception;
|
||||
use stdclass;
|
||||
|
||||
/**
|
||||
* Class containing a lang string cleaned.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a single string
|
||||
*/
|
||||
class langstring {
|
||||
|
||||
/** @var string identifier */
|
||||
public $id = null;
|
||||
|
||||
/** @var string */
|
||||
public $text = '';
|
||||
|
||||
/** @var int the time stamp when this string was saved */
|
||||
public $timemodified = null;
|
||||
|
||||
/** @var bool is deleted */
|
||||
public $deleted = false;
|
||||
|
||||
/** @var stdclass extra information about the string */
|
||||
public $extra = null;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param string $id string identifier
|
||||
* @param string $text string text
|
||||
* @param int $timemodified
|
||||
* @param int $deleted
|
||||
* @param stdclass $extra
|
||||
*/
|
||||
public function __construct(string $id, string $text = '', int $timemodified = null,
|
||||
int $deleted = 0, stdclass $extra = null) {
|
||||
|
||||
if (is_null($timemodified)) {
|
||||
$timemodified = time();
|
||||
}
|
||||
$this->id = $id;
|
||||
$this->text = $text;
|
||||
$this->timemodified = $timemodified;
|
||||
$this->deleted = $deleted;
|
||||
$this->extra = $extra;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a string text, returns it being formatted properly for storing in AMOS repository.
|
||||
*
|
||||
* Note: This method is taken directly from local_amos as it is highly tested and robust.
|
||||
* The Moodle 1.x part is keep on puspose to make it easier the copy paste from both codes.
|
||||
* This could change in the future when AMOS stop suporting the 1.x langstrings.
|
||||
*
|
||||
* We need to know for what branch the string should be prepared due to internal changes in
|
||||
* format required by get_string()
|
||||
* - for get_string() in Moodle 1.6 - 1.9 use $format == 1
|
||||
* - for get_string() in Moodle 2.0 and higher use $format == 2
|
||||
*
|
||||
* Typical usages of this methods:
|
||||
* $t = langstring::fix_syntax($t); // sanity new translations of 2.x strings
|
||||
* $t = langstring::fix_syntax($t, 1); // sanity legacy 1.x strings
|
||||
* $t = langstring::fix_syntax($t, 2, 1); // convert format of 1.x strings into 2.x
|
||||
*
|
||||
* Backward converting 2.x format into 1.x is not supported
|
||||
*
|
||||
* @param string $text string text to be fixed
|
||||
* @param int $format target get_string() format version
|
||||
* @param int $from which format version does the text come from, defaults to the same as $format
|
||||
* @return string
|
||||
*/
|
||||
public static function fix_syntax(string $text, int $format = 2, ?int $from = null): string {
|
||||
if (is_null($from)) {
|
||||
$from = $format;
|
||||
}
|
||||
|
||||
// Common filter.
|
||||
$clean = trim($text);
|
||||
$search = [
|
||||
// Remove \r if it is part of \r\n.
|
||||
'/\r(?=\n)/',
|
||||
|
||||
// Control characters to be replaced with \n
|
||||
// LINE TABULATION, FORM FEED, CARRIAGE RETURN, END OF TRANSMISSION BLOCK,
|
||||
// END OF MEDIUM, SUBSTITUTE, BREAK PERMITTED HERE, NEXT LINE, START OF STRING,
|
||||
// STRING TERMINATOR and Unicode character categorys Zl and Zp.
|
||||
'/[\x{0B}-\r\x{17}\x{19}\x{1A}\x{82}\x{85}\x{98}\x{9C}\p{Zl}\p{Zp}]/u',
|
||||
|
||||
// Control characters to be removed
|
||||
// NULL, ENQUIRY, ACKNOWLEDGE, BELL, SHIFT {OUT,IN}, DATA LINK ESCAPE,
|
||||
// DEVICE CONTROL {ONE,TWO,THREE,FOUR}, NEGATIVE ACKNOWLEDGE, SYNCHRONOUS IDLE, ESCAPE,
|
||||
// DELETE, PADDING CHARACTER, HIGH OCTET PRESET, NO BREAK HERE, INDEX,
|
||||
// {START,END} OF SELECTED AREA, CHARACTER TABULATION {SET,WITH JUSTIFICATION},
|
||||
// LINE TABULATION SET, PARTIAL LINE {FORWARD,BACKWARD}, REVERSE LINE FEED,
|
||||
// SINGLE SHIFT {TWO,THREE}, DEVICE CONTROL STRING, PRIVATE USE {ONE,TWO},
|
||||
// SET TRANSMIT STATE, MESSAGE WAITING, {START,END} OF GUARDED AREA,
|
||||
// {SINGLE {GRAPHIC,} CHARACTER,CONTROL SEQUENCE} INTRODUCER, OPERATING SYSTEM COMMAND,
|
||||
// PRIVACY MESSAGE, APPLICATION PROGRAM COMMAND, ZERO WIDTH {,NO-BREAK} SPACE,
|
||||
// REPLACEMENT CHARACTER.
|
||||
'/[\0\x{05}-\x{07}\x{0E}-\x{16}\x{1B}\x{7F}\x{80}\x{81}\x{83}\x{84}\x{86}-\x{93}\x{95}-\x{97}\x{99}-\x{9B}\x{9D}-\x{9F}\x{200B}\x{FEFF}\x{FFFD}]++/u',
|
||||
|
||||
// Remove trailing whitespace at the end of lines in a multiline string.
|
||||
'/[ \t]+(?=\n)/',
|
||||
];
|
||||
$replace = [
|
||||
'',
|
||||
"\n",
|
||||
'',
|
||||
'',
|
||||
];
|
||||
$clean = preg_replace($search, $replace, $clean);
|
||||
|
||||
if (($format === 2) && ($from === 2)) {
|
||||
// Sanity translations of 2.x strings.
|
||||
$clean = preg_replace("/\n{3,}/", "\n\n\n", $clean); // Collapse runs of blank lines.
|
||||
|
||||
} else if (($format === 2) && ($from === 1)) {
|
||||
// Convert 1.x string into 2.x format.
|
||||
$clean = preg_replace("/\n{3,}/", "\n\n\n", $clean); // Collapse runs of blank lines.
|
||||
$clean = preg_replace('/%+/', '%', $clean); // Collapse % characters.
|
||||
$clean = str_replace('\$', '@@@___XXX_ESCAPED_DOLLAR__@@@', $clean); // Remember for later.
|
||||
$clean = str_replace("\\", '', $clean); // Delete all slashes.
|
||||
$clean = preg_replace('/(^|[^{])\$a\b(\->[a-zA-Z0-9_]+)?/', '\\1{$a\\2}', $clean); // Wrap placeholders.
|
||||
$clean = str_replace('@@@___XXX_ESCAPED_DOLLAR__@@@', '$', $clean);
|
||||
$clean = str_replace('$', '$', $clean);
|
||||
|
||||
} else if (($format === 1) && ($from === 1)) {
|
||||
// Sanity legacy 1.x strings.
|
||||
$clean = preg_replace("/\n{3,}/", "\n\n", $clean); // Collapse runs of blank lines.
|
||||
$clean = str_replace('\$', '@@@___XXX_ESCAPED_DOLLAR__@@@', $clean);
|
||||
$clean = str_replace("\\", '', $clean); // Delete all slashes.
|
||||
$clean = str_replace('$', '\$', $clean); // Escape all embedded variables.
|
||||
// Unescape placeholders: only $a and $a->something are allowed. All other $variables are left escaped.
|
||||
$clean = preg_replace('/\\\\\$a\b(\->[a-zA-Z0-9_]+)?/', '$a\\1', $clean); // Unescape placeholders.
|
||||
$clean = str_replace('@@@___XXX_ESCAPED_DOLLAR__@@@', '\$', $clean);
|
||||
$clean = str_replace('"', "\\\"", $clean); // Add slashes for ".
|
||||
$clean = preg_replace('/%+/', '%', $clean); // Collapse % characters.
|
||||
$clean = str_replace('%', '%%', $clean); // Duplicate %.
|
||||
|
||||
} else {
|
||||
throw new moodle_exception('Unknown get_string() format version');
|
||||
}
|
||||
return $clean;
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Language string based on David Mudrak langstring from local_amos.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_customlang\local\mlang;
|
||||
|
||||
use moodle_exception;
|
||||
use stdclass;
|
||||
|
||||
/**
|
||||
* Class containing a lang string cleaned.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a single string
|
||||
*/
|
||||
class logstatus {
|
||||
|
||||
/** @var langstring the current string */
|
||||
public $langstring = null;
|
||||
|
||||
/** @var string the component */
|
||||
public $component = null;
|
||||
|
||||
/** @var string the string ID */
|
||||
public $stringid = null;
|
||||
|
||||
/** @var string the original filename */
|
||||
public $filename = null;
|
||||
|
||||
/** @var int the error level */
|
||||
public $errorlevel = null;
|
||||
|
||||
/** @var string the message identifier */
|
||||
private $message;
|
||||
|
||||
/**
|
||||
* Class creator.
|
||||
*
|
||||
* @param string $message the message identifier to display
|
||||
* @param string $errorlevel the notice level
|
||||
* @param string|null $filename the filename of this log
|
||||
* @param string|null $component the component of this log
|
||||
* @param langstring|null $langstring the langstring of this log
|
||||
*/
|
||||
public function __construct(string $message, string $errorlevel, ?string $filename = null,
|
||||
?string $component = null, ?langstring $langstring = null) {
|
||||
|
||||
$this->filename = $filename;
|
||||
$this->component = $component;
|
||||
$this->langstring = $langstring;
|
||||
$this->message = $message;
|
||||
$this->errorlevel = $errorlevel;
|
||||
|
||||
if ($langstring) {
|
||||
$this->stringid = $langstring->id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the log message.
|
||||
*
|
||||
* @return string the log message.
|
||||
*/
|
||||
public function get_message(): string {
|
||||
return get_string($this->message, 'tool_customlang', $this);
|
||||
}
|
||||
}
|
||||
@@ -1,260 +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/>.
|
||||
|
||||
/**
|
||||
* Mlang PHP based on David Mudrak phpparser for local_amos.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_customlang\local\mlang;
|
||||
|
||||
use coding_exception;
|
||||
use moodle_exception;
|
||||
|
||||
/**
|
||||
* Parser of Moodle strings defined as associative array.
|
||||
*
|
||||
* Moodle core just includes this file format directly as normal PHP code. However
|
||||
* for security reasons, we must not do this for files uploaded by anonymous users.
|
||||
* This parser reconstructs the associative $string array without actually including
|
||||
* the file.
|
||||
*/
|
||||
class phpparser {
|
||||
|
||||
/** @var holds the singleton instance of self */
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Prevents direct creation of object
|
||||
*/
|
||||
private function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent from cloning the instance
|
||||
*/
|
||||
public function __clone() {
|
||||
throw new coding_exception('Cloning os singleton is not allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the singleton instance fo this class
|
||||
*
|
||||
* @return phpparser singleton instance of phpparser
|
||||
*/
|
||||
public static function get_instance(): phpparser {
|
||||
if (is_null(self::$instance)) {
|
||||
self::$instance = new phpparser();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given data in Moodle PHP string format
|
||||
*
|
||||
* Note: This method is adapted from local_amos as it is highly tested and robust.
|
||||
* The priority is keeping it similar to the original one to make it easier to mantain.
|
||||
*
|
||||
* @param string $data definition of the associative array
|
||||
* @param int $format the data format on the input, defaults to the one used since 2.0
|
||||
* @return langstring[] array of langstrings of this file
|
||||
*/
|
||||
public function parse(string $data, int $format = 2): array {
|
||||
$result = [];
|
||||
$strings = $this->extract_strings($data);
|
||||
foreach ($strings as $id => $text) {
|
||||
$cleaned = clean_param($id, PARAM_STRINGID);
|
||||
if ($cleaned !== $id) {
|
||||
continue;
|
||||
}
|
||||
$text = langstring::fix_syntax($text, 2, $format);
|
||||
$result[] = new langstring($id, $text);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Low level parsing method
|
||||
*
|
||||
* Note: This method is adapted from local_amos as it is highly tested and robust.
|
||||
* The priority is keeping it similar to the original one to make it easier to mantain.
|
||||
*
|
||||
* @param string $data
|
||||
* @return string[] the data strings
|
||||
*/
|
||||
protected function extract_strings(string $data): array {
|
||||
|
||||
$strings = []; // To be returned.
|
||||
|
||||
if (empty($data)) {
|
||||
return $strings;
|
||||
}
|
||||
|
||||
// Tokenize data - we expect valid PHP code.
|
||||
$tokens = token_get_all($data);
|
||||
|
||||
// Get rid of all non-relevant tokens.
|
||||
$rubbish = [T_WHITESPACE, T_INLINE_HTML, T_COMMENT, T_DOC_COMMENT, T_OPEN_TAG, T_CLOSE_TAG];
|
||||
foreach ($tokens as $i => $token) {
|
||||
if (is_array($token)) {
|
||||
if (in_array($token[0], $rubbish)) {
|
||||
unset($tokens[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$id = null;
|
||||
$text = null;
|
||||
$line = 0;
|
||||
$expect = 'STRING_VAR'; // The first expected token is '$string'.
|
||||
|
||||
// Iterate over tokens and look for valid $string array assignment patterns.
|
||||
foreach ($tokens as $token) {
|
||||
$foundtype = null;
|
||||
$founddata = null;
|
||||
if (is_array($token)) {
|
||||
$foundtype = $token[0];
|
||||
$founddata = $token[1];
|
||||
if (!empty($token[2])) {
|
||||
$line = $token[2];
|
||||
}
|
||||
|
||||
} else {
|
||||
$foundtype = 'char';
|
||||
$founddata = $token;
|
||||
}
|
||||
|
||||
if ($expect == 'STRING_VAR') {
|
||||
if ($foundtype === T_VARIABLE and $founddata === '$string') {
|
||||
$expect = 'LEFT_BRACKET';
|
||||
continue;
|
||||
} else {
|
||||
// Allow other code at the global level.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($expect == 'LEFT_BRACKET') {
|
||||
if ($foundtype === 'char' and $founddata === '[') {
|
||||
$expect = 'STRING_ID';
|
||||
continue;
|
||||
} else {
|
||||
throw new moodle_exception('Parsing error. Expected character [ at line '.$line);
|
||||
}
|
||||
}
|
||||
|
||||
if ($expect == 'STRING_ID') {
|
||||
if ($foundtype === T_CONSTANT_ENCAPSED_STRING) {
|
||||
$id = $this->decapsulate($founddata);
|
||||
$expect = 'RIGHT_BRACKET';
|
||||
continue;
|
||||
} else {
|
||||
throw new moodle_exception('Parsing error. Expected T_CONSTANT_ENCAPSED_STRING array key at line '.$line);
|
||||
}
|
||||
}
|
||||
|
||||
if ($expect == 'RIGHT_BRACKET') {
|
||||
if ($foundtype === 'char' and $founddata === ']') {
|
||||
$expect = 'ASSIGNMENT';
|
||||
continue;
|
||||
} else {
|
||||
throw new moodle_exception('Parsing error. Expected character ] at line '.$line);
|
||||
}
|
||||
}
|
||||
|
||||
if ($expect == 'ASSIGNMENT') {
|
||||
if ($foundtype === 'char' and $founddata === '=') {
|
||||
$expect = 'STRING_TEXT';
|
||||
continue;
|
||||
} else {
|
||||
throw new moodle_exception('Parsing error. Expected character = at line '.$line);
|
||||
}
|
||||
}
|
||||
|
||||
if ($expect == 'STRING_TEXT') {
|
||||
if ($foundtype === T_CONSTANT_ENCAPSED_STRING) {
|
||||
$text = $this->decapsulate($founddata);
|
||||
$expect = 'SEMICOLON';
|
||||
continue;
|
||||
} else {
|
||||
throw new moodle_exception(
|
||||
'Parsing error. Expected T_CONSTANT_ENCAPSED_STRING array item value at line '.$line
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($expect == 'SEMICOLON') {
|
||||
if (is_null($id) or is_null($text)) {
|
||||
throw new moodle_exception('Parsing error. NULL string id or value at line '.$line);
|
||||
}
|
||||
if ($foundtype === 'char' and $founddata === ';') {
|
||||
if (!empty($id)) {
|
||||
$strings[$id] = $text;
|
||||
}
|
||||
$id = null;
|
||||
$text = null;
|
||||
$expect = 'STRING_VAR';
|
||||
continue;
|
||||
} else {
|
||||
throw new moodle_exception('Parsing error. Expected character ; at line '.$line);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $strings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given one T_CONSTANT_ENCAPSED_STRING, return its value without quotes
|
||||
*
|
||||
* Also processes escaped quotes inside the text.
|
||||
*
|
||||
* Note: This method is taken directly from local_amos as it is highly tested and robust.
|
||||
*
|
||||
* @param string $text value obtained by token_get_all()
|
||||
* @return string value without quotes
|
||||
*/
|
||||
protected function decapsulate(string $text): string {
|
||||
|
||||
if (strlen($text) < 2) {
|
||||
throw new moodle_exception('Parsing error. Expected T_CONSTANT_ENCAPSED_STRING in decapsulate()');
|
||||
}
|
||||
|
||||
if (substr($text, 0, 1) == "'" and substr($text, -1) == "'") {
|
||||
// Single quoted string.
|
||||
$text = trim($text, "'");
|
||||
$text = str_replace("\'", "'", $text);
|
||||
$text = str_replace('\\\\', '\\', $text);
|
||||
return $text;
|
||||
|
||||
} else if (substr($text, 0, 1) == '"' and substr($text, -1) == '"') {
|
||||
// Double quoted string.
|
||||
$text = trim($text, '"');
|
||||
$text = str_replace('\"', '"', $text);
|
||||
$text = str_replace('\\\\', '\\', $text);
|
||||
return $text;
|
||||
|
||||
} else {
|
||||
throw new moodle_exception(
|
||||
'Parsing error. Unexpected quotation in T_CONSTANT_ENCAPSED_STRING in decapsulate(): '.$text
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,9 +57,8 @@ class renderer extends \plugin_renderer_base {
|
||||
protected function render_tool_customlang_menu(\tool_customlang_menu $menu) {
|
||||
$output = '';
|
||||
foreach ($menu->get_items() as $item) {
|
||||
$button = $this->single_button($item->url, $item->title, $item->method);
|
||||
$output .= $this->box($button, 'menu');
|
||||
$output .= $this->single_button($item->url, $item->title, $item->method);
|
||||
}
|
||||
return $output;
|
||||
return $this->box($output, 'menu');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,135 +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/>.
|
||||
|
||||
/**
|
||||
* Export custom language strings to zip files.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @subpackage customlang
|
||||
* @copyright 2020 Thomas Wedekind <thomas.wedekind@univie.ac.at>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('CLI_SCRIPT', true);
|
||||
|
||||
require(__DIR__ . '/../../../../config.php');
|
||||
require_once("$CFG->libdir/clilib.php");
|
||||
require_once("$CFG->dirroot/$CFG->admin/tool/customlang/locallib.php");
|
||||
|
||||
$usage = <<<EOF
|
||||
"Export custom language files to a target folder.
|
||||
Useful for uploading custom langstrings to AMOS or importing or syncing them to other moodle instances.
|
||||
|
||||
Options:
|
||||
-l, --lang Comma seperated language ids to export, default: all
|
||||
-c, --components Comma seperated components to export, default: all
|
||||
-t, --target Target to copy the zip files to, default: $CFG->tempdir/customlang
|
||||
-o, --overwrite Overwrite existing files in the target folder.
|
||||
Note: If the target is not set, the files are always overwritten!
|
||||
-h, --help Print out this help
|
||||
|
||||
Examples:
|
||||
Export all custom language files to the default folder:
|
||||
\$ sudo -u www-data /usr/bin/php admin/tool/customlang/cli/export.php
|
||||
|
||||
Export just the english files of moodle core and the activity 'quiz' in a subfolder in my home folder:
|
||||
\$ sudo -u www-data /usr/bin/php admin/tool/customlang/cli/export.php --lang='en' --components='moodle,quiz' --target='~/customdir'
|
||||
|
||||
EOF;
|
||||
|
||||
$dafaulttarget = "$CFG->tempdir/customlang/";
|
||||
|
||||
// Now get cli options.
|
||||
list($options, $unrecognized) = cli_get_params(
|
||||
[
|
||||
'lang' => '',
|
||||
'components' => '',
|
||||
'target' => $dafaulttarget,
|
||||
'overwrite' => false,
|
||||
'help' => false,
|
||||
],
|
||||
['h' => 'help', 'c' => 'components', 't' => 'target', 'o' => 'overwrite']
|
||||
);
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
|
||||
}
|
||||
|
||||
if ($options['help']) {
|
||||
echo $usage;
|
||||
die;
|
||||
}
|
||||
if (!file_exists($options['target'])) {
|
||||
mkdir($options['target'], 0777, true);
|
||||
}
|
||||
|
||||
cli_writeln(get_string('cliexportheading', 'tool_customlang'));
|
||||
$langs = [];
|
||||
if ($options['lang']) {
|
||||
$langs = explode(',', $options['lang']);
|
||||
} else {
|
||||
// No language set. We export all installed languages.
|
||||
$langs = array_keys(get_string_manager()->get_list_of_translations(true));
|
||||
}
|
||||
|
||||
foreach ($langs as $lang) {
|
||||
$filename = $options['target'] . get_string('exportzipfilename', 'tool_customlang', ['lang' => $lang]);
|
||||
// If the file exists and we are not using the temp folder it requires an ovewrite.
|
||||
if ($options['target'] != $dafaulttarget && file_exists($filename) && !$options['overwrite']) {
|
||||
cli_problem(get_string('cliexportfileexists', 'tool_customlang', $lang));
|
||||
continue;
|
||||
}
|
||||
cli_heading(get_string('cliexportstartexport', 'tool_customlang', $lang));
|
||||
$langdir = tool_customlang_utils::get_localpack_location($lang);
|
||||
if (!file_exists($langdir)) {
|
||||
// No custom files set for this language set.
|
||||
cli_writeln(get_string('cliexportnofilefoundforlang', 'tool_customlang', ['lang' => $lang]));
|
||||
continue;
|
||||
}
|
||||
$zipper = get_file_packer();
|
||||
$tempzip = tempnam($CFG->tempdir . '/', 'tool_customlang_export');
|
||||
$filelist = [];
|
||||
if ($options['components']) {
|
||||
$components = explode(',', $options['components']);
|
||||
foreach ($components as $component) {
|
||||
$filepath = "$langdir/$component.php";
|
||||
if (file_exists($filepath)) {
|
||||
$filelist["$component.php"] = $filepath;
|
||||
} else {
|
||||
cli_problem(
|
||||
get_string('cliexportfilenotfoundforcomponent', 'tool_customlang', ['lang' => $lang, 'file' => $filepath])
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$langfiles = scandir($langdir);
|
||||
foreach ($langfiles as $file) {
|
||||
if (substr($file, 0, 1) != '.') {
|
||||
$filelist[$file] = "$langdir/$file";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($filelist)) {
|
||||
cli_problem(get_string('cliexportnofilefoundforlang', 'tool_customlang', ['lang' => $lang]));
|
||||
continue;
|
||||
}
|
||||
if ($zipper->archive_to_pathname($filelist, $filename)) {
|
||||
cli_writeln(get_string('cliexportzipdone', 'tool_customlang', $filename));
|
||||
} else {
|
||||
cli_problem(get_string('cliexportzipfail', 'tool_customlang', $filename));
|
||||
}
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* CLI customlang import tool.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use tool_customlang\local\importer;
|
||||
use core\output\notification;
|
||||
|
||||
define('CLI_SCRIPT', true);
|
||||
|
||||
require(__DIR__ . '/../../../../config.php');
|
||||
require_once($CFG->dirroot.'/'.$CFG->admin.'/tool/customlang/locallib.php');
|
||||
require_once("$CFG->libdir/clilib.php");
|
||||
|
||||
$usage =
|
||||
"Import lang customization.
|
||||
|
||||
It can get a single file or a folder.
|
||||
If no lang is provided it will try to infere from the filename
|
||||
|
||||
Options:
|
||||
--lang The target language (will get from filename if not provided)
|
||||
--source=path File or folder of the custom lang files (zip or php files)
|
||||
--mode What string should be imported. Options are:
|
||||
- all: all string will be imported (default)
|
||||
- new: only string with no previous customisation
|
||||
- update: only strings already modified
|
||||
--checkin Save strings to the language pack
|
||||
-h, --help Print out this help
|
||||
|
||||
Examples:
|
||||
\$ sudo -u www-data /usr/bin/php admin/tool/customlang/cli/import.php --lang=en --source=customlangs.zip
|
||||
|
||||
\$ sudo -u www-data /usr/bin/php admin/tool/customlang/cli/import.php --source=/tmp/customlangs --checkin
|
||||
|
||||
\$ sudo -u www-data /usr/bin/php admin/tool/customlang/cli/import.php --lang=en --source=/tmp/customlangs
|
||||
|
||||
";
|
||||
|
||||
list($options, $unrecognized) = cli_get_params(
|
||||
[
|
||||
'help' => false,
|
||||
'lang' => false,
|
||||
'source' => false,
|
||||
'mode' => 'all',
|
||||
'checkin' => false,
|
||||
],
|
||||
['h' => 'help']
|
||||
);
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
|
||||
}
|
||||
|
||||
if ($options['help']) {
|
||||
cli_write($usage);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$source = $options['source'] ?? null;
|
||||
$lang = $options['lang'] ?? null;
|
||||
$modeparam = $options['mode'] ?? 'all';
|
||||
$checkin = $options['checkin'] ?? false;
|
||||
|
||||
$modes = [
|
||||
'all' => importer::IMPORTALL,
|
||||
'update' => importer::IMPORTUPDATE,
|
||||
'new' => importer::IMPORTNEW,
|
||||
];
|
||||
if (!isset($modes[$modeparam])) {
|
||||
cli_error(get_string('climissingmode', 'tool_customlang'));
|
||||
}
|
||||
$mode = $modes[$modeparam];
|
||||
|
||||
if (empty($source)) {
|
||||
$source = $CFG->dataroot.'/temp/customlang';
|
||||
}
|
||||
|
||||
if (!file_exists($source)) {
|
||||
cli_error(get_string('climissingsource', 'tool_customlang'));
|
||||
}
|
||||
|
||||
// Emulate normal session - we use admin account by default.
|
||||
cron_setup_user();
|
||||
|
||||
// Get the file list.
|
||||
$files = [];
|
||||
$langfiles = [];
|
||||
|
||||
if (is_file($source)) {
|
||||
$files[] = $source;
|
||||
}
|
||||
if (is_dir($source)) {
|
||||
$filelist = glob("$source/*");
|
||||
foreach ($filelist as $filename) {
|
||||
$files[] = "$filename";
|
||||
}
|
||||
}
|
||||
|
||||
$countfiles = 0;
|
||||
foreach ($files as $filepath) {
|
||||
// Try to get the lang.
|
||||
$filelang = $lang;
|
||||
// Get component from filename.
|
||||
$pathparts = pathinfo($filepath);
|
||||
$filename = $pathparts['filename'];
|
||||
$extension = $pathparts['extension'];
|
||||
if ($extension == 'zip') {
|
||||
if (!$filelang) {
|
||||
// Try to get the lang from the filename.
|
||||
if (strrpos($filename, 'customlang_') === 0) {
|
||||
$parts = explode('_', $filename);
|
||||
if (!empty($parts[1])) {
|
||||
$filelang = $parts[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ($extension != 'php') {
|
||||
// Ignore any other file extension.
|
||||
continue;
|
||||
}
|
||||
if (empty($filelang)) {
|
||||
cli_error(get_string('climissinglang', 'tool_customlang'));
|
||||
}
|
||||
if (!isset($langfiles[$filelang])) {
|
||||
$langfiles[$filelang] = [];
|
||||
}
|
||||
$langfiles[$filelang][] = $filepath;
|
||||
$countfiles ++;
|
||||
}
|
||||
|
||||
if (!$countfiles) {
|
||||
cli_error(get_string('climissingfiles', 'tool_customlang'));
|
||||
}
|
||||
|
||||
foreach ($langfiles as $lng => $files) {
|
||||
$importer = new importer($lng, $mode);
|
||||
$storedfiles = [];
|
||||
$fs = get_file_storage();
|
||||
|
||||
cli_heading(get_string('clifiles', 'tool_customlang', $lng));
|
||||
|
||||
foreach ($files as $file) {
|
||||
// Generate a valid stored_file from this file.
|
||||
$record = (object)[
|
||||
'filearea' => 'draft',
|
||||
'component' => 'user',
|
||||
'filepath' => '/',
|
||||
'itemid' => file_get_unused_draft_itemid(),
|
||||
'license' => $CFG->sitedefaultlicense,
|
||||
'author' => '',
|
||||
'filename' => clean_param(basename($file), PARAM_FILE),
|
||||
'contextid' => \context_user::instance($USER->id)->id,
|
||||
'userid' => $USER->id,
|
||||
];
|
||||
cli_writeln($file);
|
||||
$storedfiles[] = $fs->create_file_from_pathname($record, $file);
|
||||
}
|
||||
cli_writeln("");
|
||||
|
||||
// Import files.
|
||||
cli_heading(get_string('cliimporting', 'tool_customlang', $modeparam));
|
||||
$importer->import($storedfiles);
|
||||
// Display logs.
|
||||
$log = $importer->get_log();
|
||||
if (empty($log)) {
|
||||
cli_problem(get_string('clinolog', 'tool_customlang', $lng));
|
||||
}
|
||||
foreach ($log as $message) {
|
||||
if ($message->errorlevel == notification::NOTIFY_ERROR) {
|
||||
cli_problem($message->get_message());
|
||||
} else {
|
||||
cli_writeln($message->get_message());
|
||||
}
|
||||
}
|
||||
// Do the checkin if necessary.
|
||||
if ($checkin) {
|
||||
tool_customlang_utils::checkin($lng);
|
||||
cli_writeln(get_string('savecheckin', 'tool_customlang'));
|
||||
}
|
||||
cli_writeln("");
|
||||
}
|
||||
|
||||
exit(0);
|
||||
@@ -46,14 +46,5 @@ $capabilities = array(
|
||||
'manager' => CAP_ALLOW
|
||||
),
|
||||
),
|
||||
/* allows the user to export the current language customization */
|
||||
'tool/customlang:export' => array(
|
||||
'riskbitmask' => RISK_CONFIG,
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'archetypes' => array(
|
||||
'manager' => CAP_ALLOW
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
@@ -1,68 +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/>.
|
||||
|
||||
/**
|
||||
* Performs the custom lang export.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @subpackage customlang
|
||||
* @copyright 2020 Thomas Wedekind <thomas.wedekind@univie.ac.at>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require(__DIR__ . '/../../../config.php');
|
||||
require_once($CFG->dirroot.'/'.$CFG->admin.'/tool/customlang/locallib.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
global $PAGE, $CFG;
|
||||
|
||||
require_login(SITEID, false);
|
||||
require_capability('tool/customlang:export', context_system::instance());
|
||||
|
||||
$lng = required_param('lng', PARAM_LANG);
|
||||
|
||||
admin_externalpage_setup('toolcustomlang', '', null,
|
||||
new moodle_url('/admin/tool/customlang/import.php', ['lng' => $lng]));
|
||||
|
||||
$form = new \tool_customlang\form\export(null, ['lng' => $lng]);
|
||||
|
||||
if ($form->is_cancelled()) {
|
||||
redirect('index.php');
|
||||
die();
|
||||
} else if ($formdata = $form->get_data()) {
|
||||
$tempzip = tempnam($CFG->tempdir . '/', 'tool_customlang_export');
|
||||
$filelist = [];
|
||||
foreach ($formdata->files as $file) {
|
||||
$filepath = tool_customlang_utils::get_localpack_location($lng). '/' . $file;
|
||||
if (file_exists($filepath)) {
|
||||
$filelist[$file] = $filepath;
|
||||
}
|
||||
}
|
||||
$zipper = new zip_packer();
|
||||
|
||||
if (!empty($filelist) && $zipper->archive_to_pathname($filelist, $tempzip)) {
|
||||
// Filename include the lang name so the file can be imported with automatic language detection.
|
||||
send_temp_file($tempzip, "customlang_$lng.zip");
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
$output = $PAGE->get_renderer('tool_customlang');
|
||||
|
||||
echo $output->header();
|
||||
echo $output->heading(get_string('pluginname', 'tool_customlang'));
|
||||
$form->display();
|
||||
echo $OUTPUT->footer();
|
||||
@@ -32,6 +32,7 @@ class tool_customlang_filter_form extends moodleform {
|
||||
|
||||
function definition() {
|
||||
$mform = $this->_form;
|
||||
$current = $this->_customdata['current'];
|
||||
|
||||
$mform->addElement('header', 'filtersettings', get_string('filter', 'tool_customlang'));
|
||||
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Import custom lang files.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @subpackage customlang
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use tool_customlang\form\import;
|
||||
use tool_customlang\local\importer;
|
||||
|
||||
require(__DIR__ . '/../../../config.php');
|
||||
require_once($CFG->dirroot.'/'.$CFG->admin.'/tool/customlang/locallib.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
require_login(SITEID, false);
|
||||
require_capability('tool/customlang:edit', context_system::instance());
|
||||
|
||||
$lng = required_param('lng', PARAM_LANG);
|
||||
|
||||
admin_externalpage_setup('toolcustomlang', '', null,
|
||||
new moodle_url('/admin/tool/customlang/import.php', ['lng' => $lng]));
|
||||
|
||||
$output = $PAGE->get_renderer('tool_customlang');
|
||||
|
||||
$form = new import(null, ['lng' => $lng]);
|
||||
if ($data = $form->get_data()) {
|
||||
require_sesskey();
|
||||
|
||||
// Get the file from the users draft area.
|
||||
$usercontext = context_user::instance($USER->id);
|
||||
$fs = get_file_storage();
|
||||
$files = $fs->get_area_files($usercontext->id, 'user', 'draft', $data->pack, 'id',
|
||||
false);
|
||||
|
||||
// Send files to the importer.
|
||||
$importer = new importer($data->lng, $data->importmode);
|
||||
$importer->import($files);
|
||||
|
||||
echo $output->header();
|
||||
|
||||
// Display logs.
|
||||
$log = $importer->get_log();
|
||||
foreach ($log as $message) {
|
||||
echo $output->notification($message->get_message(), $message->errorlevel);
|
||||
}
|
||||
|
||||
// Show continue button.
|
||||
echo $output->continue_button(new moodle_url('index.php', array('lng' => $lng)));
|
||||
|
||||
} else {
|
||||
echo $output->header();
|
||||
|
||||
$form->display();
|
||||
}
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
@@ -35,7 +35,6 @@ require_capability('tool/customlang:view', context_system::instance());
|
||||
$action = optional_param('action', '', PARAM_ALPHA);
|
||||
$confirm = optional_param('confirm', false, PARAM_BOOL);
|
||||
$lng = optional_param('lng', '', PARAM_LANG);
|
||||
$next = optional_param('next', 'edit', PARAM_ALPHA);
|
||||
|
||||
admin_externalpage_setup('toolcustomlang');
|
||||
$langs = get_string_manager()->get_list_of_translations();
|
||||
@@ -60,10 +59,11 @@ if ($action === 'checkout') {
|
||||
raise_memory_limit(MEMORY_EXTRA);
|
||||
tool_customlang_utils::checkout($lng, $progressbar);
|
||||
|
||||
echo $output->continue_button(new moodle_url("/admin/tool/customlang/{$next}.php", array('lng' => $lng)), 'get');
|
||||
echo $output->continue_button(new moodle_url('/admin/tool/customlang/edit.php', array('lng' => $lng)), 'get');
|
||||
echo $output->footer();
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'checkin') {
|
||||
require_sesskey();
|
||||
require_capability('tool/customlang:edit', context_system::instance());
|
||||
@@ -132,21 +132,6 @@ if (has_capability('tool/customlang:edit', context_system::instance())) {
|
||||
'method' => 'post',
|
||||
);
|
||||
}
|
||||
$menu['import'] = array(
|
||||
'title' => get_string('import', 'tool_customlang'),
|
||||
'url' => new moodle_url($PAGE->url, ['action' => 'checkout', 'lng' => $lng, 'next' => 'import']),
|
||||
'method' => 'post',
|
||||
);
|
||||
}
|
||||
if (has_capability('tool/customlang:export', context_system::instance())) {
|
||||
$langdir = tool_customlang_utils::get_localpack_location($lng);
|
||||
if (check_dir_exists(dirname($langdir)) && count(glob("$langdir/*"))) {
|
||||
$menu['export'] = [
|
||||
'title' => get_string('export', 'tool_customlang'),
|
||||
'url' => new moodle_url("/admin/tool/customlang/export.php", ['lng' => $lng]),
|
||||
'method' => 'post',
|
||||
];
|
||||
}
|
||||
}
|
||||
echo $output->render(new tool_customlang_menu($menu));
|
||||
|
||||
|
||||
@@ -30,26 +30,9 @@ $string['checkin'] = 'Save strings to language pack';
|
||||
$string['checkout'] = 'Open language pack for editing';
|
||||
$string['checkoutdone'] = 'Language pack loaded';
|
||||
$string['checkoutinprogress'] = 'Loading language pack';
|
||||
$string['cliexportfileexists'] = 'File for {$a->lang} already exists, skipping. If you want to overwrite add the --override=true option.';
|
||||
$string['cliexportheading'] = 'Starting to export lang files.';
|
||||
$string['cliexportnofilefoundforlang'] = 'No file found to export. Skipping export for this language.';
|
||||
$string['cliexportfilenotfoundforcomponent'] = 'File {$a->filepath} not found for language {$a->lang}.Skipping this file.';
|
||||
$string['cliexportstartexport'] = 'Exporting language "{$a}"';
|
||||
$string['cliexportzipdone'] = 'Zip created: {$a}';
|
||||
$string['cliexportzipfail'] = 'Cannot create zip {$a}';
|
||||
$string['clifiles'] = 'Files to import into {$a}';
|
||||
$string['cliimporting'] = 'Import files string (mode {$a})';
|
||||
$string['clinolog'] = 'Nothing to import into {$a}';
|
||||
$string['climissinglang'] = 'Missing language';
|
||||
$string['climissingfiles'] = 'Missing valid files';
|
||||
$string['climissingmode'] = 'Missing or invalid mode (valid is all, new or update)';
|
||||
$string['climissingsource'] = 'Missing file or folder';
|
||||
$string['confirmcheckin'] = 'You are about to save modifications to your local language pack. This will export the customised strings from the translator into your site data directory and your site will start using the modified strings. Press \'Continue\' to proceed with saving.';
|
||||
$string['customlang:edit'] = 'Edit local translation';
|
||||
$string['customlang:export'] = 'Export local translation';
|
||||
$string['customlang:view'] = 'View local translation';
|
||||
$string['export'] = 'Export custom strings';
|
||||
$string['exportfilter'] = 'Select component(s) to export';
|
||||
$string['filter'] = 'Filter strings';
|
||||
$string['filtercomponent'] = 'Show strings of these components';
|
||||
$string['filtercustomized'] = 'Customised only';
|
||||
@@ -62,24 +45,11 @@ $string['headingcomponent'] = 'Component';
|
||||
$string['headinglocal'] = 'Local customisation';
|
||||
$string['headingstandard'] = 'Standard text';
|
||||
$string['headingstringid'] = 'String';
|
||||
$string['import'] = 'Import custom strings';
|
||||
$string['import_mode'] = 'Import mode';
|
||||
$string['import_new'] = 'Create only strings without local customisation';
|
||||
$string['import_update'] = 'Update only strings with local customisation';
|
||||
$string['import_all'] = 'Create or update all strings from the component(s)';
|
||||
$string['importfile'] = 'Import file';
|
||||
$string['langpack'] = 'Language component(s)';
|
||||
$string['markinguptodate'] = 'Marking the customisation as up-to-date';
|
||||
$string['markinguptodate_help'] = 'The customised translation may get outdated if either the English original or the master translation has modified since the string was customised on your site. Review the customised translation. If you find it up-to-date, click the checkbox. Edit it otherwise.';
|
||||
$string['markuptodate'] = 'mark as up-to-date';
|
||||
$string['modifiedno'] = 'There are no modified strings to save.';
|
||||
$string['modifiednum'] = 'There are {$a} modified strings. Do you wish to save these changes to your local language pack?';
|
||||
$string['nolocallang'] = 'No local strings found.';
|
||||
$string['notice_ignorenew'] = 'Ignoring string {$a->component}/{$a->stringid} because it is not customised.';
|
||||
$string['notice_ignoreupdate'] = 'Ignoring string {$a->component}/{$a->stringid} because it is already defined.';
|
||||
$string['notice_inexitentstring'] = 'String {$a->component}/{$a->stringid} not found.';
|
||||
$string['notice_missingcomponent'] = 'Missing component {$a->component}.';
|
||||
$string['notice_success'] = 'String {$a->component}/{$a->stringid} updated successfully.';
|
||||
$string['nostringsfound'] = 'No strings found, please modify the filter settings';
|
||||
$string['placeholder'] = 'Placeholders';
|
||||
$string['placeholder_help'] = 'Placeholders are special statements like `{$a}` or `{$a->something}` within the string. They are replaced with a value when the string is actually printed.
|
||||
|
||||
@@ -243,7 +243,7 @@ class tool_customlang_utils {
|
||||
* @param string $lang language code
|
||||
* @return string full path
|
||||
*/
|
||||
public static function get_localpack_location($lang) {
|
||||
protected static function get_localpack_location($lang) {
|
||||
global $CFG;
|
||||
|
||||
return $CFG->langlocalroot.'/'.$lang.'_local';
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<input type="hidden" name="sesskey" value="{{{ sesskey }}}">
|
||||
<input type="hidden" name="p" value="{{ currentpage }}">
|
||||
|
||||
<fieldset class="m-3">
|
||||
<fieldset class="m-a-1 m-3">
|
||||
<button type="submit" name="savecontinue" class="btn btn-secondary">
|
||||
{{#str}}savecontinue, tool_customlang{{/str}}
|
||||
</button>
|
||||
@@ -70,7 +70,7 @@
|
||||
|
||||
<div class="list-group">
|
||||
<div class="container-fluid d-none d-md-block list-group-item border-bottom-0">
|
||||
<div class="row">
|
||||
<div class="row-fluid">
|
||||
<div class="col-sm-4 col-md-2">
|
||||
<strong>{{#str}}headingcomponent, tool_customlang{{/str}}</strong>
|
||||
</div>
|
||||
@@ -81,7 +81,7 @@
|
||||
<strong>{{#str}}headingstandard, tool_customlang{{/str}}</strong>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<span class="pl-3">
|
||||
<span class="p-l-1 pl-3">
|
||||
<strong>{{#str}}headinglocal, tool_customlang{{/str}}</strong>
|
||||
</span>
|
||||
</div>
|
||||
@@ -96,7 +96,7 @@
|
||||
{{#outdated}}list-group-item-warning{{/outdated}}
|
||||
{{#modified}}list-group-item-info{{/modified}}"
|
||||
>
|
||||
<div class="row">
|
||||
<div class="row-fluid ">
|
||||
<div class="col-sm-4 col-md-2">
|
||||
<div class="d-md-none">
|
||||
<strong>{{#str}}headingcomponent, tool_customlang{{/str}}</strong>
|
||||
@@ -129,8 +129,8 @@
|
||||
<strong>{{#str}}headinglocal, tool_customlang{{/str}}</strong>
|
||||
</div>
|
||||
<div class="py-2 py-md-0 px-md-3">
|
||||
<label for="{{id}}" class="sr-only sr-only-focusable">{{{ component }}}/{{{ stringid }}}</label>
|
||||
<textarea class="form-control w-100 border-box" id="{{id}}" name="cust[{{id}}]" cols="40" rows="3">{{{ local }}}</textarea>
|
||||
<textarea class="form-control w-100 border-box" name="cust[{{id}}]" cols="40" rows="3">{{{ local }}}</textarea>
|
||||
|
||||
{{#checkupdated}}
|
||||
<div class="uptodatewrapper">
|
||||
<div class="form-check">
|
||||
@@ -147,7 +147,7 @@
|
||||
{{/strings}}
|
||||
</div>
|
||||
|
||||
<fieldset class="m-3">
|
||||
<fieldset class="m-a-1 m-3">
|
||||
<button type="submit" name="savecontinue" class="btn btn-secondary">
|
||||
{{#str}}savecontinue, tool_customlang{{/str}}
|
||||
</button>
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
@tool @tool_customlang
|
||||
Feature: Within a moodle instance, an administrator should be able to modify langstrings for the entire Moodle installation.
|
||||
In order to change langstrings in the adminsettings of the instance,
|
||||
As an admin
|
||||
I need to be able to access and change values in the the language customisation of the language pack.
|
||||
|
||||
Background:
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language customisation" in site administration
|
||||
And I set the field "lng" to "en"
|
||||
And I press "Open language pack for editing"
|
||||
And I press "Continue"
|
||||
And I set the field "Show strings of these components" to "moodle.php"
|
||||
And I set the field "String identifier" to "administrationsite"
|
||||
And I press "Show strings"
|
||||
And I set the field "core/administrationsite" to "Custom string example"
|
||||
|
||||
@javascript
|
||||
Scenario: Edit an string but don't save it to lang pack.
|
||||
When I press "Apply changes and continue editing"
|
||||
Then I should see "Site administration" in the "page-header" "region"
|
||||
And I should not see "Custom string example" in the "page-header" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Customize an string as admin and save it to lang pack.
|
||||
Given I press "Save changes to the language pack"
|
||||
And I should see "There are 1 modified strings."
|
||||
When I click on "Continue" "button"
|
||||
Then I should see "Custom string example" in the "page-header" "region"
|
||||
And I should not see "Site administration" in the "page-header" "region"
|
||||
@@ -1,49 +0,0 @@
|
||||
@tool @tool_customlang
|
||||
Feature: Within a moodle instance, an administrator should be able to export modified langstrings.
|
||||
In order to export modified langstrings in the adminsettings of the instance,
|
||||
As an admin
|
||||
I need to be able to export the php-files of the language customisation of a language.
|
||||
|
||||
@javascript
|
||||
Scenario: Export button should not appear if no customization is made
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language customisation" in site administration
|
||||
And I set the field "lng" to "en"
|
||||
Then I should see "Open language pack for editing"
|
||||
And I should not see "Export custom strings"
|
||||
|
||||
@javascript
|
||||
Scenario: Export button should not appear if no customization is saved into langpack
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language customisation" in site administration
|
||||
And I set the field "lng" to "en"
|
||||
And I press "Open language pack for editing"
|
||||
And I press "Continue"
|
||||
And I set the field "Show strings of these components" to "moodle.php"
|
||||
And I set the field "String identifier" to "accept"
|
||||
And I press "Show strings"
|
||||
And I set the field "core/accept" to "Accept-custom_export"
|
||||
When I press "Apply changes and continue editing"
|
||||
And I navigate to "Language > Language customisation" in site administration
|
||||
And I set the field "lng" to "en"
|
||||
Then I should see "Open language pack for editing"
|
||||
And I should see "There are 1 modified strings."
|
||||
And I should not see "Export custom strings"
|
||||
|
||||
@javascript
|
||||
Scenario: Export the php-file including a customised langstring.
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language customisation" in site administration
|
||||
And I set the field "lng" to "en"
|
||||
And I press "Open language pack for editing"
|
||||
And I press "Continue"
|
||||
And I set the field "Show strings of these components" to "moodle.php"
|
||||
And I set the field "String identifier" to "accept"
|
||||
And I press "Show strings"
|
||||
And I set the field "core/accept" to "Accept-custom_export"
|
||||
When I press "Save changes to the language pack"
|
||||
And I should see "There are 1 modified strings."
|
||||
And I click on "Continue" "button"
|
||||
Then I set the field "lng" to "en"
|
||||
And I click on "Export custom strings" "button"
|
||||
And I set the field "Select component(s) to export" to "moodle.php"
|
||||
@@ -1,48 +0,0 @@
|
||||
@tool @tool_customlang @_file_upload
|
||||
Feature: Within a moodle instance, an administrator should be able to import modified langstrings.
|
||||
In order to import modified langstrings in the adminsettings from one to another instance,
|
||||
As an admin
|
||||
I need to be able to import the zips and php files of the language customisation of a language.
|
||||
|
||||
Background:
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language customisation" in site administration
|
||||
And I set the field "lng" to "en"
|
||||
And I click on "Import custom strings" "button"
|
||||
And I press "Continue"
|
||||
|
||||
@javascript
|
||||
Scenario: Import a PHP file to add a new core lang customization
|
||||
When I upload "admin/tool/customlang/tests/fixtures/tool_customlang.php" file to "Language component(s)" filemanager
|
||||
And I press "Import file"
|
||||
Then I should see "String tool_customlang/pluginname updated successfully."
|
||||
And I should see "String tool_customlang/nonexistentinvetedstring not found."
|
||||
And I click on "Continue" "button"
|
||||
And I should see "There are 1 modified strings."
|
||||
And I click on "Save strings to language pack" "button"
|
||||
And I click on "Continue" "button"
|
||||
And I should see "An amazing import feature" in the "page-header" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Try to import a PHP file from a non existent component
|
||||
When I upload "admin/tool/customlang/tests/fixtures/mod_fakecomponent.php" file to "Language component(s)" filemanager
|
||||
And I press "Import file"
|
||||
Then I should see "Missing component mod_fakecomponent."
|
||||
|
||||
@javascript
|
||||
Scenario: Import a zip file with some PHP files in it.
|
||||
When I upload "admin/tool/customlang/tests/fixtures/customlang.zip" file to "Language component(s)" filemanager
|
||||
And I press "Import file"
|
||||
Then I should see "String core/administrationsite updated successfully."
|
||||
And I should see "String core/language updated successfully."
|
||||
And I should see "String core/nonexistentinvetedstring not found."
|
||||
And I should see "String tool_customlang/pluginname updated successfully."
|
||||
And I should see "String tool_customlang/nonexistentinvetedstring not found."
|
||||
And I should see "Missing component mod_fakecomponent."
|
||||
And I click on "Continue" "button"
|
||||
And I should see "There are 3 modified strings."
|
||||
And I click on "Save strings to language pack" "button"
|
||||
And I click on "Continue" "button"
|
||||
And I should see "Uploaded custom string" in the "page-header" "region"
|
||||
And I should see "Another Uploaded string" in the "page-header" "region"
|
||||
And I should see "An amazing import feature" in the "page-header" "region"
|
||||
@@ -1,81 +0,0 @@
|
||||
@tool @tool_customlang @_file_upload
|
||||
Feature: Within a moodle instance, an administrator should be able to import langstrings with several modes.
|
||||
In order to import modified langstrings in the adminsettings from one to another instance,
|
||||
As an admin
|
||||
I need to be able to import only some language customisation strings depending on some conditions.
|
||||
|
||||
Background:
|
||||
# Add one customization.
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Language > Language customisation" in site administration
|
||||
And I set the field "lng" to "en"
|
||||
And I press "Open language pack for editing"
|
||||
And I press "Continue"
|
||||
And I set the field "Show strings of these components" to "moodle.php"
|
||||
And I set the field "String identifier" to "administrationsite"
|
||||
And I press "Show strings"
|
||||
And I set the field "core/administrationsite" to "Custom string example"
|
||||
And I press "Save changes to the language pack"
|
||||
And I should see "There are 1 modified strings."
|
||||
And I click on "Continue" "button"
|
||||
And I should see "Custom string example" in the "page-header" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Update only customized strings
|
||||
When I set the field "lng" to "en"
|
||||
And I click on "Import custom strings" "button"
|
||||
And I press "Continue"
|
||||
And I upload "admin/tool/customlang/tests/fixtures/moodle.php" file to "Language component(s)" filemanager
|
||||
And I set the field "Import mode" to "Update only strings with local customisation"
|
||||
And I press "Import file"
|
||||
Then I should see "String core/administrationsite updated successfully."
|
||||
And I should see "Ignoring string core/language because it is not customised."
|
||||
And I should see "String core/nonexistentinvetedstring not found."
|
||||
And I click on "Continue" "button"
|
||||
And I should see "There are 1 modified strings."
|
||||
And I should not see "Uploaded custom string" in the "page-header" "region"
|
||||
And I click on "Save strings to language pack" "button"
|
||||
And I click on "Continue" "button"
|
||||
And I should not see "Custom string example" in the "page-header" "region"
|
||||
And I should see "Uploaded custom string" in the "page-header" "region"
|
||||
And I should not see "Another Uploaded string" in the "page-header" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Create only new strings
|
||||
When I set the field "lng" to "en"
|
||||
And I click on "Import custom strings" "button"
|
||||
And I press "Continue"
|
||||
And I upload "admin/tool/customlang/tests/fixtures/moodle.php" file to "Language component(s)" filemanager
|
||||
And I set the field "Import mode" to "Create only strings without local customisation"
|
||||
And I press "Import file"
|
||||
Then I should see "Ignoring string core/administrationsite because it is already defined."
|
||||
And I should see "String core/language updated successfully."
|
||||
And I should see "String core/nonexistentinvetedstring not found."
|
||||
And I click on "Continue" "button"
|
||||
And I should see "There are 1 modified strings."
|
||||
And I should not see "Uploaded custom string" in the "page-header" "region"
|
||||
And I click on "Save strings to language pack" "button"
|
||||
And I click on "Continue" "button"
|
||||
And I should see "Custom string example" in the "page-header" "region"
|
||||
And I should not see "Uploaded custom string" in the "page-header" "region"
|
||||
And I should see "Another Uploaded string" in the "page-header" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Import all strings
|
||||
When I set the field "lng" to "en"
|
||||
And I click on "Import custom strings" "button"
|
||||
And I press "Continue"
|
||||
And I upload "admin/tool/customlang/tests/fixtures/moodle.php" file to "Language component(s)" filemanager
|
||||
And I set the field "Import mode" to "Create or update all strings from the component(s)"
|
||||
And I press "Import file"
|
||||
Then I should see "String core/administrationsite updated successfully."
|
||||
And I should see "String core/language updated successfully."
|
||||
And I should see "String core/nonexistentinvetedstring not found."
|
||||
And I click on "Continue" "button"
|
||||
And I should see "There are 2 modified strings."
|
||||
And I should not see "Uploaded custom string" in the "page-header" "region"
|
||||
And I click on "Save strings to language pack" "button"
|
||||
And I click on "Continue" "button"
|
||||
And I should not see "Custom string example" in the "page-header" "region"
|
||||
And I should see "Uploaded custom string" in the "page-header" "region"
|
||||
And I should see "Another Uploaded string" in the "page-header" "region"
|
||||
Binary file not shown.
@@ -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/>.
|
||||
|
||||
/**
|
||||
* Local language pack.
|
||||
*
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
$string['administrationsite'] = 'Uploaded custom string';
|
||||
$string['language'] = 'Another Uploaded string';
|
||||
$string['nonexistentinvetedstring'] = 'This should not be imported';
|
||||
-28
@@ -1,28 +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/>.
|
||||
|
||||
/**
|
||||
* Local language pack.
|
||||
*
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['administrationsite'] = 'Uploaded custom string';
|
||||
$string['language'] = 'Another Uploaded string';
|
||||
$string['nonexistentinvetedstring'] = 'This should not be imported';
|
||||
@@ -1,28 +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/>.
|
||||
|
||||
/**
|
||||
* Local language pack from http://localhost/m/MDL-69583
|
||||
*
|
||||
* @copyright 2020 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
$string['pluginname'] = 'An amazing import feature';
|
||||
$string['nonexistentinvetedstring'] = 'This string should not be imported';
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,207 +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/>.
|
||||
|
||||
/**
|
||||
* PHP lang parser test.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_customlang\local\mlang;
|
||||
|
||||
use advanced_testcase;
|
||||
use moodle_exception;
|
||||
|
||||
/**
|
||||
* PHP lang parser test class.
|
||||
*
|
||||
* @package tool_customlang
|
||||
* @copyright 2015 Damyon Wiese
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class phpparser_testcase extends advanced_testcase {
|
||||
|
||||
|
||||
/**
|
||||
* Test get instance static method.
|
||||
*
|
||||
*/
|
||||
public function test_get_instance(): void {
|
||||
|
||||
$instance = phpparser::get_instance();
|
||||
|
||||
$this->assertInstanceOf('tool_customlang\local\mlang\phpparser', $instance);
|
||||
$this->assertEquals($instance, phpparser::get_instance());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get instance parse method.
|
||||
*
|
||||
* @dataProvider parse_provider
|
||||
* @param string $phpcode PHP code to test
|
||||
* @param array $expected Expected result
|
||||
* @param bool $exception if an exception is expected
|
||||
*/
|
||||
public function test_parse(string $phpcode, array $expected, bool $exception): void {
|
||||
|
||||
$instance = phpparser::get_instance();
|
||||
|
||||
if ($exception) {
|
||||
$this->expectException(moodle_exception::class);
|
||||
}
|
||||
|
||||
$strings = $instance->parse($phpcode);
|
||||
|
||||
$this->assertEquals(count($expected), count($strings));
|
||||
foreach ($strings as $key => $langstring) {
|
||||
$this->assertEquals($expected[$key][0], $langstring->id);
|
||||
$this->assertEquals($expected[$key][1], $langstring->text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for the test_parse.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function parse_provider() : array {
|
||||
return [
|
||||
'Invalid PHP code' => [
|
||||
'No PHP code', [], false
|
||||
],
|
||||
'No PHP open tag' => [
|
||||
"\$string['example'] = 'text';\n", [], false
|
||||
],
|
||||
'One string code' => [
|
||||
"<?php \$string['example'] = 'text';\n", [['example', 'text']], false
|
||||
],
|
||||
'Extra spaces' => [
|
||||
"<?php \$string['example'] = 'text';\n", [['example', 'text']], false
|
||||
],
|
||||
'Extra tabs' => [
|
||||
"<?php \$string['example']\t=\t'text';\n", [['example', 'text']], false
|
||||
],
|
||||
'Double quote string' => [
|
||||
"<?php
|
||||
\$string['example'] = \"text\";
|
||||
\$string[\"example2\"] = 'text2';
|
||||
\$string[\"example3\"] = \"text3\";
|
||||
", [
|
||||
['example', 'text'],
|
||||
['example2', 'text2'],
|
||||
['example3', 'text3'],
|
||||
], false
|
||||
],
|
||||
'Multiple lines strings' => [
|
||||
"<?php
|
||||
\$string['example'] = 'First line\nsecondline';
|
||||
\$string['example2'] = \"First line\nsecondline2\";
|
||||
", [
|
||||
['example', "First line\nsecondline"],
|
||||
['example2', "First line\nsecondline2"],
|
||||
], false
|
||||
],
|
||||
'Two strings code' => [
|
||||
"<?php
|
||||
\$string['example'] = 'text';
|
||||
\$string['example2'] = 'text2';
|
||||
", [
|
||||
['example', 'text'],
|
||||
['example2', 'text2'],
|
||||
], false
|
||||
],
|
||||
'Scaped characters' => [
|
||||
"<?php
|
||||
\$string['example'] = 'Thos are \\' quotes \" 1';
|
||||
\$string['example2'] = \"Thos are ' quotes \\\" 2\";
|
||||
", [
|
||||
['example', "Thos are ' quotes \" 1"],
|
||||
['example2', "Thos are ' quotes \" 2"],
|
||||
], false
|
||||
],
|
||||
'PHP with single line comments' => [
|
||||
"<?php
|
||||
// This is a comment.
|
||||
\$string['example'] = 'text';
|
||||
// This is another commment.
|
||||
", [
|
||||
['example', 'text'],
|
||||
], false
|
||||
],
|
||||
'PHP with block comments' => [
|
||||
"<?php
|
||||
/* This is a block comment. */
|
||||
\$string['example'] = 'text';
|
||||
/* This is another
|
||||
block comment. */
|
||||
", [
|
||||
['example', 'text'],
|
||||
], false
|
||||
],
|
||||
'Wrong variable name' => [
|
||||
"<?php
|
||||
\$stringwrong['example'] = 'text';
|
||||
\$wringstring['example'] = 'text';
|
||||
", [], false
|
||||
],
|
||||
'Single line commented valid line' => [
|
||||
"<?php
|
||||
// \$string['example'] = 'text';
|
||||
", [], false
|
||||
],
|
||||
'Block commented valid line' => [
|
||||
"<?php
|
||||
/*
|
||||
\$string['example'] = 'text';
|
||||
*/
|
||||
", [], false
|
||||
],
|
||||
'Syntax error 1 (double assignation)' => [
|
||||
"<?php
|
||||
\$string['example'] = 'text' = 'wrong';
|
||||
", [], true
|
||||
],
|
||||
'Syntax error 2 (no closing string)' => [
|
||||
"<?php
|
||||
\$string['example'] = 'wrong;
|
||||
", [], true
|
||||
],
|
||||
'Syntax error 3 (Array without key)' => [
|
||||
"<?php
|
||||
\$string[] = 'wrong';
|
||||
", [], true
|
||||
],
|
||||
'Syntax error 4 (Array not open)' => [
|
||||
"<?php
|
||||
\$string'example'] = 'wrong';
|
||||
", [], true
|
||||
],
|
||||
'Syntax error 5 (Array not closed)' => [
|
||||
"<?php
|
||||
\$string['example' = 'wrong';
|
||||
", [], true
|
||||
],
|
||||
'Syntax error 6 (Missing assignment)' => [
|
||||
"<?php
|
||||
\$string['example'] 'wrong';
|
||||
", [], true
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,6 +25,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2020101300;
|
||||
$plugin->version = 2020061500;
|
||||
$plugin->requires = 2020060900;
|
||||
$plugin->component = 'tool_customlang'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
statuspreprocessing,tool_dataprivacy
|
||||
@@ -344,3 +344,6 @@ $string['role_help'] = 'The role which the override should apply to.';
|
||||
$string['duplicaterole'] = 'Role already specified';
|
||||
$string['purposeoverview'] = 'A purpose describes the intended use and retention policy for stored data. The basis for storing and retaining that data is also described in the purpose.';
|
||||
$string['roleoverrideoverview'] = 'The default retention policy can be overridden for specific user roles, allowing you to specify a longer, or a shorter, retention policy. A user is only expired when all of their roles have expired.';
|
||||
|
||||
// Deprecated since Moodle 3.6.
|
||||
$string['statuspreprocessing'] = 'Pre-processing';
|
||||
|
||||
@@ -50,12 +50,12 @@
|
||||
<hr />
|
||||
<div class="row">
|
||||
{{#compliant}}
|
||||
<a class="component-expand pl-5" data-component="{{raw_component}}" href='#'>
|
||||
<h4 class=" d-inline pl-5 " id="{{raw_component}}">{{#pix}}t/collapsed, moodle, {{#str}}expandplugin, tool_dataprivacy{{/str}}{{/pix}}{{component}}</h4>
|
||||
<a class="component-expand p-l-2" data-component="{{raw_component}}" href='#'>
|
||||
<h4 class=" d-inline p-l-2 " id="{{raw_component}}">{{#pix}}t/collapsed, moodle, {{#str}}expandplugin, tool_dataprivacy{{/str}}{{/pix}}{{component}}</h4>
|
||||
</a>
|
||||
{{/compliant}}
|
||||
{{^compliant}}
|
||||
<h4 class="d-inline pl-6 " id="{{raw_component}}">{{component}}</h4>
|
||||
<h4 class="d-inline p-l-3 " id="{{raw_component}}">{{component}}</h4>
|
||||
<span>{{#pix}}i/risk_xss, moodle, {{#str}}requiresattention, tool_dataprivacy{{/str}}{{/pix}}</span>
|
||||
{{/compliant}}
|
||||
{{#external}}
|
||||
@@ -73,7 +73,7 @@
|
||||
<div class="hide" data-section="{{raw_component}}" aria-expanded="false" role="contentinfo">
|
||||
{{#metadata}}
|
||||
<hr />
|
||||
<div class="pl-6">
|
||||
<div class="p-l-3">
|
||||
<dl class="row">
|
||||
<dt class="col-3">
|
||||
{{#link}}
|
||||
@@ -98,7 +98,7 @@
|
||||
{{/metadata}}
|
||||
{{#nullprovider}}
|
||||
<hr />
|
||||
<div class="pl-6">
|
||||
<div class="p-l-3">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
{{nullprovider}}
|
||||
@@ -108,4 +108,4 @@
|
||||
{{/nullprovider}}
|
||||
</div>
|
||||
{{/compliant}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
<div class="container-fluid mt-2">
|
||||
<div class="row">
|
||||
<div class="col-md-4 pl-0 nav-pills context-tree">
|
||||
<div class="col-md-4 p-l-0 nav-pills context-tree">
|
||||
{{#tree}}
|
||||
{{> tool_dataprivacy/context_tree_node}}
|
||||
{{/tree}}
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<h3 id="{{plugin_type_raw}}">{{#pix}}t/collapsed, moodle, {{#str}}expandplugintype, tool_dataprivacy{{/str}}{{/pix}}{{plugin_type}}</h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="hide pb-3" data-plugintarget="{{plugin_type_raw}}" aria-expanded="false" role="contentinfo">
|
||||
<div class="hide p-b-1" data-plugintarget="{{plugin_type_raw}}" aria-expanded="false" role="contentinfo">
|
||||
{{#plugins}}
|
||||
{{> tool_dataprivacy/component_status}}
|
||||
{{/plugins}}
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
"contextlevel": 70
|
||||
}
|
||||
}}
|
||||
<div class="row rtl-compatible mt-1 mb-1">
|
||||
<div class="row-fluid rtl-compatible mt-1 mb-1">
|
||||
<div class="col-md-9">
|
||||
<div class="row rtl-compatible mt-1 mb-1">
|
||||
<div class="row-fluid rtl-compatible mt-1 mb-1">
|
||||
<div class="col-md-3">
|
||||
<strong>{{#str}}category, tool_dataprivacy{{/str}}</strong>
|
||||
</div>
|
||||
@@ -51,7 +51,7 @@
|
||||
{{category}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row rtl-compatible mt-1 mb-1">
|
||||
<div class="row-fluid rtl-compatible mt-1 mb-1">
|
||||
<div class="col-md-3">
|
||||
<strong>{{#str}}purpose, tool_dataprivacy{{/str}}</strong>
|
||||
</div>
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
{{#contexts}}
|
||||
<div class="card mb-3">
|
||||
<div class="card-header"><h3>{{contextname}}</h3></div>
|
||||
<div class="card-body pl-5 pr-5">
|
||||
<div class="card-body p-l-2 p-r-2">
|
||||
|
||||
{{#category.name}}
|
||||
<h4>{{#str}}category, tool_dataprivacy{{/str}}</h4>
|
||||
@@ -120,4 +120,4 @@
|
||||
</div>
|
||||
</div>
|
||||
{{/contexts}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -997,8 +997,8 @@ class tool_dataprivacy_api_testcase extends advanced_testcase {
|
||||
$this->assertEquals($subject, $message->subject);
|
||||
$this->assertEquals('tool_dataprivacy', $message->component);
|
||||
$this->assertEquals('contactdataprotectionofficer', $message->eventtype);
|
||||
$this->assertStringContainsString(fullname($dpo), $message->fullmessage);
|
||||
$this->assertStringContainsString(fullname($user1), $message->fullmessage);
|
||||
$this->assertContains(fullname($dpo), $message->fullmessage);
|
||||
$this->assertContains(fullname($user1), $message->fullmessage);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,7 +46,7 @@ Feature: Manage data requests
|
||||
And I open the action menu in "John Doe" "table_row"
|
||||
And I should see "View the request"
|
||||
But I should not see "Mark as complete"
|
||||
And I press key "27" in ".moodle-actionmenu" "css_element"
|
||||
And I press the escape key
|
||||
And I open the action menu in "Jane Doe" "table_row"
|
||||
And I choose "Mark as complete" in the open action menu
|
||||
And I should see "Do you really want to mark this user enquiry as complete?"
|
||||
|
||||
@@ -10,16 +10,12 @@ Feature: Manage data storage purposes
|
||||
And I open the action menu in "region-main" "region"
|
||||
And I choose "Purposes" in the open action menu
|
||||
And I press "Add purpose"
|
||||
And I set the field "Name" to "Purpose 1"
|
||||
And I set the field "Description" to "Purpose 1 description"
|
||||
And I click on ".form-autocomplete-downarrow" "css_element" in the "Lawful bases" "form_row"
|
||||
And I click on "Contract (GDPR Art. 6.1(b))" "list_item"
|
||||
And I click on "Legal obligation (GDPR Art 6.1(c))" "list_item"
|
||||
And I press key "27" in the field "Lawful bases"
|
||||
And I click on ".form-autocomplete-downarrow" "css_element" in the "Sensitive personal data processing reasons" "form_row"
|
||||
And I click on "Explicit consent (GDPR Art. 9.2(a))" "list_item"
|
||||
And I press key "27" in the field "Sensitive personal data processing reasons"
|
||||
And I set the field "retentionperiodnumber" to "2"
|
||||
And I set the following fields to these values:
|
||||
| Name | Purpose 1 |
|
||||
| Description | Purpose 1 description |
|
||||
| Lawful bases | Contract (GDPR Art. 6.1(b)),Legal obligation (GDPR Art 6.1(c)) |
|
||||
| Sensitive personal data processing reasons | Explicit consent (GDPR Art. 9.2(a)) |
|
||||
| retentionperiodnumber | 2 |
|
||||
When I press "Save"
|
||||
Then I should see "Purpose 1" in the "List of data purposes" "table"
|
||||
And I should see "Contract (GDPR Art. 6.1(b))" in the "Purpose 1" "table_row"
|
||||
@@ -31,14 +27,13 @@ Feature: Manage data storage purposes
|
||||
Scenario: Update a data storage purpose
|
||||
Given I open the action menu in "Purpose 1" "table_row"
|
||||
And I choose "Edit" in the open action menu
|
||||
And I set the field "Name" to "Purpose 1 edited"
|
||||
And I set the field "Description" to "Purpose 1 description edited"
|
||||
And I click on "Legal obligation (GDPR Art 6.1(c))" "text" in the ".form-autocomplete-selection" "css_element"
|
||||
And I click on ".form-autocomplete-downarrow" "css_element" in the "Lawful bases" "form_row"
|
||||
And I click on "Vital interests (GDPR Art. 6.1(d))" "list_item"
|
||||
And I press key "27" in the field "Lawful bases"
|
||||
And I set the field "retentionperiodnumber" to "3"
|
||||
And I click on "protected" "checkbox"
|
||||
And I set the following fields to these values:
|
||||
| Name | Purpose 1 edited |
|
||||
| Description | Purpose 1 description edited |
|
||||
| Lawful bases | Contract (GDPR Art. 6.1(b)), Vital interests (GDPR Art. 6.1(d)) |
|
||||
| Sensitive personal data processing reasons | Explicit consent (GDPR Art. 9.2(a)) |
|
||||
| retentionperiodnumber | 3 |
|
||||
| protected | 1 |
|
||||
When I press "Save changes"
|
||||
Then I should see "Purpose 1 edited" in the "List of data purposes" "table"
|
||||
And I should see "Purpose 1 description edited" in the "Purpose 1 edited" "table_row"
|
||||
|
||||
@@ -44,7 +44,7 @@ class tool_dataprivacy_expired_data_requests_testcase extends data_privacy_testc
|
||||
/**
|
||||
* Test tearDown.
|
||||
*/
|
||||
public function tearDown(): void {
|
||||
public function tearDown() {
|
||||
\core_privacy\local\request\writer::reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ class tool_dataprivacy_manager_observer_testcase extends data_privacy_testcase {
|
||||
return $message->useridto;
|
||||
}, $messages);
|
||||
|
||||
$this->assertEqualsCanonicalizing(array_keys($dpos), $messageusers);
|
||||
$this->assertEquals(array_keys($dpos), $messageusers, '', 0.0, 0, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -142,7 +142,7 @@ class tool_dataprivacy_privacy_provider_testcase extends provider_testcase {
|
||||
$this->assertEquals($strs->statusrejected, $data[1]->status);
|
||||
$this->assertEquals($strs->creationmanual, $data[1]->creationmethod);
|
||||
$this->assertEmpty($data[1]->comments);
|
||||
$this->assertStringContainsString('Nope', $data[1]->dpocomment);
|
||||
$this->assertContains('Nope', $data[1]->dpocomment);
|
||||
$this->assertNotEmpty($data[1]->timecreated);
|
||||
}
|
||||
|
||||
@@ -184,4 +184,4 @@ class tool_dataprivacy_privacy_provider_testcase extends provider_testcase {
|
||||
|
||||
$this->assertEquals(6, $preferences[helper::PREF_REQUEST_PERPAGE]->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ class tool_dataprivacy_task_testcase extends data_privacy_testcase {
|
||||
/**
|
||||
* Test tearDown.
|
||||
*/
|
||||
public function tearDown(): void {
|
||||
public function tearDown() {
|
||||
\core_privacy\local\request\writer::reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ function tool_dbtransfer_get_drivers() {
|
||||
$dblibrary = $matches[2];
|
||||
|
||||
if ($dbtype === 'sqlite3') {
|
||||
// The sqlite3 driver is not fully working yet and should not be returned.
|
||||
// Blacklist unfinished drivers.
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ class httpsreplace_test extends \advanced_testcase {
|
||||
$finder->upgrade_http_links();
|
||||
|
||||
$summary = $DB->get_field('course', 'summary', ['id' => $course->id]);
|
||||
$this->assertStringContainsString($expectedcontent, $summary);
|
||||
$this->assertContains($expectedcontent, $summary);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,10 +253,10 @@ class httpsreplace_test extends \advanced_testcase {
|
||||
$this->assertCount(0, $results);
|
||||
|
||||
$summary = $DB->get_field('course', 'summary', ['id' => $course->id]);
|
||||
$this->assertStringContainsString('http://intentionally.unavailable/page.php', $summary);
|
||||
$this->assertStringContainsString('http://other.unavailable/page.php', $summary);
|
||||
$this->assertStringNotContainsString('https://intentionally.unavailable', $summary);
|
||||
$this->assertStringNotContainsString('https://other.unavailable', $summary);
|
||||
$this->assertContains('http://intentionally.unavailable/page.php', $summary);
|
||||
$this->assertContains('http://other.unavailable/page.php', $summary);
|
||||
$this->assertNotContains('https://intentionally.unavailable', $summary);
|
||||
$this->assertNotContains('https://other.unavailable', $summary);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,7 +281,7 @@ class httpsreplace_test extends \advanced_testcase {
|
||||
|
||||
$finder->upgrade_http_links();
|
||||
$summary = $DB->get_field('course', 'summary', ['id' => $course->id]);
|
||||
$this->assertStringContainsString($CFG->wwwroot, $summary);
|
||||
$this->assertContains($CFG->wwwroot, $summary);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,10 +298,10 @@ class httpsreplace_test extends \advanced_testcase {
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->assertTrue($results);
|
||||
$this->assertStringNotContainsString('https://somesite', $output);
|
||||
$this->assertNotContains('https://somesite', $output);
|
||||
$testconf = get_config('core', 'test_upgrade_http_links');
|
||||
$this->assertStringContainsString('http://somesite', $testconf);
|
||||
$this->assertStringNotContainsString('https://somesite', $testconf);
|
||||
$this->assertContains('http://somesite', $testconf);
|
||||
$this->assertNotContains('https://somesite', $testconf);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,8 +331,8 @@ class httpsreplace_test extends \advanced_testcase {
|
||||
$finder->upgrade_http_links();
|
||||
|
||||
$summary = $DB->get_field('course', 'summary', ['id' => $course->id]);
|
||||
$this->assertStringContainsString('https://secure.example.com', $summary);
|
||||
$this->assertStringNotContainsString('http://example.com', $summary);
|
||||
$this->assertContains('https://secure.example.com', $summary);
|
||||
$this->assertNotContains('http://example.com', $summary);
|
||||
$this->assertEquals('<script src="https://secure.example.com/test.js">' .
|
||||
'<img src="https://secure.example.com/someimage.png">', $summary);
|
||||
}
|
||||
@@ -401,7 +401,7 @@ class httpsreplace_test extends \advanced_testcase {
|
||||
$finder->upgrade_http_links();
|
||||
|
||||
$record = $DB->get_record('reserved_words_temp', []);
|
||||
$this->assertStringContainsString($expectedcontent, $record->where);
|
||||
$this->assertContains($expectedcontent, $record->where);
|
||||
|
||||
$dbman->drop_table($table);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class tool_installaddon_installer_testcase extends advanced_testcase {
|
||||
$this->assertEquals(1, preg_match('~^site=(.+)$~', $query, $matches));
|
||||
$site = rawurldecode($matches[1]);
|
||||
$site = json_decode(base64_decode($site), true);
|
||||
$this->assertIsArray($site);
|
||||
$this->assertInternalType('array', $site);
|
||||
$this->assertEquals(3, count($site));
|
||||
$this->assertSame('Nasty site', $site['fullname']);
|
||||
$this->assertSame('file:///etc/passwd', $site['url']);
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace tool_langimport\output;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use core_collator;
|
||||
use moodle_url;
|
||||
use renderable;
|
||||
use renderer_base;
|
||||
@@ -95,6 +95,8 @@ class langimport_page implements renderable, templatable {
|
||||
|
||||
if (!empty($this->availablelanguages)) {
|
||||
$data->toinstalloptions = [];
|
||||
|
||||
core_collator::asort($this->availablelanguages);
|
||||
foreach ($this->availablelanguages as $code => $language) {
|
||||
$option = new stdClass();
|
||||
$option->value = $code;
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
}
|
||||
}}
|
||||
<div class="container-fluid langimport">
|
||||
<div class="row rtl-compatible">
|
||||
<div class="row row-fluid rtl-compatible">
|
||||
<div class="col-md-{{#caninstall}}6{{/caninstall}}{{^caninstall}}12{{/caninstall}} span{{#caninstall}}6{{/caninstall}}{{^caninstall}}12{{/caninstall}} mb-1">
|
||||
<form id="uninstallform" action="{{uninstallurl}}" method="post">
|
||||
<fieldset>
|
||||
|
||||
@@ -36,7 +36,7 @@ class tool_langimport_events_testcase extends advanced_testcase {
|
||||
/**
|
||||
* Setup testcase.
|
||||
*/
|
||||
public function setUp(): void {
|
||||
public function setUp() {
|
||||
$this->setAdminUser();
|
||||
$this->resetAfterTest();
|
||||
}
|
||||
@@ -56,10 +56,12 @@ class tool_langimport_events_testcase extends advanced_testcase {
|
||||
$this->assertEquals(context_system::instance(), $event->get_context());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @expectedExceptionMessage The 'langcode' value must be set to a valid language code
|
||||
*/
|
||||
public function test_langpack_updated_validation() {
|
||||
|
||||
$this->expectException('coding_exception');
|
||||
$this->expectExceptionMessage("The 'langcode' value must be set to a valid language code");
|
||||
\tool_langimport\event\langpack_updated::event_with_langcode('broken langcode');
|
||||
}
|
||||
|
||||
@@ -76,10 +78,12 @@ class tool_langimport_events_testcase extends advanced_testcase {
|
||||
$this->assertEquals(context_system::instance(), $event->get_context());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @expectedExceptionMessage The 'langcode' value must be set to a valid language code
|
||||
*/
|
||||
public function test_langpack_installed_validation() {
|
||||
|
||||
$this->expectException('coding_exception');
|
||||
$this->expectExceptionMessage("The 'langcode' value must be set to a valid language code");
|
||||
\tool_langimport\event\langpack_imported::event_with_langcode('broken langcode');
|
||||
}
|
||||
|
||||
@@ -96,10 +100,12 @@ class tool_langimport_events_testcase extends advanced_testcase {
|
||||
$this->assertEquals(context_system::instance(), $event->get_context());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException coding_exception
|
||||
* @expectedExceptionMessage The 'langcode' value must be set to a valid language code
|
||||
*/
|
||||
public function test_langpack_removed_validation() {
|
||||
|
||||
$this->expectException('coding_exception');
|
||||
$this->expectExceptionMessage("The 'langcode' value must be set to a valid language code");
|
||||
\tool_langimport\event\langpack_removed::event_with_langcode('broken langcode');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ require_once(__DIR__ . '/fixtures/event.php');
|
||||
*/
|
||||
class logstore_database_privacy_testcase extends provider_testcase {
|
||||
|
||||
public function setUp(): void {
|
||||
public function setUp() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest();
|
||||
$this->preventResetByRollback(); // Logging waits till the transaction gets committed.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/**
|
||||
* Legacy log reader.
|
||||
* @deprecated since Moodle 3.6 MDL-52953 - Please use supported log stores such as "standard" or "external" instead.
|
||||
* @todo MDL-52805 This is to be removed in Moodle 3.10
|
||||
* @todo MDL-52805 This is to be removed in Moodle 4.0
|
||||
*
|
||||
* @package logstore_legacy
|
||||
* @copyright 2013 Petr Skoda {@link http://skodak.org}
|
||||
@@ -34,7 +34,7 @@ class store implements \tool_log\log\store, \core\log\sql_reader {
|
||||
|
||||
/**
|
||||
* @deprecated since Moodle 3.6 MDL-52953 - Please use supported log stores such as "standard" or "external" instead.
|
||||
* @todo MDL-52805 This is to be removed in Moodle 3.10
|
||||
* @todo MDL-52805 This is to be removed in Moodle 4.0
|
||||
*
|
||||
* @param \tool_log\log\manager $manager
|
||||
*/
|
||||
@@ -93,7 +93,7 @@ class store implements \tool_log\log\store, \core\log\sql_reader {
|
||||
|
||||
/**
|
||||
* @deprecated since Moodle 3.6 MDL-52953 - Please use supported log stores such as "standard" or "external" instead.
|
||||
* @todo MDL-52805 This will be removed in Moodle 3.10
|
||||
* @todo MDL-52805 This will be removed in Moodle 4.0
|
||||
*
|
||||
* @param string $selectwhere
|
||||
* @param array $params
|
||||
@@ -134,7 +134,7 @@ class store implements \tool_log\log\store, \core\log\sql_reader {
|
||||
/**
|
||||
* Fetch records using given criteria returning a Traversable object.
|
||||
* @deprecated since Moodle 3.6 MDL-52953 - Please use supported log stores such as "standard" or "external" instead.
|
||||
* @todo MDL-52805 This will be removed in Moodle 3.10
|
||||
* @todo MDL-52805 This will be removed in Moodle 4.0
|
||||
*
|
||||
* Note that the traversable object contains a moodle_recordset, so
|
||||
* remember that is important that you call close() once you finish
|
||||
@@ -168,7 +168,7 @@ class store implements \tool_log\log\store, \core\log\sql_reader {
|
||||
/**
|
||||
* Returns an event from the log data.
|
||||
* @deprecated since Moodle 3.6 MDL-52953 - Please use supported log stores such as "standard" or "external" instead.
|
||||
* @todo MDL-52805 This will be removed in Moodle 3.10
|
||||
* @todo MDL-52805 This will be removed in Moodle 4.0
|
||||
*
|
||||
* @param stdClass $data Log data
|
||||
* @return \core\event\base
|
||||
@@ -179,7 +179,7 @@ class store implements \tool_log\log\store, \core\log\sql_reader {
|
||||
|
||||
/**
|
||||
* @deprecated since Moodle 3.6 MDL-52953 - Please use supported log stores such as "standard" or "external" instead.
|
||||
* @todo MDL-52805 This will be removed in Moodle 3.10
|
||||
* @todo MDL-52805 This will be removed in Moodle 4.0
|
||||
*
|
||||
* @param string $selectwhere
|
||||
* @param array $params
|
||||
@@ -202,7 +202,7 @@ class store implements \tool_log\log\store, \core\log\sql_reader {
|
||||
/**
|
||||
* Are the new events appearing in the reader?
|
||||
* @deprecated since Moodle 3.6 MDL-52953 - Please use supported log stores such as "standard" or "external" instead.
|
||||
* @todo MDL-52805 This will be removed in Moodle 3.10
|
||||
* @todo MDL-52805 This will be removed in Moodle 4.0
|
||||
*
|
||||
* @return bool true means new log events are being added, false means no new data will be added
|
||||
*/
|
||||
@@ -212,7 +212,7 @@ class store implements \tool_log\log\store, \core\log\sql_reader {
|
||||
|
||||
/**
|
||||
* @deprecated since Moodle 3.6 MDL-52953 - Please use supported log stores such as "standard" or "external" instead.
|
||||
* @todo MDL-52805 This will be removed in Moodle 3.10
|
||||
* @todo MDL-52805 This will be removed in Moodle 4.0
|
||||
*/
|
||||
public function dispose() {
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user