Compare commits
761 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b15cd07d4b | |||
| ecbd8716f6 | |||
| 7820e5047d | |||
| c4101db016 | |||
| d1582f14d5 | |||
| e153abc018 | |||
| f1ae261bc9 | |||
| 19fcc09ac7 | |||
| 82bd683018 | |||
| 19c8fd9e8b | |||
| 0bfc2dde8f | |||
| 807f806ed7 | |||
| 85dd2a674a | |||
| fa8843c424 | |||
| fdca6e8321 | |||
| ae3056cb00 | |||
| 74969d8866 | |||
| 5e69fe4971 | |||
| 133173e213 | |||
| 747d6b5aac | |||
| 91a7a788aa | |||
| c3a4009a56 | |||
| f0837f65d8 | |||
| a70eda6cc8 | |||
| c5c9be022d | |||
| 96909b1597 | |||
| 8f40d27954 | |||
| 59c8be2362 | |||
| f289c698a9 | |||
| daf4471a40 | |||
| b056fee5ba | |||
| c6e321ccaf | |||
| f6705d681a | |||
| 30ed26a576 | |||
| 1e6c738c6c | |||
| 4cb89f4df4 | |||
| 1f2d15dc62 | |||
| 7d9cb204be | |||
| e6f5ebe25b | |||
| 6eeb293e04 | |||
| 124414cc5e | |||
| 69a62c2646 | |||
| add033dafe | |||
| 90e44b5068 | |||
| bf49e4404c | |||
| e4346a63ba | |||
| e438ff9942 | |||
| ddf0d0dcd7 | |||
| d85d6ccd3e | |||
| bd90c5891f | |||
| e58c72d050 | |||
| 77be201a0f | |||
| 73a48291b3 | |||
| cb7699c3a9 | |||
| 22ba72591c | |||
| 41be2f3587 | |||
| 7bbad2e268 | |||
| fc15f0837a | |||
| 9d0cc2cb4c | |||
| f058ea24c9 | |||
| b99d21aaa9 | |||
| 778854eef5 | |||
| 5c6377900a | |||
| a00b84e864 | |||
| 667ffef155 | |||
| 8258ddff3b | |||
| 03fb10da20 | |||
| 342f224f03 | |||
| 0623443356 | |||
| 4a313905bc | |||
| 9c36051feb | |||
| fa447a513e | |||
| 037afad8c3 | |||
| 72a32ea968 | |||
| 21973a92a4 | |||
| af9a00d398 | |||
| 3264974513 | |||
| 214784a4af | |||
| b15ab7630c | |||
| 3973662145 | |||
| f7bb84df23 | |||
| fc316236f5 | |||
| e9be98eed2 | |||
| ca92a99a2e | |||
| d021250bf0 | |||
| 2b4dcfdcbd | |||
| fe245b725b | |||
| 3dba01a40f | |||
| 5cac28fb2b | |||
| dc110687c8 | |||
| 0518140c31 | |||
| 4d7a9cd8f5 | |||
| ba1afa0d95 | |||
| f8431a1933 | |||
| 3cef27bf9f | |||
| 9551f03606 | |||
| 8daff43635 | |||
| e90206aaa4 | |||
| b967bf6005 | |||
| ded9134e03 | |||
| 9d7b02bec0 | |||
| d496829c61 | |||
| 9c43f8f7e1 | |||
| 7af777217d | |||
| 585bd02479 | |||
| d7749a10a6 | |||
| 65072bfdc2 | |||
| 9f05075c61 | |||
| ef4cf39174 | |||
| 7294a0649b | |||
| 9c49600397 | |||
| 0a5afc0583 | |||
| 2de4e3872c | |||
| d73581da42 | |||
| dbd388acef | |||
| 51fd4dd261 | |||
| dddcaf6b6b | |||
| 8710d49bec | |||
| a672bd8ad5 | |||
| 4d1e35d8c0 | |||
| 7bfc279ffb | |||
| cb59f50fb8 | |||
| 5d81093e3c | |||
| a9384ab0d0 | |||
| 18d81bdb3c | |||
| 4b5c0b461c | |||
| 0047a8f47d | |||
| a39eb49fc2 | |||
| cfb909d013 | |||
| 81fa243ea4 | |||
| 747d4d3e25 | |||
| 74ca90e5fb | |||
| 4e92a71fb3 | |||
| e6674da8ff | |||
| 136fa79e34 | |||
| 06a22aecb7 | |||
| f7cf17a853 | |||
| e63827ad98 | |||
| 84de2336fb | |||
| 7f0d91d546 | |||
| 14312ebc6a | |||
| 292faa4f7d | |||
| e93bb0ca52 | |||
| a886ad10ea | |||
| c4b234ec54 | |||
| 6831c9ff36 | |||
| 6a49c01825 | |||
| 0ff54e134f | |||
| 5af8bbf854 | |||
| 75ebacb1ec | |||
| 1859247e0c | |||
| f199117f05 | |||
| bc24c20388 | |||
| 4e970a5335 | |||
| 955f15a71f | |||
| 5585910ea7 | |||
| 1b17be9050 | |||
| 26c28d0821 | |||
| 8104e0f2df | |||
| 4ded0afd16 | |||
| 2e348a6643 | |||
| 84cae7bef8 | |||
| 3d2029f3d4 | |||
| 9acc5736a8 | |||
| 08d1ba7106 | |||
| e9197a3711 | |||
| 4394f91b26 | |||
| 25aa44ea97 | |||
| f9d4ab44e0 | |||
| 1f552b4c48 | |||
| b19539bf44 | |||
| ce0cb2451b | |||
| 929c1e4a8b | |||
| 7923d63b16 | |||
| efb0aacf37 | |||
| 9e312ed269 | |||
| 6aa9352f66 | |||
| 2023ca1f0f | |||
| 6f1156a6c2 | |||
| a7cb1e62f4 | |||
| edb8077e7b | |||
| d8f2500f46 | |||
| 6519a7769d | |||
| 995b4d16cd | |||
| 717c3395be | |||
| 6bc526319e | |||
| b3c64930ff | |||
| a6f388c664 | |||
| 90d14d089c | |||
| 9d8dbe645c | |||
| 937e0a23d9 | |||
| 910671644c | |||
| 9e6ef6ccc2 | |||
| 4a277f4f4e | |||
| 786a905607 | |||
| 20ff7e3279 | |||
| 2513a2b24f | |||
| 4966b0ee71 | |||
| 18fc309097 | |||
| 3bfe7ce57a | |||
| 366c19fabd | |||
| 56a1642c5b | |||
| 9d74bab3bc | |||
| 993261dcff | |||
| 4b5233f9c4 | |||
| 0cf269c1fc | |||
| e1e082a809 | |||
| 8cd0f221b6 | |||
| 94a720f287 | |||
| f6090a3531 | |||
| 3dfac46e97 | |||
| 3119ba9a2a | |||
| 74743b5e48 | |||
| 033a066e4f | |||
| 8ede1d5121 | |||
| 0347dd4d70 | |||
| 5da6f4eeb6 | |||
| 34c46428f1 | |||
| 9ec4220c84 | |||
| 22e8ad6134 | |||
| 0780ba7ca7 | |||
| 06b66d530b | |||
| 57d30b5276 | |||
| a640301b81 | |||
| 593b4518ad | |||
| abaff947c6 | |||
| ae115cf229 | |||
| 152ee16812 | |||
| ed2448a342 | |||
| 48f6a80092 | |||
| 85f5ab3145 | |||
| 26cfc10584 | |||
| 5f856fdfe9 | |||
| 0d7dcbf1ae | |||
| 6786f79ab4 | |||
| a010bfe63d | |||
| 3cabe2de8c | |||
| 7ecabfdce4 | |||
| c8fa99de72 | |||
| 02aac22ff8 | |||
| 05956888d7 | |||
| caff2aa640 | |||
| 5031249d84 | |||
| 3c7a83744e | |||
| 436135f52a | |||
| 41f17b384f | |||
| 47b9f44c6f | |||
| 7a8a938077 | |||
| e3a6a3878e | |||
| 35dd29564b | |||
| 5c71cfca6a | |||
| e5df0e3e17 | |||
| 6b94a62ff8 | |||
| e9a574454c | |||
| ddf322586e | |||
| ed9041c9ce | |||
| 3853dc585c | |||
| 132c116509 | |||
| 97dd4ec539 | |||
| 5266e929da | |||
| 9c89f307f8 | |||
| 4524a47a0a | |||
| 7816f5acb0 | |||
| ce4285c883 | |||
| 208b9e2a50 | |||
| 5a8f177c73 | |||
| fa3dff1318 | |||
| a4ad64950b | |||
| 6870b5dcbb | |||
| 6e582f1632 | |||
| 3bdb9bfd54 | |||
| 1dd41f0eb1 | |||
| 78b19caf0a | |||
| 4984e712e6 | |||
| 174245497e | |||
| 119b895133 | |||
| 04dc7f877b | |||
| 5e7d9e3e36 | |||
| c24ccde07f | |||
| b38bcc3a1d | |||
| 9b81b37eb9 | |||
| 2f2cf818c2 | |||
| ed32596d3a | |||
| 9651053bb4 | |||
| 15e6246359 | |||
| b1a24c1eb0 | |||
| 362d5c1ed1 | |||
| d5ae2ed112 | |||
| e4527c5497 | |||
| 200cb06bfc | |||
| 97e4e3953a | |||
| ee4dee99e8 | |||
| 7adfd55ec2 | |||
| efc2de0e97 | |||
| ddec658859 | |||
| e9f707d38a | |||
| 7faa5b4e9c | |||
| 2eb3bb390f | |||
| 2134aa6129 | |||
| adc0d74ac9 | |||
| b5013dc868 | |||
| b61fd419e8 | |||
| 8c412f122c | |||
| 7a4a1f14ca | |||
| fad5ec9b5a | |||
| 93e8c6c422 | |||
| 16dc846eb1 | |||
| c7c1a8cf14 | |||
| b13eda7e8d | |||
| a3ad8fd883 | |||
| 4ffedd8b0e | |||
| 71cf843ad2 | |||
| fd7bdf278c | |||
| 80fc30b7bd | |||
| 251037cefd | |||
| 3d95259d7e | |||
| 1b502dff19 | |||
| e9f8af2a1b | |||
| 35dd038144 | |||
| f403941133 | |||
| a1eeb0185a | |||
| dc70aa7378 | |||
| bb37aab093 | |||
| 72bd83e0f1 | |||
| 1b69c111cc | |||
| 23eccfcd77 | |||
| 68cfdb72f9 | |||
| 0570e81ecb | |||
| 5ce736caa8 | |||
| 8145290d43 | |||
| d94b4b327d | |||
| c896d5c54d | |||
| 5cfb119475 | |||
| 092c6089c9 | |||
| 8fb3542126 | |||
| 4b0fbfcbd9 | |||
| b1ea3fb2c6 | |||
| 94aa0fbe8c | |||
| 6be8a680e2 | |||
| 6310adb3f4 | |||
| 80fa621c50 | |||
| 60854b669a | |||
| 8db14e344b | |||
| a47827691a | |||
| 3b9bf6a949 | |||
| 5eb8c77850 | |||
| 51606ad2d8 | |||
| 812e3294be | |||
| 181b0dc545 | |||
| 6b3d645e9b | |||
| 3d233b9dab | |||
| 5c364504a6 | |||
| 0864c8a59d | |||
| c498bf796b | |||
| a32da065ae | |||
| 68d9daa187 | |||
| 4bdcd23e19 | |||
| 716f93efdb | |||
| ec5f40b1a9 | |||
| 01f9bc7948 | |||
| fc218ba9e2 | |||
| f3e0eac04f | |||
| da45306da5 | |||
| 96bab3e01d | |||
| cb5a7bba89 | |||
| 0a20ddbe7d | |||
| 3575052f81 | |||
| 6d9ae2adf0 | |||
| f76dc0ff65 | |||
| 1b64c78d36 | |||
| 24654d977b | |||
| cd91adc715 | |||
| e5ba71b479 | |||
| ad307c7121 | |||
| 1c64c52951 | |||
| 74475bd5d5 | |||
| c30dadce6f | |||
| f45cf8cb2c | |||
| 4239318be9 | |||
| 33868528bb | |||
| e3af6a00ba | |||
| 95caac3cc8 | |||
| c89c390759 | |||
| 25bde46869 | |||
| 269c653560 | |||
| 88b340161b | |||
| 5b18861bf0 | |||
| 84e093e143 | |||
| 02b36f79d2 | |||
| a6f18c98f4 | |||
| 273ac54baa | |||
| 549af292b6 | |||
| 28f9b39287 | |||
| e42213ab72 | |||
| 68d998c6cf | |||
| bf22dc969c | |||
| 0031600453 | |||
| 3bcd0781f1 | |||
| 26e3dce466 | |||
| 5e54da0a69 | |||
| a4f85cc579 | |||
| bf1b681560 | |||
| 2ce0d40694 | |||
| 7f10fbbf5f | |||
| e67a234c98 | |||
| 80e3f00091 | |||
| d3fd75d21d | |||
| 8ad92a30f1 | |||
| bee0152fda | |||
| 2c7cc519d8 | |||
| 643e2728df | |||
| 3a7de25755 | |||
| 56d57a9a4e | |||
| 1449e4faa2 | |||
| b51aac313f | |||
| ee124f531b | |||
| 63ff326835 | |||
| 5ce30862f2 | |||
| dbc61bc225 | |||
| f08cc8276c | |||
| 3a5778ec5a | |||
| d0aeb0abfa | |||
| f364d3f91d | |||
| 07b5fbb9ca | |||
| 7637e2e5e4 | |||
| d980c1d746 | |||
| 339c198ade | |||
| 4f4cbbad8f | |||
| 6a211fb52d | |||
| 9271414522 | |||
| f715589ee5 | |||
| 6c506c9a07 | |||
| a28b6620d6 | |||
| c0d30fbb75 | |||
| 3b97dedfbd | |||
| d04b3d580e | |||
| 0f61d7f97c | |||
| 37f5c92302 | |||
| dc4bff71a2 | |||
| fd6a17ecfb | |||
| fe34282df6 | |||
| 6b4422a086 | |||
| 9dba637233 | |||
| 5c5cb085c0 | |||
| 1c106106fd | |||
| 65be66e4d4 | |||
| 006776fc71 | |||
| 6f80b9b3e9 | |||
| 56f2ab3335 | |||
| 5553dcba67 | |||
| 806e82b7fc | |||
| 172007a066 | |||
| 9a2e30d8bc | |||
| 272d804840 | |||
| 40b4296d07 | |||
| f24eca0c6b | |||
| 9d660d5f0e | |||
| cf7daeae7e | |||
| 62bdb79c26 | |||
| 6f7c43c7de | |||
| cf8cc1bab1 | |||
| 6b9c6cc54e | |||
| 31b4fdabbf | |||
| a9fbf9fb87 | |||
| 2e81c307d0 | |||
| c2edea7cbd | |||
| f6589dd72d | |||
| 29a27d3ca4 | |||
| e24225351c | |||
| 520f687cde | |||
| e25df8c464 | |||
| a5410db4e3 | |||
| d84336c27d | |||
| cbe6399300 | |||
| c5fe3d7490 | |||
| c04c6e6b8a | |||
| 6f90ec4703 | |||
| e3b8930087 | |||
| 70ade8e8d7 | |||
| b312305ccc | |||
| 1ad4fb6f12 | |||
| 056a53e81f | |||
| 788e2b30a5 | |||
| 005900fd2a | |||
| f97a14ba27 | |||
| 3e1d47f2cc | |||
| ad66263bc1 | |||
| 64d8fed91c | |||
| 80eb52c415 | |||
| c0852d9a0c | |||
| 5dd9ee192e | |||
| e1bb4741f1 | |||
| 4a45ddbae2 | |||
| aa34ca4309 | |||
| 11351de2d3 | |||
| 08282ec16c | |||
| 8981b64a41 | |||
| c6b8bbfa9b | |||
| 275a6f59d7 | |||
| 308e4280e3 | |||
| 5d08b03e5b | |||
| e4e3b12325 | |||
| 97247fdadd | |||
| fb563a9949 | |||
| f166ab0bec | |||
| bae927bebd | |||
| 7f62477a87 | |||
| 5a5e7bb3b1 | |||
| 6f2723ae83 | |||
| 365ed23695 | |||
| c0c2b3dc1a | |||
| 26dcfcb542 | |||
| 34eee090a7 | |||
| 9a1f42da6d | |||
| 5be31c5bf2 | |||
| 3e2569f70d | |||
| fa0f970835 | |||
| f89a34fb77 | |||
| 09e7c66714 | |||
| c4eea3e21a | |||
| 189bdcf125 | |||
| b587abd989 | |||
| 9cacdc07d7 | |||
| e054707e9a | |||
| 9cd9d86640 | |||
| 919fcc6f12 | |||
| f9694db2cb | |||
| 2154de3b3c | |||
| 0c566ce339 | |||
| 5bda1372a1 | |||
| 877f061325 | |||
| 263f258ae2 | |||
| 06b04e5c62 | |||
| d0752d358e | |||
| c7f69afe4a | |||
| 2fa0daefca | |||
| 89c13e32a0 | |||
| 235a394e04 | |||
| a10ec7f66a | |||
| 0638e55b14 | |||
| a637417d78 | |||
| 9da3c2efad | |||
| 16e382f8c5 | |||
| e12ec6169a | |||
| 01528075a2 | |||
| 3cddd60db7 | |||
| 216113139f | |||
| f664cb7c29 | |||
| 4ac669f1e8 | |||
| 99b0cba0ec | |||
| 526d69522d | |||
| a24681a87a | |||
| e1ad3c38bc | |||
| 7ff71aca59 | |||
| e205686397 | |||
| ba295bba29 | |||
| 25f9dae427 | |||
| d8f77afbb8 | |||
| aa4292ad22 | |||
| 2d4c4b65d4 | |||
| ce9423eaa7 | |||
| 26a4f319a8 | |||
| 93c5c05423 | |||
| 2f74865eef | |||
| fc391624f0 | |||
| a5224e1f83 | |||
| 30bfe73981 | |||
| b835eebad9 | |||
| 3152ccf0a4 | |||
| 38a6a195a4 | |||
| 18c2fcf8f1 | |||
| dbb6d73c8c | |||
| ae5375722e | |||
| 274d9cf950 | |||
| 7b205e100b | |||
| 39a84a780b | |||
| c782b4bb58 | |||
| b1591c6568 | |||
| 6e48852633 | |||
| 88b014092d | |||
| 7d8b8d1abe | |||
| 13d0cc41eb | |||
| f76942869c | |||
| 50ecbad305 | |||
| 1e075c08a0 | |||
| 4cbc500d1f | |||
| 4e6464937c | |||
| cb52b340d3 | |||
| f1073b930b | |||
| 4133a3cd5b | |||
| bdbb48efe9 | |||
| 965c9b97ab | |||
| 22cf3b24a5 | |||
| d19983fac1 | |||
| 283ccdc71f | |||
| 279a874108 | |||
| e0d9ebc1f2 | |||
| aede1fe6a7 | |||
| f21656d5d0 | |||
| feccdaa0ff | |||
| fc7224bac7 | |||
| 27b4936fcf | |||
| cdf9c89416 | |||
| bf953fe670 | |||
| 677ee6dee7 | |||
| 8fa38242d0 | |||
| aa3097da63 | |||
| 719368f8cf | |||
| dd70519ab4 | |||
| 38a1040957 | |||
| ea3317e782 | |||
| f871cc1b8a | |||
| 29d4f2eeb3 | |||
| a699cbcdbc | |||
| 8910a2d15a | |||
| 0d9cdacf89 | |||
| 982ea16909 | |||
| 39b10270a1 | |||
| 4e579f6067 | |||
| f6c2b4fc13 | |||
| 056c04c9b4 | |||
| 03368c0b2e | |||
| 4bc43436b9 | |||
| 5dd5e31616 | |||
| bd202c1531 | |||
| 9190787dff | |||
| 3753033ef6 | |||
| 0a02548c23 | |||
| 8399f5a230 | |||
| ffbde27300 | |||
| dd6142b7d2 | |||
| d5cb69e9ba | |||
| 285e578ed7 | |||
| e7250e5bd0 | |||
| f2b1a6c2ad | |||
| 52bdbe7617 | |||
| bf225ac4c8 | |||
| 697c3ab6b6 | |||
| 0954c43f81 | |||
| 536ac72d51 | |||
| 1024510a4a | |||
| 659d31bf25 | |||
| 3012b215f6 | |||
| 7a97eccc48 | |||
| b8dd2bb73c | |||
| 2987d698b4 | |||
| 082325c271 | |||
| 93d82f4601 | |||
| 3a9e75e464 | |||
| accc55da27 | |||
| d1c368e050 | |||
| 35ef97232c | |||
| f3e47fc8d2 | |||
| 4479a18d52 | |||
| 7869e36193 | |||
| aa132e3f9b | |||
| 34ee79470f | |||
| 9b1ffd0159 | |||
| 9741999e77 | |||
| 3274dc1461 | |||
| fe97a3dc7a | |||
| 6f09ed8643 | |||
| e0dfb65718 | |||
| 9cf58aba08 | |||
| c43a4beda8 | |||
| 64149328dd | |||
| 15bec9a365 | |||
| 665120d4e6 | |||
| 74275cf6e5 | |||
| 1187c38d6d | |||
| a19c77bd24 | |||
| b8cde34b06 | |||
| 2d28584695 | |||
| c261b351cf | |||
| 934c878eaa | |||
| b11d374122 | |||
| 337284688d | |||
| 661dd2cf61 | |||
| b0e79df977 | |||
| 6ca0ba0104 | |||
| 153694ed0a | |||
| 1541d1a36b | |||
| c159d8e872 | |||
| a8361fc214 | |||
| 96c7aa3fe5 | |||
| a3b71db63b | |||
| 66c36644d3 | |||
| 903c12c74b | |||
| 73d78d8de4 | |||
| bbdd6f2dc1 | |||
| f738eb06e7 | |||
| 6f30a86bc7 | |||
| 4db5d94af5 | |||
| 5299507674 | |||
| d5a8ec5ccd | |||
| 4daa20bb5b | |||
| 3a32daedb5 | |||
| 130fcbd649 | |||
| 96ab22afc8 | |||
| b88f5de7ec | |||
| 0ae4c47c76 | |||
| 60201a66e0 | |||
| 5a062fcd8f | |||
| 4481d845e1 | |||
| fefd37d864 | |||
| a938306457 | |||
| 8718d91313 | |||
| 24813d35f7 | |||
| 8437ce030d | |||
| 583e6a6992 | |||
| f738546c8f | |||
| 0e24cfb800 | |||
| cabce0e259 | |||
| fbe00fbec7 | |||
| 2fa78e85e9 | |||
| dd402d1fa3 | |||
| 14cf05a2cf | |||
| acfa08a69f | |||
| e986a24a9d | |||
| 7a0374f6e7 | |||
| 78087ddfa5 | |||
| bde4f81335 | |||
| 334b4f6301 | |||
| e4318be030 | |||
| 4c26ea1713 | |||
| 40ff08d84f | |||
| 9a1da08340 | |||
| eeb78f323a | |||
| 54bf1cf7dc | |||
| 376d87ca03 | |||
| fbb580c38a | |||
| 35a39e35e2 | |||
| 84a05572c9 | |||
| c01d7b4d79 | |||
| baa97ed623 | |||
| 05f4555422 | |||
| a5dd15e921 | |||
| 05299908b4 | |||
| 9a49e6004b | |||
| a3fd215cb8 | |||
| 6ff0bacee1 | |||
| 757ca142ca | |||
| 98e86d8b27 | |||
| 69b88de0df | |||
| 17b8d59a0a | |||
| d396a03bac | |||
| f404343487 | |||
| f8632149ad | |||
| a056d4fa9e | |||
| 3c9cd14006 | |||
| d5670c612b | |||
| 88d9d9fba5 | |||
| cc3e8c536c | |||
| a43b8cf330 | |||
| 028fba6878 | |||
| 8f32d623c5 | |||
| 63e8936bb1 | |||
| 5b806d1524 | |||
| 7679e8d256 | |||
| e1a1827b59 | |||
| 9f098ef0ec |
+1
-1
@@ -19,7 +19,7 @@ $returnurl = new moodle_url('/admin/settings.php', array('section'=>'manageauths
|
||||
$PAGE->set_url($returnurl);
|
||||
|
||||
$action = optional_param('action', '', PARAM_ACTION);
|
||||
$auth = optional_param('auth', '', PARAM_PLUGIN);
|
||||
$auth = optional_param('auth', '', PARAM_SAFEDIR);
|
||||
|
||||
get_enabled_auth_plugins(true); // fix the list of enabled auths
|
||||
if (empty($CFG->auth)) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
require_once '../config.php';
|
||||
require_once $CFG->libdir.'/adminlib.php';
|
||||
|
||||
$auth = required_param('auth', PARAM_PLUGIN);
|
||||
$auth = required_param('auth', PARAM_SAFEDIR);
|
||||
$PAGE->set_pagetype('admin-auth-' . $auth);
|
||||
|
||||
admin_externalpage_setup('authsetting'.$auth);
|
||||
|
||||
+28
-3
@@ -98,9 +98,34 @@
|
||||
exit;
|
||||
|
||||
} else {
|
||||
uninstall_plugin('block', $block->name);
|
||||
// Inform block it's about to be deleted
|
||||
if (file_exists("$CFG->dirroot/blocks/$block->name/block_$block->name.php")) {
|
||||
$blockobject = block_instance($block->name);
|
||||
if ($blockobject) {
|
||||
$blockobject->before_delete(); //only if we can create instance, block might have been already removed
|
||||
}
|
||||
}
|
||||
|
||||
// First delete instances and then block
|
||||
$instances = $DB->get_records('block_instances', array('blockname' => $block->name));
|
||||
if(!empty($instances)) {
|
||||
foreach($instances as $instance) {
|
||||
blocks_delete_instance($instance);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete block
|
||||
$DB->delete_records('block', array('id'=>$block->id));
|
||||
|
||||
drop_plugin_tables($block->name, "$CFG->dirroot/blocks/$block->name/db/install.xml", false); // old obsoleted table names
|
||||
drop_plugin_tables('block_'.$block->name, "$CFG->dirroot/blocks/$block->name/db/install.xml", false);
|
||||
|
||||
// Delete the capabilities that were defined by this block
|
||||
capabilities_cleanup('block/'.$block->name);
|
||||
|
||||
// Remove event handlers and dequeue pending events
|
||||
events_uninstall('block/'.$block->name);
|
||||
|
||||
$a = new stdClass();
|
||||
$a->block = $strblockname;
|
||||
$a->directory = $CFG->dirroot.'/blocks/'.$block->name;
|
||||
notice(get_string('blockdeletefiles', '', $a), 'blocks.php');
|
||||
@@ -225,7 +250,7 @@
|
||||
$tablerows[] = array(strip_tags($strblockname), $row); // first element will be used for sorting
|
||||
}
|
||||
|
||||
collatorlib::asort($tablerows);
|
||||
textlib_get_instance()->asort($tablerows);
|
||||
foreach ($tablerows as $row) {
|
||||
$table->add_data($row[1]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
/// Create "blog" forums in each course and copy blog entries from these courses' participants in these forums
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->dirroot.'/course/lib.php');
|
||||
require_once($CFG->dirroot.'/blog/lib.php');
|
||||
require_once($CFG->dirroot.'/mod/forum/lib.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('bloglevelupgrade');
|
||||
$PAGE->set_pagelayout('maintenance');
|
||||
|
||||
$go = optional_param('go', 0, PARAM_BOOL);
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading(get_string('bloglevelupgrade', 'admin'));
|
||||
|
||||
$strbloglevelupgrade = get_string('bloglevelupgradeinfo', 'admin');
|
||||
|
||||
if (!$go or !data_submitted() or !confirm_sesskey()) { /// Print a form
|
||||
$optionsyes = array('go'=>1, 'sesskey'=>sesskey());
|
||||
echo $OUTPUT->confirm($strbloglevelupgrade, new moodle_url('bloglevelupgrade.php', $optionsyes), 'index.php');
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
}
|
||||
|
||||
echo $OUTPUT->box_start();
|
||||
|
||||
/// Turn off time limits, sometimes upgrades can be slow.
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
$i = 0;
|
||||
|
||||
// If $CFG->bloglevel is set to BLOG_GROUP_LEVEL or BLOG_COURSE_LEVEL, create a new "blog" forum in each course
|
||||
// whose enrolled students have written blog entries, copy these entries in that forum and switch off blogs at site level
|
||||
|
||||
if ($CFG->bloglevel == BLOG_COURSE_LEVEL || $CFG->bloglevel == BLOG_GROUP_LEVEL) {
|
||||
$pbar = new progress_bar('bloglevelupgrade', 500, true);
|
||||
|
||||
$bloggers = $DB->get_records_sql("SELECT userid FROM {post} WHERE module = 'blog' GROUP BY userid");
|
||||
require_once($CFG->dirroot.'/mod/forum/lib.php');
|
||||
|
||||
$a = new stdClass();
|
||||
$a->userscount = 0;
|
||||
$a->blogcount = 0;
|
||||
|
||||
foreach ($bloggers as $blogger) {
|
||||
$courses = enrol_get_users_courses($blogger->userid, true, 'groupmode,groupmodeforce');
|
||||
$blogentries = $DB->get_records('post', array('module' => 'blog', 'userid' => $blogger->userid));
|
||||
|
||||
foreach ($courses as $course) {
|
||||
$forum = forum_get_course_forum($course->id, 'blog');
|
||||
$cm = get_coursemodule_from_instance('forum', $forum->id);
|
||||
|
||||
if ($CFG->bloglevel == BLOG_GROUP_LEVEL && $course->groupmode != NOGROUPS) {
|
||||
// Unless the course is set to separate groups forced, force the forum to Separate groups
|
||||
if (!($course->groupmode == SEPARATEGROUPS && $course->groupmodeforce)) {
|
||||
$cm->groupmode = SEPARATEGROUPS;
|
||||
$DB->update_record('course_modules', $cm);
|
||||
}
|
||||
|
||||
$groups = groups_get_user_groups($course->id, $blogger->userid);
|
||||
foreach ($groups[0] as $groupid) { // [0] is for all groupings combined
|
||||
$a->blogcount += bloglevelupgrade_entries($blogentries, $forum, $cm, $groupid);
|
||||
}
|
||||
} else {
|
||||
$a->blogcount += bloglevelupgrade_entries($blogentries, $forum, $cm);
|
||||
}
|
||||
}
|
||||
|
||||
$a->userscount = $i . '/' . count($bloggers);
|
||||
$pbar->update($i, count($bloggers), get_string('bloglevelupgradeprogress', 'admin', $a));
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
function bloglevelupgrade_entries($blogentries, $forum, $cm, $groupid=-1) {
|
||||
$count = 0;
|
||||
|
||||
$forumcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
|
||||
foreach ($blogentries as $blogentry) {
|
||||
$discussion = new stdClass();
|
||||
$discussion->course = $forum->course;
|
||||
$discussion->forum = $forum->id;
|
||||
$discussion->name = $blogentry->subject;
|
||||
$discussion->assessed = $forum->assessed;
|
||||
$discussion->message = $blogentry->summary;
|
||||
$discussion->messageformat = $blogentry->summaryformat;
|
||||
$discussion->messagetrust = 0;
|
||||
$discussion->attachments = 0;
|
||||
$discussion->mailnow = false;
|
||||
$discussion->timemodified = $blogentry->created;
|
||||
$discussion->itemid = null;
|
||||
$discussion->groupid = $groupid;
|
||||
$message = '';
|
||||
|
||||
$discussionid = forum_add_discussion($discussion, null, $message);
|
||||
|
||||
// Copy file attachment records
|
||||
$fs = get_file_storage();
|
||||
$files = $fs->get_area_files($sitecontext->id, 'blog', 'attachment', $blogentry->id);
|
||||
|
||||
if (!empty($files)) {
|
||||
foreach ($files as $storedfile) {
|
||||
$newfile = new stdClass();
|
||||
$newfile->component = 'mod_forum';
|
||||
$newfile->filearea = 'attachment';
|
||||
$newfile->itemid = $discussion->firstpost;
|
||||
$newfile->contextid = $forumcontext->id;
|
||||
$fs->create_file_from_storedfile($newfile, $storedfile->get_id());
|
||||
}
|
||||
}
|
||||
|
||||
$files = $fs->get_area_files($sitecontext->id, 'blog', 'post', $blogentry->id);
|
||||
|
||||
if (!empty($files)) {
|
||||
foreach ($files as $storedfile) {
|
||||
$newfile = new stdClass();
|
||||
$newfile->component = 'mod_forum';
|
||||
$newfile->filearea = 'post';
|
||||
$newfile->itemid = $discussion->firstpost;
|
||||
$newfile->contextid = $forumcontext->id;
|
||||
$fs->create_file_from_storedfile($newfile, $storedfile->get_id());
|
||||
}
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
// END OF LOOP
|
||||
|
||||
// set conversion flag - switches to new plugin automatically
|
||||
set_config('bloglevel_upgrade_complete', 1);
|
||||
// Finally switch bloglevel to 0 (disabled)
|
||||
set_config('bloglevel', 0);
|
||||
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
/// Rebuild course cache which might be incorrect now
|
||||
echo $OUTPUT->notification('Rebuilding course cache...', 'notifysuccess');
|
||||
rebuild_course_cache();
|
||||
echo $OUTPUT->notification('...finished', 'notifysuccess');
|
||||
|
||||
echo $OUTPUT->continue_button('index.php');
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
+13
-49
@@ -20,6 +20,7 @@
|
||||
*
|
||||
* This script is not intended for beginners!
|
||||
* Potential problems:
|
||||
* - environment check is not present yet
|
||||
* - su to apache account or sudo before execution
|
||||
* - not compatible with Windows platform
|
||||
*
|
||||
@@ -78,16 +79,6 @@ Example:
|
||||
"; //TODO: localize, mark as needed in install - to be translated later when everything is finished
|
||||
|
||||
|
||||
// distro specific customisation
|
||||
$distrolibfile = dirname(dirname(dirname(__FILE__))).'/install/distrolib.php';
|
||||
$distro = null;
|
||||
if (file_exists($distrolibfile)) {
|
||||
require_once($distrolibfile);
|
||||
if (function_exists('distro_get_config')) {
|
||||
$distro = distro_get_config();
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to do if config.php exists
|
||||
$configfile = dirname(dirname(dirname(__FILE__))).'/config.php';
|
||||
if (file_exists($configfile)) {
|
||||
@@ -100,16 +91,12 @@ if (file_exists($configfile)) {
|
||||
echo "\n\n";
|
||||
}
|
||||
|
||||
if ($DB->get_manager()->table_exists('config')) {
|
||||
cli_error(get_string('clialreadyinstalled', 'install'));
|
||||
} else {
|
||||
cli_error(get_string('clialreadyconfigured', 'install'));
|
||||
}
|
||||
cli_error(get_string('clialreadyinstalled', 'install'));
|
||||
}
|
||||
|
||||
$olddir = getcwd();
|
||||
|
||||
// change directory so that includes below work properly
|
||||
// change directory so that includes bellow work properly
|
||||
chdir(dirname($_SERVER['argv'][0]));
|
||||
|
||||
// Servers should define a default timezone in php.ini, but if they don't then make sure something is defined.
|
||||
@@ -143,6 +130,7 @@ $CFG->dirroot = dirname(dirname(dirname(__FILE__)));
|
||||
$CFG->libdir = "$CFG->dirroot/lib";
|
||||
$CFG->wwwroot = "http://localhost";
|
||||
$CFG->httpswwwroot = $CFG->wwwroot;
|
||||
$CFG->dataroot = str_replace('\\', '/', dirname(dirname(dirname(dirname(__FILE__)))).'/moodledata');
|
||||
$CFG->docroot = 'http://docs.moodle.org';
|
||||
$CFG->running_installer = true;
|
||||
$CFG->early_install_lang = true;
|
||||
@@ -190,14 +178,14 @@ if (empty($databases)) {
|
||||
// now get cli options
|
||||
list($options, $unrecognized) = cli_get_params(
|
||||
array(
|
||||
'chmod' => isset($distro->directorypermissions) ? sprintf('%04o',$distro->directorypermissions) : '2777', // let distros set dir permissions
|
||||
'chmod' => '2777',
|
||||
'lang' => $CFG->lang,
|
||||
'wwwroot' => '',
|
||||
'dataroot' => empty($distro->dataroot) ? str_replace('\\', '/', dirname(dirname(dirname(dirname(__FILE__)))).'/moodledata'): $distro->dataroot, // initialised later after including libs or by distro
|
||||
'dbtype' => empty($distro->dbtype) ? $defaultdb : $distro->dbtype, // let distro skip dbtype selection
|
||||
'dbhost' => empty($distro->dbhost) ? 'localhost' : $distro->dbhost, // let distros set dbhost
|
||||
'dataroot' => $CFG->dataroot,
|
||||
'dbtype' => $defaultdb,
|
||||
'dbhost' => 'localhost',
|
||||
'dbname' => 'moodle',
|
||||
'dbuser' => empty($distro->dbuser) ? 'root' : $distro->dbuser, // let distros set dbuser
|
||||
'dbuser' => 'root',
|
||||
'dbpass' => '',
|
||||
'dbsocket' => false,
|
||||
'prefix' => 'mdl_',
|
||||
@@ -277,7 +265,7 @@ if ($interactive) {
|
||||
$chmod = octdec(clean_param($options['chmod'], PARAM_INT));
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
cli_heading(get_string('datarootpermission', 'install'));
|
||||
cli_heading('Data directories permission'); // todo localize
|
||||
$prompt = get_string('clitypevaluedefault', 'admin', decoct($chmod));
|
||||
$error = '';
|
||||
do {
|
||||
@@ -337,7 +325,9 @@ $CFG->httpswwwroot = $CFG->wwwroot;
|
||||
|
||||
|
||||
//We need dataroot before lang download
|
||||
$CFG->dataroot = $options['dataroot'];
|
||||
if (!empty($options['dataroot'])) {
|
||||
$CFG->dataroot = $options['dataroot'];
|
||||
}
|
||||
if ($interactive) {
|
||||
cli_separator();
|
||||
$i=0;
|
||||
@@ -385,8 +375,6 @@ if ($interactive) {
|
||||
cli_error(get_string('pathserrcreatedataroot', 'install', $a));
|
||||
}
|
||||
}
|
||||
$CFG->tempdir = $CFG->dataroot.'/temp';
|
||||
$CFG->cachedir = $CFG->dataroot.'/cache';
|
||||
|
||||
// download required lang packs
|
||||
if ($CFG->lang !== 'en') {
|
||||
@@ -528,9 +516,6 @@ if ($interactive) {
|
||||
}
|
||||
|
||||
$CFG->dbpass = cli_input($prompt, $options['dbpass']);
|
||||
if (function_exists('distro_pre_create_db')) { // Hook for distros needing to do something before DB creation
|
||||
$distro = distro_pre_create_db($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbsocket'=>$options['dbsocket']), $distro);
|
||||
}
|
||||
$hint_database = install_db_validate($database, $CFG->dbhost, $CFG->dbuser, $CFG->dbpass, $CFG->dbname, $CFG->prefix, array('dbpersist'=>0, 'dbsocket'=>$options['dbsocket']));
|
||||
} while ($hint_database !== '');
|
||||
|
||||
@@ -660,27 +645,6 @@ require($configfile);
|
||||
$CFG->lang = $installlang;
|
||||
$SESSION->lang = $CFG->lang;
|
||||
|
||||
require("$CFG->dirroot/version.php");
|
||||
|
||||
// Test environment first.
|
||||
require_once($CFG->libdir . '/environmentlib.php');
|
||||
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
|
||||
if (!$envstatus) {
|
||||
$errors = environment_get_errors($environment_results);
|
||||
cli_heading(get_string('environment', 'admin'));
|
||||
foreach ($errors as $error) {
|
||||
list($info, $report) = $error;
|
||||
echo "!! $info !!\n$report\n\n";
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Test plugin dependencies.
|
||||
require_once($CFG->libdir . '/pluginlib.php');
|
||||
if (!plugin_manager::instance()->all_plugins_ok($version)) {
|
||||
cli_error(get_string('pluginschecktodo', 'admin'));
|
||||
}
|
||||
|
||||
install_cli_database($options, $interactive);
|
||||
|
||||
echo get_string('cliinstallfinished', 'install')."\n";
|
||||
|
||||
@@ -46,8 +46,8 @@ Options:
|
||||
--adminuser=USERNAME Username for the moodle admin account. Default is admin.
|
||||
--adminpass=PASSWORD Password for the moodle admin account.
|
||||
--agree-license Indicates agreement with software license.
|
||||
--fullname=STRING Name of the site
|
||||
--shortname=STRING Name of the site
|
||||
--fullname Name of the site
|
||||
--shortname Name of the site
|
||||
-h, --help Print out this help
|
||||
|
||||
Example:
|
||||
@@ -144,26 +144,6 @@ if ($CFG->lang !== 'en') {
|
||||
$CFG->early_install_lang = false;
|
||||
get_string_manager(true);
|
||||
|
||||
require("$CFG->dirroot/version.php");
|
||||
|
||||
// Test environment first.
|
||||
require_once($CFG->libdir . '/environmentlib.php');
|
||||
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
|
||||
if (!$envstatus) {
|
||||
$errors = environment_get_errors($environment_results);
|
||||
cli_heading(get_string('environment', 'admin'));
|
||||
foreach ($errors as $error) {
|
||||
list($info, $report) = $error;
|
||||
echo "!! $info !!\n$report\n\n";
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Test plugin dependencies.
|
||||
require_once($CFG->libdir . '/pluginlib.php');
|
||||
if (!plugin_manager::instance()->all_plugins_ok($version)) {
|
||||
cli_error(get_string('pluginschecktodo', 'admin'));
|
||||
}
|
||||
|
||||
install_cli_database($options, true);
|
||||
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* MySQL collation conversion tool.
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2012 Petr Skoda (http://skodak.org)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('CLI_SCRIPT', true);
|
||||
|
||||
require(dirname(dirname(dirname(__FILE__))).'/config.php');
|
||||
require_once($CFG->libdir.'/clilib.php'); // cli only functions
|
||||
|
||||
if ($DB->get_dbfamily() !== 'mysql') {
|
||||
cli_error('This function is designed for MySQL databases only!');
|
||||
}
|
||||
|
||||
// now get cli options
|
||||
list($options, $unrecognized) = cli_get_params(array('help'=>false, 'list'=>false, 'collation'=>false, 'available'=>false),
|
||||
array('h'=>'help', 'l'=>'list', 'a'=>'available'));
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
|
||||
}
|
||||
|
||||
$help =
|
||||
"MySQL collation conversions script.
|
||||
|
||||
It is strongly recommended to stop the web server before the conversion.
|
||||
This script may be executed before the main upgrade - 1.9.x data for example.
|
||||
|
||||
Options:
|
||||
--collation=COLLATION Convert MySQL tables to different collation
|
||||
-l, --list Show table and column information
|
||||
-a, --available Show list of available collations
|
||||
-h, --help Print out this help
|
||||
|
||||
Example:
|
||||
\$ sudo -u www-data /usr/bin/php admin/cli/mysql_collation.php --collation=utf8_general_ci
|
||||
";
|
||||
|
||||
if (!empty($options['collation'])) {
|
||||
$collations = mysql_get_collations();
|
||||
$collation = clean_param($options['collation'], PARAM_ALPHANUMEXT);
|
||||
$collation = strtolower($collation);
|
||||
if (!isset($collations[$collation])) {
|
||||
cli_error("Error: collation '$collation' is not available on this server!");
|
||||
}
|
||||
|
||||
echo "Converting tables and columns to '$collation' for $CFG->wwwroot:\n";
|
||||
$prefix = $DB->get_prefix();
|
||||
$prefix = str_replace('_', '\\_', $prefix);
|
||||
$sql = "SHOW TABLE STATUS WHERE Name LIKE BINARY '$prefix%'";
|
||||
$rs = $DB->get_recordset_sql($sql);
|
||||
$converted = 0;
|
||||
$skipped = 0;
|
||||
$errors = 0;
|
||||
foreach ($rs as $table) {
|
||||
echo str_pad($table->name, 40). " - ";
|
||||
|
||||
if ($table->collation === $collation) {
|
||||
echo "NO CHANGE\n";
|
||||
$skipped++;
|
||||
|
||||
} else {
|
||||
$DB->change_database_structure("ALTER TABLE $table->name DEFAULT COLLATE = $collation");
|
||||
echo "CONVERTED\n";
|
||||
$converted++;
|
||||
}
|
||||
|
||||
$sql = "SHOW FULL COLUMNS FROM $table->name WHERE collation IS NOT NULL";
|
||||
$rs2 = $DB->get_recordset_sql($sql);
|
||||
foreach ($rs2 as $column) {
|
||||
$column = (object)array_change_key_case((array)$column, CASE_LOWER);
|
||||
echo ' '.str_pad($column->field, 36). " - ";
|
||||
if ($column->collation === $collation) {
|
||||
echo "NO CHANGE\n";
|
||||
$skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($column->type === 'tinytext' or $column->type === 'mediumtext' or $column->type === 'text' or $column->type === 'longtext') {
|
||||
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
|
||||
$default = (!is_null($column->default) and $column->default !== '') ? "DEFAULT '$column->default'" : '';
|
||||
// primary, unique and inc are not supported for texts
|
||||
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default";
|
||||
$DB->change_database_structure($sql);
|
||||
|
||||
} else if (strpos($column->type, 'varchar') === 0) {
|
||||
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
|
||||
$default = !is_null($column->default) ? "DEFAULT '$column->default'" : '';
|
||||
// primary, unique and inc are not supported for texts
|
||||
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default";
|
||||
$DB->change_database_structure($sql);
|
||||
} else {
|
||||
echo "ERROR (unknown column type: $column->type)\n";
|
||||
$error++;
|
||||
continue;
|
||||
}
|
||||
echo "CONVERTED\n";
|
||||
$converted++;
|
||||
}
|
||||
$rs2->close();
|
||||
}
|
||||
$rs->close();
|
||||
echo "Converted: $converted, skipped: $skipped, errors: $errors\n";
|
||||
exit(0); // success
|
||||
|
||||
} else if (!empty($options['list'])) {
|
||||
echo "List of tables for $CFG->wwwroot:\n";
|
||||
$prefix = $DB->get_prefix();
|
||||
$prefix = str_replace('_', '\\_', $prefix);
|
||||
$sql = "SHOW TABLE STATUS WHERE Name LIKE BINARY '$prefix%'";
|
||||
$rs = $DB->get_recordset_sql($sql);
|
||||
$counts = array();
|
||||
foreach ($rs as $table) {
|
||||
if (isset($counts[$table->collation])) {
|
||||
$counts[$table->collation]++;
|
||||
} else {
|
||||
$counts[$table->collation] = 1;
|
||||
}
|
||||
echo str_pad($table->name, 40);
|
||||
echo $table->collation. "\n";
|
||||
$collations = mysql_get_column_collations($table->name);
|
||||
foreach ($collations as $columname=>$collation) {
|
||||
if (isset($counts[$collation])) {
|
||||
$counts[$collation]++;
|
||||
} else {
|
||||
$counts[$collation] = 1;
|
||||
}
|
||||
echo ' ';
|
||||
echo str_pad($columname, 36);
|
||||
echo $collation. "\n";
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
|
||||
echo "\n";
|
||||
echo "Table collations summary for $CFG->wwwroot:\n";
|
||||
foreach ($counts as $collation => $count) {
|
||||
echo "$collation: $count\n";
|
||||
}
|
||||
exit(0); // success
|
||||
|
||||
} else if (!empty($options['available'])) {
|
||||
echo "List of available MySQL collations for $CFG->wwwroot:\n";
|
||||
$collations = mysql_get_collations();
|
||||
foreach ($collations as $collation) {
|
||||
echo " $collation\n";
|
||||
}
|
||||
die;
|
||||
|
||||
} else {
|
||||
echo $help;
|
||||
die;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ========== Some functions ==============
|
||||
|
||||
function mysql_get_collations() {
|
||||
global $DB;
|
||||
|
||||
$collations = array();
|
||||
$sql = "SHOW COLLATION WHERE Collation LIKE 'utf8\_%' AND Charset = 'utf8'";
|
||||
$rs = $DB->get_recordset_sql($sql);
|
||||
foreach ($rs as $collation) {
|
||||
$collations[$collation->collation] = $collation->collation;
|
||||
}
|
||||
$rs->close();
|
||||
|
||||
$collation = $DB->get_dbcollation();
|
||||
if (isset($collations[$collation])) {
|
||||
$collations[$collation] .= ' (default)';
|
||||
}
|
||||
|
||||
return $collations;
|
||||
}
|
||||
|
||||
function mysql_get_column_collations($tablename) {
|
||||
global $DB;
|
||||
|
||||
$collations = array();
|
||||
$sql = "SELECT column_name, collation_name
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_schema = DATABASE() AND table_name = ? AND collation_name IS NOT NULL";
|
||||
$rs = $DB->get_recordset_sql($sql, array($tablename));
|
||||
foreach($rs as $record) {
|
||||
$collations[$record->column_name] = $record->collation_name;
|
||||
}
|
||||
$rs->close();
|
||||
return $collations;
|
||||
}
|
||||
@@ -76,13 +76,7 @@ if (!empty($options['engine'])) {
|
||||
}
|
||||
echo str_pad($table->name, 40). " - ";
|
||||
|
||||
try {
|
||||
$DB->change_database_structure("ALTER TABLE {$table->name} ENGINE = $engine");
|
||||
} catch (moodle_exception $e) {
|
||||
echo $e->getMessage()."\n";
|
||||
$skipped++;
|
||||
continue;
|
||||
}
|
||||
$DB->change_database_structure("ALTER TABLE {$table->name} TYPE = $engine");
|
||||
echo "DONE\n";
|
||||
$converted++;
|
||||
}
|
||||
|
||||
@@ -1,53 +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/>.
|
||||
|
||||
/**
|
||||
* @package core
|
||||
* @subpackage cli
|
||||
* @copyright 2011 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('CLI_SCRIPT', true);
|
||||
|
||||
require(dirname(dirname(dirname(__FILE__))).'/config.php');
|
||||
require_once($CFG->libdir.'/clilib.php');
|
||||
|
||||
list($options, $unrecognized) = cli_get_params(array('help' => false), array('h' => 'help'));
|
||||
|
||||
if ($unrecognized) {
|
||||
$unrecognized = implode("\n ", $unrecognized);
|
||||
cli_error(get_string('cliunknowoption', 'admin', $unrecognized), 2);
|
||||
}
|
||||
|
||||
if ($options['help']) {
|
||||
$help =
|
||||
"Invalidates all Moodle internal caches
|
||||
|
||||
Options:
|
||||
-h, --help Print out this help
|
||||
|
||||
Example:
|
||||
\$sudo -u www-data /usr/bin/php admin/cli/purge_caches.php
|
||||
";
|
||||
|
||||
echo $help;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
purge_all_caches();
|
||||
|
||||
exit(0);
|
||||
+4
-13
@@ -20,6 +20,7 @@
|
||||
*
|
||||
* This script is not intended for beginners!
|
||||
* Potential problems:
|
||||
* - environment check is not present yet
|
||||
* - su to apache account or sudo before execution
|
||||
* - not compatible with Windows platform
|
||||
*
|
||||
@@ -36,7 +37,7 @@ require_once($CFG->libdir.'/adminlib.php'); // various admin-only function
|
||||
require_once($CFG->libdir.'/upgradelib.php'); // general upgrade/install related functions
|
||||
require_once($CFG->libdir.'/clilib.php'); // cli only functions
|
||||
require_once($CFG->libdir.'/environmentlib.php');
|
||||
require_once($CFG->libdir.'/pluginlib.php');
|
||||
|
||||
|
||||
// now get cli options
|
||||
list($options, $unrecognized) = cli_get_params(
|
||||
@@ -92,13 +93,8 @@ if ($version < $CFG->version) {
|
||||
$oldversion = "$CFG->release ($CFG->version)";
|
||||
$newversion = "$release ($version)";
|
||||
|
||||
if (!moodle_needs_upgrading()) {
|
||||
cli_error(get_string('cliupgradenoneed', 'core_admin', $newversion), 0);
|
||||
}
|
||||
|
||||
// Test environment first.
|
||||
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
|
||||
if (!$envstatus) {
|
||||
// test environment first
|
||||
if (!check_moodle_environment(normalize_version($release), $environment_results, false, ENV_SELECT_RELEASE)) {
|
||||
$errors = environment_get_errors($environment_results);
|
||||
cli_heading(get_string('environment', 'admin'));
|
||||
foreach ($errors as $error) {
|
||||
@@ -108,11 +104,6 @@ if (!$envstatus) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Test plugin dependencies.
|
||||
if (!plugin_manager::instance()->all_plugins_ok($version)) {
|
||||
cli_error(get_string('pluginschecktodo', 'admin'));
|
||||
}
|
||||
|
||||
if ($interactive) {
|
||||
$a = new stdClass();
|
||||
$a->oldversion = $oldversion;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?PHP
|
||||
// dbperformance.php - shows latest ADOdb stats for the current server
|
||||
|
||||
// disable moodle specific debug messages and any errors in output
|
||||
define('NO_DEBUG_DISPLAY', true);
|
||||
|
||||
require_once('../config.php');
|
||||
|
||||
error('TODO: rewrite db perf code'); // TODO: rewrite
|
||||
|
||||
|
||||
$topframe = optional_param('topframe', 0, PARAM_BOOL);
|
||||
$bottomframe = optional_param('bottomframe', 0, PARAM_BOOL);
|
||||
$do = optional_param('do', '', PARAM_ALPHA);
|
||||
|
||||
require_login();
|
||||
|
||||
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
|
||||
|
||||
$strdatabaseperformance = get_string("databaseperformance");
|
||||
$stradministration = get_string("administration");
|
||||
$site = get_site();
|
||||
|
||||
if (!empty($topframe)) {
|
||||
$PAGE->set_url('/admin/dbperformance.php');
|
||||
$PAGE->navbar->add($stradministration, new moodle_url('/admin/index.php'));
|
||||
$PAGE->navbar->add($strdatabaseperformance);
|
||||
$PAGE->set_title("$site->shortname: $strdatabaseperformance");
|
||||
$PAGE->set_heading($site->fullname);
|
||||
echo $OUTPUT->header();
|
||||
exit;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
if (!defined('MOODLE_INTERNAL')) {
|
||||
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
|
||||
}
|
||||
|
||||
require_once $CFG->libdir.'/formslib.php';
|
||||
|
||||
class database_export_form extends moodleform {
|
||||
|
||||
function definition() {
|
||||
$mform = $this->_form;
|
||||
|
||||
$mform->addElement('header', 'database', get_string('dbexport', 'dbtransfer'));
|
||||
$mform->addElement('textarea', 'description', get_string('description'), array('rows'=>5, 'cols'=>60));
|
||||
|
||||
$this->add_action_buttons(false, get_string('exportdata', 'dbtransfer'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
if (!defined('MOODLE_INTERNAL')) {
|
||||
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
|
||||
}
|
||||
|
||||
require_once $CFG->libdir.'/formslib.php';
|
||||
|
||||
class database_transfer_form extends moodleform {
|
||||
|
||||
function definition() {
|
||||
$mform = $this->_form;
|
||||
|
||||
$mform->addElement('header', 'database', get_string('dbtransfer', 'dbtransfer'));
|
||||
|
||||
$supported = array (
|
||||
'mysqli/native',
|
||||
'pgsql/native',
|
||||
'mssql/native',
|
||||
'oci/native',
|
||||
'sqlite3/pdo',
|
||||
);
|
||||
$drivers = array();
|
||||
foreach($supported as $driver) {
|
||||
list($dbtype, $dblibrary) = explode('/', $driver);
|
||||
$targetdb = moodle_database::get_driver_instance($dbtype, $dblibrary);
|
||||
if ($targetdb->driver_installed() !== true) {
|
||||
continue;
|
||||
}
|
||||
$drivers[$driver] = $driver;
|
||||
}
|
||||
|
||||
$mform->addElement('select', 'driver', get_string('dbtype', 'install'), $drivers);
|
||||
$mform->addElement('text', 'dbhost', get_string('dbhost', 'install'));
|
||||
$mform->addElement('text', 'dbname', get_string('database', 'install'));
|
||||
$mform->addElement('text', 'dbuser', get_string('user'));
|
||||
$mform->addElement('text', 'dbpass', get_string('password'));
|
||||
$mform->addElement('text', 'prefix', get_string('dbprefix', 'install'));
|
||||
|
||||
$mform->addRule('dbhost', get_string('required'), 'required', null);
|
||||
$mform->addRule('dbname', get_string('required'), 'required', null);
|
||||
$mform->addRule('dbuser', get_string('required'), 'required', null);
|
||||
$mform->addRule('dbpass', get_string('required'), 'required', null);
|
||||
$mform->addRule('prefix', get_string('required'), 'required', null);
|
||||
|
||||
$this->add_action_buttons(false, get_string('transferdata', 'dbtransfer'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
require('../../config.php');
|
||||
require_once('lib.php');
|
||||
require_once('database_export_form.php');
|
||||
|
||||
require_login();
|
||||
admin_externalpage_setup('dbexport');
|
||||
|
||||
//create form
|
||||
$form = new database_export_form();
|
||||
|
||||
if ($data = $form->get_data()) {
|
||||
dbtransfer_export_xml_database($data->description, $DB);
|
||||
die;
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
// TODO: add some more info here
|
||||
$form->display();
|
||||
echo $OUTPUT->footer();
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
require('../../config.php');
|
||||
require_once('lib.php');
|
||||
require_once('database_transfer_form.php');
|
||||
|
||||
require_login();
|
||||
admin_externalpage_setup('dbtransfer');
|
||||
|
||||
// Create the form
|
||||
$form = new database_transfer_form();
|
||||
|
||||
// If we have valid input.
|
||||
if ($data = $form->get_data()) {
|
||||
// Connect to the other database.
|
||||
list($dbtype, $dblibrary) = explode('/', $data->driver);
|
||||
$targetdb = moodle_database::get_driver_instance($dbtype, $dblibrary);
|
||||
if (!$targetdb->connect($data->dbhost, $data->dbuser, $data->dbpass, $data->dbname, $data->prefix, null)) {
|
||||
throw new dbtransfer_exception('notargetconectexception', null, "$CFG->wwwroot/$CFG->admin/dbtransfer/");
|
||||
}
|
||||
if ($targetdb->get_tables()) {
|
||||
throw new dbtransfer_exception('targetdatabasenotempty', null, "$CFG->wwwroot/$CFG->admin/dbtransfer/");
|
||||
}
|
||||
|
||||
// Start output.
|
||||
echo $OUTPUT->header();
|
||||
$data->dbtype = $dbtype;
|
||||
echo $OUTPUT->heading(get_string('transferringdbto', 'dbtransfer', $data));
|
||||
|
||||
// Do the transfer.
|
||||
$feedback = new html_list_progress_trace();
|
||||
dbtransfer_transfer_database($DB, $targetdb, $feedback);
|
||||
$feedback->finished();
|
||||
|
||||
// Finish up.
|
||||
echo $OUTPUT->notification(get_string('success'), 'notifysuccess');
|
||||
echo $OUTPUT->continue_button("$CFG->wwwroot/$CFG->admin/");
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
}
|
||||
|
||||
// Otherwise display the settings form.
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading(get_string('transferdbtoserver', 'dbtransfer'));
|
||||
echo '<p>', get_string('transferdbintro', 'dbtransfer'), "</p>\n\n";
|
||||
$form->display();
|
||||
echo $OUTPUT->footer();
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
- exporting to server file >2GB fails in 32bit operating systems - needs warning
|
||||
- we may run out of disk space exporting to srever file - we must verify the file is not truncated; read from the end of file?
|
||||
- when sending file >4GB - FAT32 limit, Apache limit, browser limit - needs warning
|
||||
- there must be some form of progress bar during export, transfer - new tracking class could be passed around
|
||||
- command line operation - could work around some 2G/4G limits in PHP; useful for cron full backups
|
||||
- by default allow exporting into empty database only (no tables with the same prefix yet)
|
||||
- all dangerous operation (like deleting of all data) should be confirmed by key found in special file in dataroot
|
||||
(user would need file access to dataroot which might prevent various "accidents")
|
||||
- implement "Export/import running" notification in lib/setup.php (similar to new upgrade flag in config table)
|
||||
- gzip compression when storing xml file - the xml is very verbose and full of repeated tags (zip is not suitable here at all)
|
||||
this could help us keep the files bellow 2G (expected ratio is > 10:1)
|
||||
|
||||
*/
|
||||
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/dtllib.php');
|
||||
|
||||
|
||||
function dbtransfer_export_xml_database($description, $mdb) {
|
||||
@set_time_limit(0);
|
||||
|
||||
session_get_instance()->write_close(); // release session
|
||||
|
||||
header('Content-Type: application/xhtml+xml; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename=database.xml');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate,post-check=0,pre-check=0');
|
||||
header('Pragma: public');
|
||||
|
||||
while(@ob_flush());
|
||||
|
||||
$var = new file_xml_database_exporter('php://output', $mdb);
|
||||
$var->export_database($description);
|
||||
|
||||
// no more output
|
||||
die;
|
||||
}
|
||||
|
||||
|
||||
function dbtransfer_transfer_database($sourcedb, $targetdb, $feedback = null) {
|
||||
@set_time_limit(0);
|
||||
|
||||
session_get_instance()->write_close(); // release session
|
||||
|
||||
$var = new database_mover($sourcedb, $targetdb, true, $feedback);
|
||||
$var->export_database(null);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
// Deletes the moodledata directory, COMPLETELY!!
|
||||
// BE VERY CAREFUL USING THIS!
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('purgemoodledata');
|
||||
|
||||
require_login();
|
||||
|
||||
$sure = optional_param('sure', 0, PARAM_BOOL);
|
||||
$reallysure = optional_param('reallysure', 0, PARAM_BOOL);
|
||||
|
||||
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
|
||||
|
||||
$deletedir = $CFG->dataroot; // The directory to delete!
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading('Purge moodledata');
|
||||
|
||||
if (empty($sure)) {
|
||||
$optionsyes = array('sure'=>'yes', 'sesskey'=>sesskey());
|
||||
|
||||
$formcontinue = new single_button(new moodle_url('delete.php', $optionsyes), get_string('yes'));
|
||||
$formcancel = new single_button('index.php', get_string('no'), 'get');
|
||||
echo $OUTPUT->confirm('Are you completely sure you want to delete everything inside the directory '. $deletedir .' ?', $formcontinue, $formcancel);
|
||||
echo $OUTPUT->footer();
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!data_submitted() or empty($reallysure)) {
|
||||
$optionsyes = array('sure'=>'yes', 'sesskey'=>sesskey(), 'reallysure'=>'yes');
|
||||
$formcontinue = new single_button(new moodle_url('delete.php', $optionsyes), get_string('yes'));
|
||||
$formcancel = new single_button('index.php', get_string('no'), 'get');
|
||||
echo $OUTPUT->confirm('Are you REALLY REALLY completely sure you want to delete everything inside the directory '.
|
||||
$deletedir .' (this includes all user images, and any other course files that have been created) ?',
|
||||
$formcontinue, $formcancel);
|
||||
echo $OUTPUT->footer();
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!confirm_sesskey()) {
|
||||
print_error('wrongcall', 'error');
|
||||
}
|
||||
|
||||
/// OK, here goes ...
|
||||
|
||||
delete_subdirectories($deletedir);
|
||||
|
||||
echo '<h1 align="center">Done!</h1>';
|
||||
echo $OUTPUT->continue_button($CFG->wwwroot);
|
||||
echo $OUTPUT->footer();
|
||||
exit;
|
||||
|
||||
|
||||
function delete_subdirectories($rootdir) {
|
||||
|
||||
$dir = opendir($rootdir);
|
||||
|
||||
while (false !== ($file = readdir($dir))) {
|
||||
if ($file != '.' and $file != '..') {
|
||||
$fullfile = $rootdir .'/'. $file;
|
||||
if (filetype($fullfile) == 'dir') {
|
||||
delete_subdirectories($fullfile);
|
||||
echo 'Deleting '. $fullfile .' ... ';
|
||||
if (rmdir($fullfile)) {
|
||||
echo 'Done.<br />';
|
||||
} else {
|
||||
echo 'FAILED.<br />';
|
||||
}
|
||||
} else {
|
||||
echo 'Deleting '. $fullfile .' ... ';
|
||||
if (unlink($fullfile)) {
|
||||
echo 'Done.<br />';
|
||||
} else {
|
||||
echo 'FAILED.<br />';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dir);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
|
||||
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=manageeditors";
|
||||
|
||||
$action = optional_param('action', '', PARAM_ACTION);
|
||||
$editor = optional_param('editor', '', PARAM_PLUGIN);
|
||||
$editor = optional_param('editor', '', PARAM_SAFEDIR);
|
||||
|
||||
// get currently installed and enabled auth plugins
|
||||
$available_editors = editors_get_available();
|
||||
|
||||
+1
-8
@@ -27,11 +27,10 @@ require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
$action = required_param('action', PARAM_ACTION);
|
||||
$enrol = required_param('enrol', PARAM_PLUGIN);
|
||||
$enrol = required_param('enrol', PARAM_SAFEDIR);
|
||||
$confirm = optional_param('confirm', 0, PARAM_BOOL);
|
||||
|
||||
$PAGE->set_url('/admin/enrol.php');
|
||||
$PAGE->set_context(context_system::instance());
|
||||
|
||||
require_login();
|
||||
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
|
||||
@@ -42,13 +41,10 @@ $all = enrol_get_plugins(false);
|
||||
|
||||
$return = new moodle_url('/admin/settings.php', array('section'=>'manageenrols'));
|
||||
|
||||
$syscontext = context_system::instance();
|
||||
|
||||
switch ($action) {
|
||||
case 'disable':
|
||||
unset($enabled[$enrol]);
|
||||
set_config('enrol_plugins_enabled', implode(',', array_keys($enabled)));
|
||||
$syscontext->mark_dirty(); // resets all enrol caches
|
||||
break;
|
||||
|
||||
case 'enable':
|
||||
@@ -58,7 +54,6 @@ switch ($action) {
|
||||
$enabled = array_keys($enabled);
|
||||
$enabled[] = $enrol;
|
||||
set_config('enrol_plugins_enabled', implode(',', $enabled));
|
||||
$syscontext->mark_dirty(); // resets all enrol caches
|
||||
break;
|
||||
|
||||
case 'up':
|
||||
@@ -111,9 +106,7 @@ switch ($action) {
|
||||
|
||||
} else { // Delete everything!!
|
||||
uninstall_plugin('enrol', $enrol);
|
||||
$syscontext->mark_dirty(); // resets all enrol caches
|
||||
|
||||
$a = new stdClass();
|
||||
$a->plugin = $strplugin;
|
||||
$a->directory = "$CFG->dirroot/enrol/$enrol";
|
||||
echo $OUTPUT->notification(get_string('uninstalldeletefiles', 'enrol', $a), 'notifysuccess');
|
||||
|
||||
+124
-96
@@ -1,109 +1,137 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* This file is the admin frontend to execute all the checks available
|
||||
* in the environment.xml file. It includes database, php and
|
||||
* php_extensions. Also, it's possible to update the xml file
|
||||
* from moodle.org be able to check more and more versions.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage admin
|
||||
* @copyright 2006 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.com //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
|
||||
// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is the admin frontend to execute all the checks available
|
||||
// in the environment.xml file. It includes database, php and
|
||||
// php_extensions. Also, it's possible to update the xml file
|
||||
// from moodle.org be able to check more and more versions.
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/environmentlib.php');
|
||||
require_once($CFG->libdir.'/componentlib.class.php');
|
||||
|
||||
admin_externalpage_setup('environment');
|
||||
|
||||
/// Parameters
|
||||
$action = optional_param('action', '', PARAM_ACTION);
|
||||
$version = optional_param('version', '', PARAM_FILE); //
|
||||
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/environmentlib.php');
|
||||
require_once($CFG->libdir.'/componentlib.class.php');
|
||||
/// Get some strings
|
||||
$stradmin = get_string('administration');
|
||||
$stradminhelpenvironment = get_string("adminhelpenvironment");
|
||||
$strenvironment = get_string('environment', 'admin');
|
||||
$strerror = get_string('error');
|
||||
$strmoodleversion = get_string('moodleversion');
|
||||
$strupdate = get_string('updatecomponent', 'admin');
|
||||
$strupwards = get_string('upwards', 'admin');
|
||||
$strmisc = get_string('miscellaneous');
|
||||
|
||||
// Parameters
|
||||
$action = optional_param('action', '', PARAM_ACTION);
|
||||
$version = optional_param('version', '', PARAM_FILE); //
|
||||
/// Print the header stuff
|
||||
echo $OUTPUT->header();
|
||||
|
||||
$extraurlparams = array();
|
||||
if ($version) {
|
||||
$extraurlparams['version'] = $version;
|
||||
}
|
||||
admin_externalpage_setup('environment', '', $extraurlparams);
|
||||
/// Print the component download link
|
||||
echo '<div class="reportlink"><a href="environment.php?action=updatecomponent&sesskey='.sesskey().'">'.$strupdate.'</a></div>';
|
||||
|
||||
// Handle the 'updatecomponent' action
|
||||
if ($action == 'updatecomponent' && confirm_sesskey()) {
|
||||
// Create component installer and execute it
|
||||
if ($cd = new component_installer('http://download.moodle.org',
|
||||
'environment',
|
||||
'environment.zip')) {
|
||||
$status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
|
||||
switch ($status) {
|
||||
case COMPONENT_ERROR:
|
||||
if ($cd->get_error() == 'remotedownloaderror') {
|
||||
$a = new stdClass();
|
||||
$a->url = 'http://download.moodle.org/environment/environment.zip';
|
||||
$a->dest = $CFG->dataroot . '/';
|
||||
print_error($cd->get_error(), 'error', $PAGE->url, $a);
|
||||
die();
|
||||
echo $OUTPUT->heading($strenvironment);
|
||||
|
||||
} else {
|
||||
print_error($cd->get_error(), 'error', $PAGE->url);
|
||||
die();
|
||||
}
|
||||
|
||||
case COMPONENT_UPTODATE:
|
||||
redirect($PAGE->url, get_string($cd->get_error(), 'error'));
|
||||
die;
|
||||
|
||||
case COMPONENT_INSTALLED:
|
||||
redirect($PAGE->url, get_string('componentinstalled', 'admin'));
|
||||
die;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get current Moodle version
|
||||
$current_version = $CFG->release;
|
||||
|
||||
// Calculate list of versions
|
||||
$versions = array();
|
||||
if ($contents = load_environment_xml()) {
|
||||
if ($env_versions = get_list_of_environment_versions($contents)) {
|
||||
// Set the current version at the beginning
|
||||
$env_version = normalize_version($current_version); //We need this later (for the upwards)
|
||||
$versions[$env_version] = $current_version;
|
||||
// If no version has been previously selected, default to $current_version
|
||||
if (empty($version)) {
|
||||
$version = $env_version;
|
||||
}
|
||||
//Iterate over each version, adding bigger than current
|
||||
foreach ($env_versions as $env_version) {
|
||||
if (version_compare(normalize_version($current_version), $env_version, '<')) {
|
||||
$versions[$env_version] = $env_version;
|
||||
/// Handle the 'updatecomponent' action
|
||||
if ($action == 'updatecomponent' && confirm_sesskey()) {
|
||||
/// Create component installer and execute it
|
||||
if ($cd = new component_installer('http://download.moodle.org',
|
||||
'environment',
|
||||
'environment.zip')) {
|
||||
$status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
|
||||
switch ($status) {
|
||||
case COMPONENT_ERROR:
|
||||
if ($cd->get_error() == 'remotedownloaderror') {
|
||||
$a = new stdClass();
|
||||
$a->url = 'http://download.moodle.org/environment/environment.zip';
|
||||
$a->dest= $CFG->dataroot.'/';
|
||||
echo $OUTPUT->box(get_string($cd->get_error(), 'error', $a), 'errorbox');
|
||||
} else {
|
||||
echo $OUTPUT->box(get_string($cd->get_error(), 'error'), 'errorbox');
|
||||
}
|
||||
break;
|
||||
case COMPONENT_UPTODATE:
|
||||
echo $OUTPUT->box(get_string($cd->get_error(), 'error'));
|
||||
break;
|
||||
case COMPONENT_INSTALLED:
|
||||
echo $OUTPUT->box(get_string('componentinstalled', 'admin'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Add 'upwards' to the last element
|
||||
$versions[$env_version] = $env_version.' '.get_string('upwards', 'admin');
|
||||
} else {
|
||||
$versions = array('error' => get_string('error'));
|
||||
}
|
||||
}
|
||||
|
||||
// Get the results of the environment check.
|
||||
list($envstatus, $environment_results) = check_moodle_environment($version);
|
||||
/// Start of main box
|
||||
echo $OUTPUT->box_start();
|
||||
|
||||
echo "<div style=\"text-align:center\">".$stradminhelpenvironment."</div><br />";
|
||||
|
||||
/// Get current Moodle version
|
||||
$current_version = $CFG->release;
|
||||
|
||||
/// Calculate list of versions
|
||||
$versions = array();
|
||||
if ($contents = load_environment_xml()) {
|
||||
if ($env_versions = get_list_of_environment_versions($contents)) {
|
||||
/// Set the current version at the beginning
|
||||
$env_version = normalize_version($current_version); //We need this later (for the upwards)
|
||||
$versions[$env_version] = $current_version;
|
||||
/// If no version has been previously selected, default to $current_version
|
||||
if (empty($version)) {
|
||||
$version = $env_version;
|
||||
}
|
||||
///Iterate over each version, adding bigger than current
|
||||
foreach ($env_versions as $env_version) {
|
||||
if (version_compare(normalize_version($current_version), $env_version, '<')) {
|
||||
$versions[$env_version] = $env_version;
|
||||
}
|
||||
}
|
||||
/// Add 'upwards' to the last element
|
||||
$versions[$env_version] = $env_version.' '.$strupwards;
|
||||
} else {
|
||||
$versions = array('error' => $strerror);
|
||||
}
|
||||
}
|
||||
|
||||
/// Print form and popup menu
|
||||
echo '<div style="text-align:center"> ';
|
||||
$select = new single_select(new moodle_url('/admin/environment.php'), 'version', $versions, $version, null);
|
||||
$select->label = $strmoodleversion;
|
||||
echo $OUTPUT->render($select);
|
||||
echo '</div>';
|
||||
|
||||
/// End of main box
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
/// Gather and show results
|
||||
$status = check_moodle_environment($version, $environment_results);
|
||||
|
||||
/// Print footer
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
// Display the page.
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->environment_check_page($versions, $version, $envstatus, $environment_results);
|
||||
|
||||
+10
-334
@@ -214,7 +214,11 @@
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mysql" version="5.0.25" />
|
||||
<VENDOR name="mysql" version="5.0.25">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="mysql416required" />
|
||||
</FEEDBACK>
|
||||
</VENDOR>
|
||||
<VENDOR name="postgres" version="8.3" />
|
||||
<VENDOR name="mssql" version="9.0" />
|
||||
<VENDOR name="odbc_mssql" version="9.0" />
|
||||
@@ -331,7 +335,11 @@
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mysql" version="5.0.25" />
|
||||
<VENDOR name="mysql" version="5.0.25">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="mysql416required" />
|
||||
</FEEDBACK>
|
||||
</VENDOR>
|
||||
<VENDOR name="postgres" version="8.3" />
|
||||
<VENDOR name="mssql" version="9.0" />
|
||||
<VENDOR name="odbc_mssql" version="9.0" />
|
||||
@@ -434,336 +442,4 @@
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
</MOODLE>
|
||||
<MOODLE version="2.2" requires="1.9">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mysql" version="5.0.25" />
|
||||
<VENDOR name="postgres" version="8.3" />
|
||||
<VENDOR name="mssql" version="9.0" />
|
||||
<VENDOR name="odbc_mssql" version="9.0" />
|
||||
<VENDOR name="mssql_n" version="9.0" />
|
||||
<VENDOR name="oracle" version="10.2" />
|
||||
<VENDOR name="sqlite" version="2.0" />
|
||||
</DATABASE>
|
||||
<PHP version="5.3.2" level="required">
|
||||
</PHP>
|
||||
<PHP_EXTENSIONS>
|
||||
<PHP_EXTENSION name="iconv" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="iconvrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="mbstring" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="mbstringrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="curl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="curlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="openssl" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="opensslrecommended" />
|
||||
</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="gd" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="gdrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="simplexml" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="simplexmlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="spl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK 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="intl" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="intlrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="json" level="required">
|
||||
</PHP_EXTENSION>
|
||||
</PHP_EXTENSIONS>
|
||||
<PHP_SETTINGS>
|
||||
<PHP_SETTING name="memory_limit" value="40M" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="settingmemorylimit" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="safe_mode" value="0" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingsafemode" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="file_uploads" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingfileuploads" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
</MOODLE>
|
||||
<MOODLE version="2.3" requires="2.2">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mysql" version="5.1.33" />
|
||||
<VENDOR name="postgres" version="8.3" />
|
||||
<VENDOR name="mssql" version="9.0" />
|
||||
<VENDOR name="odbc_mssql" version="9.0" />
|
||||
<VENDOR name="mssql_n" version="9.0" />
|
||||
<VENDOR name="oracle" version="10.2" />
|
||||
<VENDOR name="sqlite" version="2.0" />
|
||||
</DATABASE>
|
||||
<PHP version="5.3.2" level="required">
|
||||
</PHP>
|
||||
<PHP_EXTENSIONS>
|
||||
<PHP_EXTENSION name="iconv" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="iconvrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="mbstring" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="mbstringrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="curl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="curlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="openssl" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="opensslrecommended" />
|
||||
</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="gd" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="gdrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="simplexml" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="simplexmlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="spl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK 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="intl" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="intlrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="json" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="hash" level="required"/>
|
||||
</PHP_EXTENSIONS>
|
||||
<PHP_SETTINGS>
|
||||
<PHP_SETTING name="memory_limit" value="40M" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="settingmemorylimit" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="safe_mode" value="0" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingsafemode" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="file_uploads" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingfileuploads" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
</MOODLE>
|
||||
<MOODLE version="2.4" requires="2.2">
|
||||
<UNICODE level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="unicoderequired" />
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mysql" version="5.1.33" />
|
||||
<VENDOR name="postgres" version="8.3" />
|
||||
<VENDOR name="mssql" version="9.0" />
|
||||
<VENDOR name="odbc_mssql" version="9.0" />
|
||||
<VENDOR name="mssql_n" version="9.0" />
|
||||
<VENDOR name="oracle" version="10.2" />
|
||||
<VENDOR name="sqlite" version="2.0" />
|
||||
</DATABASE>
|
||||
<PHP version="5.3.2" level="required">
|
||||
</PHP>
|
||||
<PHP_EXTENSIONS>
|
||||
<PHP_EXTENSION name="iconv" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="iconvrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="mbstring" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="mbstringrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="curl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="curlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="openssl" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="opensslrecommended" />
|
||||
</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="gd" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="gdrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="simplexml" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="simplexmlrequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="spl" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK 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="intl" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="intlrecommended" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="json" level="required">
|
||||
</PHP_EXTENSION>
|
||||
<PHP_EXTENSION name="hash" level="required"/>
|
||||
</PHP_EXTENSIONS>
|
||||
<PHP_SETTINGS>
|
||||
<PHP_SETTING name="memory_limit" value="40M" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="settingmemorylimit" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="safe_mode" value="0" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingsafemode" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
<PHP_SETTING name="file_uploads" value="1" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="settingfileuploads" />
|
||||
</FEEDBACK>
|
||||
</PHP_SETTING>
|
||||
</PHP_SETTINGS>
|
||||
</MOODLE>
|
||||
</COMPATIBILITY_MATRIX>
|
||||
|
||||
@@ -242,7 +242,6 @@ function get_table_row($filterinfo, $isfirstrow, $islastactive, $applytostrings)
|
||||
|
||||
// Disable/off/on
|
||||
$select = new single_select(filters_action_url($filter, 'setstate'), 'newstate', $activechoices, $filterinfo->active, null, 'active' . basename($filter));
|
||||
$select->set_label(get_string('isactive', 'filters'), array('class' => 'accesshide'));
|
||||
$row[] = $OUTPUT->render($select);
|
||||
|
||||
// Re-order
|
||||
@@ -264,7 +263,6 @@ function get_table_row($filterinfo, $isfirstrow, $islastactive, $applytostrings)
|
||||
|
||||
// Apply to strings.
|
||||
$select = new single_select(filters_action_url($filter, 'setapplyto'), 'stringstoo', $applytochoices, $applytostrings, null, 'applyto' . basename($filter));
|
||||
$select->set_label(get_string('applyto', 'filters'), array('class' => 'accesshide'));
|
||||
$select->disabled = $filterinfo->active == TEXTFILTER_DISABLED;
|
||||
$row[] = $OUTPUT->render($select);
|
||||
|
||||
|
||||
+1336
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,790 @@
|
||||
<?php
|
||||
|
||||
ob_start(); //for whitespace test
|
||||
require_once('../config.php');
|
||||
|
||||
// extra whitespace test - intentionally breaks cookieless mode
|
||||
$extraws = '';
|
||||
while (ob_get_level()) {
|
||||
$extraws .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('healthcenter');
|
||||
|
||||
define('SEVERITY_NOTICE', 'notice');
|
||||
define('SEVERITY_ANNOYANCE', 'annoyance');
|
||||
define('SEVERITY_SIGNIFICANT', 'significant');
|
||||
define('SEVERITY_CRITICAL', 'critical');
|
||||
|
||||
$solution = optional_param('solution', 0, PARAM_SAFEDIR); //in fact it is class name alhanumeric and _
|
||||
|
||||
require_login();
|
||||
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
|
||||
|
||||
$site = get_site();
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
echo <<<STYLES
|
||||
<style type="text/css">
|
||||
div#healthnoproblemsfound {
|
||||
width: 60%;
|
||||
margin: auto;
|
||||
padding: 1em;
|
||||
border: 1px black solid;
|
||||
-moz-border-radius: 6px;
|
||||
}
|
||||
dl.healthissues {
|
||||
width: 60%;
|
||||
margin: auto;
|
||||
}
|
||||
dl.critical dt, dl.critical dd {
|
||||
background-color: #a71501;
|
||||
}
|
||||
dl.significant dt, dl.significant dd {
|
||||
background-color: #d36707;
|
||||
}
|
||||
dl.annoyance dt, dl.annoyance dd {
|
||||
background-color: #dba707;
|
||||
}
|
||||
dl.notice dt, dl.notice dd {
|
||||
background-color: #e5db36;
|
||||
}
|
||||
dt.solution, dd.solution, div#healthnoproblemsfound {
|
||||
background-color: #5BB83E !important;
|
||||
}
|
||||
dl.healthissues dt, dl.healthissues dd {
|
||||
margin: 0px;
|
||||
padding: 1em;
|
||||
border: 1px black solid;
|
||||
}
|
||||
dl.healthissues dt {
|
||||
font-weight: bold;
|
||||
border-bottom: none;
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
dl.healthissues dd {
|
||||
border-top: none;
|
||||
padding-top: 0.5em;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
dl.healthissues dd form {
|
||||
margin-top: 0.5em;
|
||||
text-align: right;
|
||||
}
|
||||
form#healthformreturn {
|
||||
text-align: center;
|
||||
margin: 2em;
|
||||
}
|
||||
dd.solution p {
|
||||
padding: 0px;
|
||||
margin: 1em 0px;
|
||||
}
|
||||
dd.solution li {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
</style>
|
||||
STYLES;
|
||||
|
||||
if(strpos($solution, 'problem_') === 0 && class_exists($solution)) {
|
||||
health_print_solution($solution);
|
||||
}
|
||||
else {
|
||||
health_find_problems();
|
||||
}
|
||||
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
|
||||
function health_find_problems() {
|
||||
global $OUTPUT;
|
||||
|
||||
echo $OUTPUT->heading(get_string('healthcenter'));
|
||||
|
||||
$issues = array(
|
||||
SEVERITY_CRITICAL => array(),
|
||||
SEVERITY_SIGNIFICANT => array(),
|
||||
SEVERITY_ANNOYANCE => array(),
|
||||
SEVERITY_NOTICE => array(),
|
||||
);
|
||||
$problems = 0;
|
||||
|
||||
for($i = 1; $i < 1000000; ++$i) {
|
||||
$classname = sprintf('problem_%06d', $i);
|
||||
if(!class_exists($classname)) {
|
||||
break;
|
||||
}
|
||||
$problem = new $classname;
|
||||
if($problem->exists()) {
|
||||
$severity = $problem->severity();
|
||||
$issues[$severity][$classname] = array(
|
||||
'severity' => $severity,
|
||||
'description' => $problem->description(),
|
||||
'title' => $problem->title()
|
||||
);
|
||||
++$problems;
|
||||
}
|
||||
unset($problem);
|
||||
}
|
||||
|
||||
if($problems == 0) {
|
||||
echo '<div id="healthnoproblemsfound">';
|
||||
echo get_string('healthnoproblemsfound');
|
||||
echo '</div>';
|
||||
}
|
||||
else {
|
||||
echo $OUTPUT->heading(get_string('healthproblemsdetected'));
|
||||
$severities = array(SEVERITY_CRITICAL, SEVERITY_SIGNIFICANT, SEVERITY_ANNOYANCE, SEVERITY_NOTICE);
|
||||
foreach($severities as $severity) {
|
||||
if(!empty($issues[$severity])) {
|
||||
echo '<dl class="healthissues '.$severity.'">';
|
||||
foreach($issues[$severity] as $classname => $data) {
|
||||
echo '<dt id="'.$classname.'">'.$data['title'].'</dt>';
|
||||
echo '<dd>'.$data['description'];
|
||||
echo '<form action="health.php#solution" method="get">';
|
||||
echo '<input type="hidden" name="solution" value="'.$classname.'" /><input type="submit" value="'.get_string('viewsolution').'" />';
|
||||
echo '</form></dd>';
|
||||
}
|
||||
echo '</dl>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function health_print_solution($classname) {
|
||||
global $OUTPUT;
|
||||
$problem = new $classname;
|
||||
$data = array(
|
||||
'title' => $problem->title(),
|
||||
'severity' => $problem->severity(),
|
||||
'description' => $problem->description(),
|
||||
'solution' => $problem->solution()
|
||||
);
|
||||
|
||||
echo $OUTPUT->heading(get_string('healthcenter'));
|
||||
echo $OUTPUT->heading(get_string('healthproblemsolution'));
|
||||
echo '<dl class="healthissues '.$data['severity'].'">';
|
||||
echo '<dt>'.$data['title'].'</dt>';
|
||||
echo '<dd>'.$data['description'].'</dd>';
|
||||
echo '<dt id="solution" class="solution">'.get_string('healthsolution').'</dt>';
|
||||
echo '<dd class="solution">'.$data['solution'].'</dd></dl>';
|
||||
echo '<form id="healthformreturn" action="health.php#'.$classname.'" method="get">';
|
||||
echo '<input type="submit" value="'.get_string('healthreturntomain').'" />';
|
||||
echo '</form>';
|
||||
}
|
||||
|
||||
class problem_base {
|
||||
function exists() {
|
||||
return false;
|
||||
}
|
||||
function title() {
|
||||
return '???';
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_NOTICE;
|
||||
}
|
||||
function description() {
|
||||
return '';
|
||||
}
|
||||
function solution() {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000002 extends problem_base {
|
||||
function title() {
|
||||
return 'Extra characters at the end of config.php or other library function';
|
||||
}
|
||||
function exists() {
|
||||
global $extraws;
|
||||
|
||||
if($extraws === '') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_SIGNIFICANT;
|
||||
}
|
||||
function description() {
|
||||
return 'Your Moodle configuration file config.php or another library file, contains some characters after the closing PHP tag (?>). This causes Moodle to exhibit several kinds of problems (such as broken downloaded files) and must be fixed.';
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
return 'You need to edit <strong>'.$CFG->dirroot.'/config.php</strong> and remove all characters (including spaces and returns) after the ending ?> tag. These two characters should be the very last in that file. The extra trailing whitespace may be also present in other PHP files that are included from lib/setup.php.';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000003 extends problem_base {
|
||||
function title() {
|
||||
return '$CFG->dataroot does not exist or does not have write permissions';
|
||||
}
|
||||
function exists() {
|
||||
global $CFG;
|
||||
if(!is_dir($CFG->dataroot) || !is_writable($CFG->dataroot)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_SIGNIFICANT;
|
||||
}
|
||||
function description() {
|
||||
global $CFG;
|
||||
return 'Your <strong>config.php</strong> says that your "data root" directory is <strong>'.$CFG->dataroot.'</strong>. However, this directory either does not exist or cannot be written to by Moodle. This means that a variety of problems will be present, such as users not being able to log in and not being able to upload any files. It is imperative that you address this problem for Moodle to work correctly.';
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
return 'First of all, make sure that the directory <strong>'.$CFG->dataroot.'</strong> exists. If the directory does exist, then you must make sure that Moodle is able to write to it. Contact your web server administrator and request that he gives write permissions for that directory to the user that the web server process is running as.';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000004 extends problem_base {
|
||||
function title() {
|
||||
return 'cron.php is not set up to run automatically';
|
||||
}
|
||||
function exists() {
|
||||
global $DB;
|
||||
$lastcron = $DB->get_field_sql('SELECT max(lastcron) FROM {modules}');
|
||||
return (time() - $lastcron > 3600 * 24);
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_SIGNIFICANT;
|
||||
}
|
||||
function description() {
|
||||
return 'The cron.php mainenance script has not been run in the past 24 hours. This probably means that your server is not configured to automatically run this script in regular time intervals. If this is the case, then Moodle will mostly work as it should but some operations (notably sending email to users) will not be carried out at all.';
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
return 'For detailed instructions on how to enable cron, see <a href="'.$CFG->wwwroot.'/doc/?file=install.html#cron">this section</a> of the installation manual.';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000005 extends problem_base {
|
||||
function title() {
|
||||
return 'PHP: session.auto_start is enabled';
|
||||
}
|
||||
function exists() {
|
||||
return ini_get_bool('session.auto_start');
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_CRITICAL;
|
||||
}
|
||||
function description() {
|
||||
return 'Your PHP configuration includes an enabled setting, session.auto_start, that <strong>must be disabled</strong> in order for Moodle to work correctly. Notable symptoms arising from this misconfiguration include fatal errors and/or blank pages when trying to log in.';
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
return '<p>There are two ways you can solve this problem:</p><ol><li>If you have access to your main <strong>php.ini</strong> file, then find the line that looks like this: <pre>session.auto_start = 1</pre> and change it to <pre>session.auto_start = 0</pre> and then restart your web server. Be warned that this, as any other PHP setting change, might affect other web applications running on the server.</li><li>Finally, you may be able to change this setting just for your site by creating or editing the file <strong>'.$CFG->dirroot.'/.htaccess</strong> to contain this line: <pre>php_value session.auto_start "0"</pre></li></ol>';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000006 extends problem_base {
|
||||
function title() {
|
||||
return 'PHP: magic_quotes_runtime is enabled';
|
||||
}
|
||||
function exists() {
|
||||
return (ini_get_bool('magic_quotes_runtime'));
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_SIGNIFICANT;
|
||||
}
|
||||
function description() {
|
||||
return 'Your PHP configuration includes an enabled setting, magic_quotes_runtime, that <strong>must be disabled</strong> in order for Moodle to work correctly. Notable symptoms arising from this misconfiguration include strange display errors whenever a text field that includes single or double quotes is processed.';
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
return '<p>There are two ways you can solve this problem:</p><ol><li>If you have access to your main <strong>php.ini</strong> file, then find the line that looks like this: <pre>magic_quotes_runtime = On</pre> and change it to <pre>magic_quotes_runtime = Off</pre> and then restart your web server. Be warned that this, as any other PHP setting change, might affect other web applications running on the server.</li><li>Finally, you may be able to change this setting just for your site by creating or editing the file <strong>'.$CFG->dirroot.'/.htaccess</strong> to contain this line: <pre>php_value magic_quotes_runtime "Off"</pre></li></ol>';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000007 extends problem_base {
|
||||
function title() {
|
||||
return 'PHP: file_uploads is disabled';
|
||||
}
|
||||
function exists() {
|
||||
return !ini_get_bool('file_uploads');
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_SIGNIFICANT;
|
||||
}
|
||||
function description() {
|
||||
return 'Your PHP configuration includes a disabled setting, file_uploads, that <strong>must be enabled</strong> to let Moodle offer its full functionality. Until this setting is enabled, it will not be possible to upload any files into Moodle. This includes, for example, course content and user pictures.';
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
return '<p>There are two ways you can solve this problem:</p><ol><li>If you have access to your main <strong>php.ini</strong> file, then find the line that looks like this: <pre>file_uploads = Off</pre> and change it to <pre>file_uploads = On</pre> and then restart your web server. Be warned that this, as any other PHP setting change, might affect other web applications running on the server.</li><li>Finally, you may be able to change this setting just for your site by creating or editing the file <strong>'.$CFG->dirroot.'/.htaccess</strong> to contain this line: <pre>php_value file_uploads "On"</pre></li></ol>';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000008 extends problem_base {
|
||||
function title() {
|
||||
return 'PHP: memory_limit cannot be controlled by Moodle';
|
||||
}
|
||||
function exists() {
|
||||
global $CFG;
|
||||
|
||||
$oldmemlimit = @ini_get('memory_limit');
|
||||
if (empty($oldmemlimit)) {
|
||||
// PHP not compiled with memory limits, this means that it's
|
||||
// probably limited to 8M or in case of Windows not at all.
|
||||
// We can ignore it for now - there is not much to test anyway
|
||||
// TODO: add manual test that fills memory??
|
||||
return false;
|
||||
}
|
||||
$oldmemlimit = get_real_size($oldmemlimit);
|
||||
//now lets change the memory limit to something higher
|
||||
$newmemlimit = ($oldmemlimit + 1024*1024*5);
|
||||
raise_memory_limit($newmemlimit);
|
||||
$testmemlimit = get_real_size(@ini_get('memory_limit'));
|
||||
//verify the change had any effect at all
|
||||
if ($oldmemlimit == $testmemlimit) {
|
||||
//memory limit can not be changed - is it big enough then?
|
||||
if ($oldmemlimit < get_real_size('128M')) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
reduce_memory_limit($oldmemlimit);
|
||||
return false;
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_NOTICE;
|
||||
}
|
||||
function description() {
|
||||
return 'The settings for PHP on your server do not allow a script to request more memory during its execution. '.
|
||||
'This means that there is a hard limit of '.@ini_get('memory_limit').' for each script. '.
|
||||
'It is possible that certain operations within Moodle will require more than this amount in order '.
|
||||
'to complete successfully, especially if there are lots of data to be processed.';
|
||||
}
|
||||
function solution() {
|
||||
return 'It is recommended that you contact your web server administrator to address this issue.';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000009 extends problem_base {
|
||||
function title() {
|
||||
return 'SQL: using account without password';
|
||||
}
|
||||
function exists() {
|
||||
global $CFG;
|
||||
return empty($CFG->dbpass);
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_CRITICAL;
|
||||
}
|
||||
function description() {
|
||||
global $CFG;
|
||||
return 'The user account your are connecting to the database server with is set up without a password. This is a very big security risk and is only somewhat lessened if your database is configured to not accept connections from any hosts other than the server Moodle is running on. Unless you use a strong password to connect to the database, you risk unauthorized access to and manipulation of your data.'.($CFG->dbuser != 'root'?'':' <strong>This is especially alarming because such access to the database would be as the superuser (root)!</strong>');
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
return 'You should change the password of the user <strong>'.$CFG->dbuser.'</strong> both in your database and in your Moodle <strong>config.php</strong> immediately!'.($CFG->dbuser != 'root'?'':' It would also be a good idea to change the user account from root to something else, because this would lessen the impact in the event that your database is compromised anyway.');
|
||||
}
|
||||
}
|
||||
/* // not implemented in 2.0 yet
|
||||
class problem_000010 extends problem_base {
|
||||
function title() {
|
||||
return 'Uploaded files: slasharguments disabled or not working';
|
||||
}
|
||||
function exists() {
|
||||
if (!$this->is_enabled()) {
|
||||
return true;
|
||||
}
|
||||
if ($this->status() < 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function severity() {
|
||||
if ($this->is_enabled() and $this->status() == 0) {
|
||||
return SEVERITY_SIGNIFICANT;
|
||||
} else {
|
||||
return SEVERITY_ANNOYANCE;
|
||||
}
|
||||
}
|
||||
function description() {
|
||||
global $CFG;
|
||||
$desc = 'Slasharguments are needed for relative linking in uploaded resources:<ul>';
|
||||
if (!$this->is_enabled()) {
|
||||
$desc .= '<li>slasharguments are <strong>disabled</strong> in Moodle configuration</li>';
|
||||
} else {
|
||||
$desc .= '<li>slasharguments are enabled in Moodle configuration</li>';
|
||||
}
|
||||
if ($this->status() == -1) {
|
||||
$desc .= '<li>can not run automatic test, you can verify it <a href="'.$CFG->wwwroot.'/file.php/testslasharguments" target="_blank">here</a> manually</li>';
|
||||
} else if ($this->status() == 0) {
|
||||
$desc .= '<li>slashargument test <strong>failed</strong>, please check server configuration</li>';
|
||||
} else {
|
||||
$desc .= '<li>slashargument test passed</li>';
|
||||
}
|
||||
$desc .= '</ul>';
|
||||
return $desc;
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
$enabled = $this->is_enabled();
|
||||
$status = $this->status();
|
||||
$solution = '';
|
||||
if ($enabled and ($status == 0)) {
|
||||
$solution .= 'Slasharguments are enabled, but the test failed. Please disable slasharguments in Moodle configuration or fix the server configuration.<hr />';
|
||||
} else if ((!$enabled) and ($status == 0)) {
|
||||
$solution .= 'Slasharguments are disabled and the test failed. You may try to fix the server configuration.<hr />';
|
||||
} else if ($enabled and ($status == -1)) {
|
||||
$solution .= 'Slasharguments are enabled, <a href="'.$CFG->wwwroot.'/file.php/testslasharguments">automatic testing</a> not possible.<hr />';
|
||||
} else if ((!$enabled) and ($status == -1)) {
|
||||
$solution .= 'Slasharguments are disabled, <a href="'.$CFG->wwwroot.'/file.php/testslasharguments">automatic testing</a> not possible.<hr />';
|
||||
} else if ((!$enabled) and ($status > 0)) {
|
||||
$solution .= 'Slasharguments are disabled though the iternal test is OK. You should enable slasharguments in Moodle configuration.';
|
||||
} else if ($enabled and ($status > 0)) {
|
||||
$solution .= 'Congratulations - everything seems OK now :-D';
|
||||
}
|
||||
if ($status < 1) {
|
||||
$solution .= '<p>IIS:<ul><li>try to add <code>cgi.fix_pathinfo=1</code> to php.ini</li><li>do NOT enable AllowPathInfoForScriptMappings !!!</li><li>slasharguments may not work when using ISAPI and PHP 4.3.10 and older</li></ul></p>';
|
||||
$solution .= '<p>Apache 1:<ul><li>try to add <code>cgi.fix_pathinfo=1</code> to php.ini</li></ul></p>';
|
||||
$solution .= '<p>Apache 2:<ul><li>you must add <code>AcceptPathInfo on</code> to php.ini or .htaccess</li><li>try to add <code>cgi.fix_pathinfo=1</code> to php.ini</li></ul></p>';
|
||||
}
|
||||
return $solution;
|
||||
}
|
||||
function is_enabled() {
|
||||
global $CFG;
|
||||
return !empty($CFG->slasharguments);
|
||||
}
|
||||
function status() {
|
||||
global $CFG;
|
||||
$handle = @fopen($CFG->wwwroot.'/file.php?file=/testslasharguments', "r");
|
||||
$contents = @trim(fread($handle, 10));
|
||||
@fclose($handle);
|
||||
if ($contents != 'test -1') {
|
||||
return -1;
|
||||
}
|
||||
$handle = @fopen($CFG->wwwroot.'/file.php/testslasharguments', "r");
|
||||
$contents = trim(@fread($handle, 10));
|
||||
@fclose($handle);
|
||||
switch ($contents) {
|
||||
case 'test 1': return 1;
|
||||
case 'test 2': return 2;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
class problem_000012 extends problem_base {
|
||||
function title() {
|
||||
return 'Random questions data consistency';
|
||||
}
|
||||
function exists() {
|
||||
global $DB;
|
||||
return $DB->record_exists_select('question', "qtype = 'random' AND parent <> id", array());
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_ANNOYANCE;
|
||||
}
|
||||
function description() {
|
||||
return '<p>For random questions, question.parent should equal question.id. ' .
|
||||
'There are some questions in your database for which this is not true. ' .
|
||||
'One way that this could have happened is for random questions restored from backup before ' .
|
||||
'<a href="http://tracker.moodle.org/browse/MDL-5482">MDL-5482</a> was fixed.</p>';
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
return '<p>Upgrade to Moodle 1.9.1 or later, or manually execute the SQL</p>' .
|
||||
'<pre>UPDATE ' . $CFG->prefix . 'question SET parent = id WHERE qtype = \'random\' and parent <> id;</pre>';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000013 extends problem_base {
|
||||
function title() {
|
||||
return 'Multi-answer questions data consistency';
|
||||
}
|
||||
function exists() {
|
||||
global $DB;
|
||||
$positionexpr = $DB->sql_position($DB->sql_concat("','", "q.id", "','"),
|
||||
$DB->sql_concat("','", "qma.sequence", "','"));
|
||||
return $DB->record_exists_sql("
|
||||
SELECT * FROM {question} q
|
||||
JOIN {question_multianswer} qma ON $positionexpr > 0
|
||||
WHERE qma.question <> q.parent") ||
|
||||
$DB->record_exists_sql("
|
||||
SELECT * FROM {question} q
|
||||
JOIN {question} parent_q ON parent_q.id = q.parent
|
||||
WHERE q.category <> parent_q.category");
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_ANNOYANCE;
|
||||
}
|
||||
function description() {
|
||||
return '<p>For each sub-question whose id is listed in ' .
|
||||
'question_multianswer.sequence, its question.parent field should equal ' .
|
||||
'question_multianswer.question; and each sub-question should be in the same ' .
|
||||
'category as its parent. There are questions in your database for ' .
|
||||
'which this is not the case. One way that this could have happened is ' .
|
||||
'for multi-answer questions restored from backup before ' .
|
||||
'<a href="http://tracker.moodle.org/browse/MDL-14750">MDL-14750</a> was fixed.</p>';
|
||||
}
|
||||
function solution() {
|
||||
return '<p>Upgrade to Moodle 1.9.1 or later, or manually execute the ' .
|
||||
'code in question_multianswer_fix_subquestion_parents_and_categories in ' .
|
||||
'<a href="http://cvs.moodle.org/moodle/question/type/multianswer/db/upgrade.php?revision=1.1.10.2&view=markup">/question/type/multianswer/db/upgrade.php' .
|
||||
'from the 1.9 stable branch</a>.</p>';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000014 extends problem_base {
|
||||
function title() {
|
||||
return 'Only multianswer and random questions should be the parent of another question';
|
||||
}
|
||||
function exists() {
|
||||
global $DB;
|
||||
return $DB->record_exists_sql("
|
||||
SELECT * FROM {question} q
|
||||
JOIN {question} parent_q ON parent_q.id = q.parent
|
||||
WHERE parent_q.qtype NOT IN ('random', 'multianswer')");
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_ANNOYANCE;
|
||||
}
|
||||
function description() {
|
||||
return '<p>You have questions that violate this in your databse. ' .
|
||||
'You will need to investigate to determine how this happened.</p>';
|
||||
}
|
||||
function solution() {
|
||||
return '<p>It is impossible to give a solution without knowing more about ' .
|
||||
' how the problem was caused. You may be able to get help from the ' .
|
||||
'<a href="http://moodle.org/mod/forum/view.php?f=121">Quiz forum</a>.</p>';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000015 extends problem_base {
|
||||
function title() {
|
||||
return 'Question categories should belong to a valid context';
|
||||
}
|
||||
function exists() {
|
||||
global $DB;
|
||||
return $DB->record_exists_sql("
|
||||
SELECT qc.*, (SELECT COUNT(1) FROM {question} q WHERE q.category = qc.id) AS numquestions
|
||||
FROM {question_categories} qc
|
||||
LEFT JOIN {context} con ON qc.contextid = con.id
|
||||
WHERE con.id IS NULL");
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_ANNOYANCE;
|
||||
}
|
||||
function description() {
|
||||
global $DB;
|
||||
$problemcategories = $DB->get_records_sql("
|
||||
SELECT qc.id, qc.name, qc.contextid, (SELECT COUNT(1) FROM {question} q WHERE q.category = qc.id) AS numquestions
|
||||
FROM {question_categories} qc
|
||||
LEFT JOIN {context} con ON qc.contextid = con.id
|
||||
WHERE con.id IS NULL
|
||||
ORDER BY numquestions DESC, qc.name");
|
||||
$table = '<table><thead><tr><th>Cat id</th><th>Category name</th>' .
|
||||
"<th>Context id</th><th>Num Questions</th></tr></thead><tbody>\n";
|
||||
foreach ($problemcategories as $cat) {
|
||||
$table .= "<tr><td>$cat->id</td><td>" . s($cat->name) . "</td><td>" .
|
||||
$cat->contextid ."</td><td>$cat->numquestions</td></tr>\n";
|
||||
}
|
||||
$table .= '</tbody></table>';
|
||||
return '<p>All question categories are linked to a context id, and, ' .
|
||||
'the context they are linked to must exist. The following categories ' .
|
||||
'belong to a non-existant category:</p>' . $table . '<p>Any of these ' .
|
||||
'categories that contain no questions can just be deleted form the database. ' .
|
||||
'Other categories will require more thought.</p>';
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
return '<p>You can delete the empty categories by executing the following SQL:</p><pre>
|
||||
DELETE FROM ' . $CFG->prefix . 'question_categories
|
||||
WHERE
|
||||
NOT EXISTS (SELECT * FROM ' . $CFG->prefix . 'question q WHERE q.category = ' . $CFG->prefix . 'question_categories.id)
|
||||
AND NOT EXISTS (SELECT * FROM ' . $CFG->prefix . 'context con WHERE contextid = con.id)
|
||||
</pre><p>Any remaining categories that contain questions will require more thought. ' .
|
||||
'People in the <a href="http://moodle.org/mod/forum/view.php?f=121">Quiz forum</a> may be able to help.</p>';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000016 extends problem_base {
|
||||
function title() {
|
||||
return 'Question categories should belong to the same context as their parent';
|
||||
}
|
||||
function exists() {
|
||||
global $DB;
|
||||
return $DB->record_exists_sql("
|
||||
SELECT parent_qc.id AS parent, child_qc.id AS child, child_qc.contextid
|
||||
FROM {question_categories} child_qc
|
||||
JOIN {question_categories} parent_qc ON child_qc.parent = parent_qc.id
|
||||
WHERE child_qc.contextid <> parent_qc.contextid");
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_ANNOYANCE;
|
||||
}
|
||||
function description() {
|
||||
global $DB;
|
||||
$problemcategories = $DB->get_records_sql("
|
||||
SELECT
|
||||
parent_qc.id AS parentid, parent_qc.name AS parentname, parent_qc.contextid AS parentcon,
|
||||
child_qc.id AS childid, child_qc.name AS childname, child_qc.contextid AS childcon
|
||||
FROM {question_categories} child_qc
|
||||
JOIN {question_categories} parent_qc ON child_qc.parent = parent_qc.id
|
||||
WHERE child_qc.contextid <> parent_qc.contextid");
|
||||
$table = '<table><thead><tr><th colspan="3">Child category</th><th colspan="3">Parent category</th></tr><tr>' .
|
||||
'<th>Id</th><th>Name</th><th>Context id</th>' .
|
||||
'<th>Id</th><th>Name</th><th>Context id</th>' .
|
||||
"</tr></thead><tbody>\n";
|
||||
foreach ($problemcategories as $cat) {
|
||||
$table .= "<tr><td>$cat->childid</td><td>" . s($cat->childname) .
|
||||
"</td><td>$cat->childcon</td><td>$cat->parentid</td><td>" . s($cat->parentname) .
|
||||
"</td><td>$cat->parentcon</td></tr>\n";
|
||||
}
|
||||
$table .= '</tbody></table>';
|
||||
return '<p>When one question category is the parent of another, then they ' .
|
||||
'should both belong to the same context. This is not true for the following categories:</p>' .
|
||||
$table;
|
||||
}
|
||||
function solution() {
|
||||
return '<p>An automated solution is difficult. It depends whether the ' .
|
||||
'parent or child category is in the wrong pace.' .
|
||||
'People in the <a href="http://moodle.org/mod/forum/view.php?f=121">Quiz forum</a> may be able to help.</p>';
|
||||
}
|
||||
}
|
||||
|
||||
class problem_000017 extends problem_base {
|
||||
function title() {
|
||||
return 'Question categories tree structure';
|
||||
}
|
||||
function find_problems() {
|
||||
global $DB;
|
||||
static $answer = null;
|
||||
|
||||
if (is_null($answer)) {
|
||||
$categories = $DB->get_records('question_categories', array(), 'id');
|
||||
|
||||
// Look for missing parents.
|
||||
$missingparent = array();
|
||||
foreach ($categories as $category) {
|
||||
if ($category->parent != 0 && !array_key_exists($category->parent, $categories)) {
|
||||
$missingparent[$category->id] = $category;
|
||||
}
|
||||
}
|
||||
|
||||
// Look for loops.
|
||||
$loops = array();
|
||||
while (!empty($categories)) {
|
||||
$current = array_pop($categories);
|
||||
$thisloop = array($current->id => $current);
|
||||
while (true) {
|
||||
if (isset($thisloop[$current->parent])) {
|
||||
// Loop detected
|
||||
$loops[$current->id] = $thisloop;
|
||||
break;
|
||||
} else if (!isset($categories[$current->parent])) {
|
||||
// Got to the top level, or a category we already know is OK.
|
||||
break;
|
||||
} else {
|
||||
// Continue following the path.
|
||||
$current = $categories[$current->parent];
|
||||
$thisloop[$current->id] = $current;
|
||||
unset($categories[$current->id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$answer = array($missingparent, $loops);
|
||||
}
|
||||
|
||||
return $answer;
|
||||
}
|
||||
function exists() {
|
||||
list($missingparent, $loops) = $this->find_problems();
|
||||
return !empty($missingparent) || !empty($loops);
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_ANNOYANCE;
|
||||
}
|
||||
function description() {
|
||||
list($missingparent, $loops) = $this->find_problems();
|
||||
|
||||
$description = '<p>The question categories should be arranged into tree ' .
|
||||
' structures by the question_categories.parent field. Sometimes ' .
|
||||
' this tree structure gets messed up.</p>';
|
||||
|
||||
if (!empty($missingparent)) {
|
||||
$description .= '<p>The following categories are missing their parents:</p><ul>';
|
||||
foreach ($missingparent as $cat) {
|
||||
$description .= "<li>Category $cat->id: " . s($cat->name) . "</li>\n";
|
||||
}
|
||||
$description .= "</ul>\n";
|
||||
}
|
||||
|
||||
if (!empty($loops)) {
|
||||
$description .= '<p>The following categories form a loop of parents:</p><ul>';
|
||||
foreach ($loops as $loop) {
|
||||
$description .= "<li><ul>\n";
|
||||
foreach ($loop as $cat) {
|
||||
$description .= "<li>Category $cat->id: " . s($cat->name) . " has parent $cat->parent</li>\n";
|
||||
}
|
||||
$description .= "</ul></li>\n";
|
||||
}
|
||||
$description .= "</ul>\n";
|
||||
}
|
||||
|
||||
return $description;
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
list($missingparent, $loops) = $this->find_problems();
|
||||
|
||||
$solution = '<p>Consider executing the following SQL queries. These fix ' .
|
||||
'the problem by moving some categories to the top level.</p>';
|
||||
|
||||
if (!empty($missingparent)) {
|
||||
$solution .= "<pre>UPDATE " . $CFG->prefix . "question_categories\n" .
|
||||
" SET parent = 0\n" .
|
||||
" WHERE id IN (" . implode(',', array_keys($missingparent)) . ");</pre>\n";
|
||||
}
|
||||
|
||||
if (!empty($loops)) {
|
||||
$solution .= "<pre>UPDATE " . $CFG->prefix . "question_categories\n" .
|
||||
" SET parent = 0\n" .
|
||||
" WHERE id IN (" . implode(',', array_keys($loops)) . ");</pre>\n";
|
||||
}
|
||||
|
||||
return $solution;
|
||||
}
|
||||
}
|
||||
|
||||
class problem_00000x extends problem_base {
|
||||
function title() {
|
||||
return '';
|
||||
}
|
||||
function exists() {
|
||||
return false;
|
||||
}
|
||||
function severity() {
|
||||
return SEVERITY_SIGNIFICANT;
|
||||
}
|
||||
function description() {
|
||||
return '';
|
||||
}
|
||||
function solution() {
|
||||
global $CFG;
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
session.save_path -- it doesn't really matter because we are already IN a session, right?
|
||||
detect unsupported characters in $CFG->wwwroot - see bug Bug #6091 - relative vs absolute path during backup/restore process
|
||||
|
||||
*/
|
||||
|
||||
|
||||
+173
-75
@@ -26,7 +26,7 @@
|
||||
// Check that config.php exists, if not then call the install script
|
||||
if (!file_exists('../config.php')) {
|
||||
header('Location: ../install.php');
|
||||
die();
|
||||
die;
|
||||
}
|
||||
|
||||
// Check that PHP is of a sufficient version as soon as possible
|
||||
@@ -35,19 +35,7 @@ if (version_compare(phpversion(), '5.3.2') < 0) {
|
||||
// do NOT localise - lang strings would not work here and we CAN NOT move it to later place
|
||||
echo "Moodle 2.1 or later requires at least PHP 5.3.2 (currently using version $phpversion).<br />";
|
||||
echo "Please upgrade your server software or install older Moodle version.";
|
||||
die();
|
||||
}
|
||||
|
||||
// make sure iconv is available and actually works
|
||||
if (!function_exists('iconv')) {
|
||||
// this should not happen, this must be very borked install
|
||||
echo 'Moodle requires the iconv PHP extension. Please install or enable the iconv extension.';
|
||||
die();
|
||||
}
|
||||
if (iconv('UTF-8', 'UTF-8//IGNORE', 'abc') !== 'abc') {
|
||||
// known to be broken in mid-2011 MAMP installations
|
||||
echo 'Broken iconv PHP extension detected, installation/upgrade can not continue.';
|
||||
die();
|
||||
die;
|
||||
}
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
@@ -87,6 +75,9 @@ if (is_float_problem()) {
|
||||
}
|
||||
|
||||
// Set some necessary variables during set-up to avoid PHP warnings later on this page
|
||||
if (!isset($CFG->framename)) {
|
||||
$CFG->framename = '_top';
|
||||
}
|
||||
if (!isset($CFG->release)) {
|
||||
$CFG->release = '';
|
||||
}
|
||||
@@ -103,11 +94,6 @@ if (!$version or !$release) {
|
||||
print_error('withoutversion', 'debug'); // without version, stop
|
||||
}
|
||||
|
||||
if (!isset($maturity)) {
|
||||
// Fallback for now. Should probably be removed in the future.
|
||||
$maturity = MATURITY_STABLE;
|
||||
}
|
||||
|
||||
// Turn off xmlstrictheaders during upgrade.
|
||||
$origxmlstrictheaders = !empty($CFG->xmlstrictheaders);
|
||||
$CFG->xmlstrictheaders = false;
|
||||
@@ -126,43 +112,65 @@ if (!core_tables_exist()) {
|
||||
|
||||
if (empty($agreelicense)) {
|
||||
$strlicense = get_string('license');
|
||||
|
||||
$PAGE->navbar->add($strlicense);
|
||||
$PAGE->set_title($strinstallation.' - Moodle '.$CFG->target_release);
|
||||
$PAGE->set_heading($strinstallation);
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->install_licence_page();
|
||||
die();
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading('<a href="http://moodle.org">Moodle</a> - Modular Object-Oriented Dynamic Learning Environment');
|
||||
echo $OUTPUT->heading(get_string('copyrightnotice'));
|
||||
$copyrightnotice = text_to_html(get_string('gpl3'));
|
||||
$copyrightnotice = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $copyrightnotice); // extremely ugly validation hack
|
||||
echo $OUTPUT->box($copyrightnotice, 'copyrightnotice');
|
||||
echo '<br />';
|
||||
$continue = new single_button(new moodle_url('/admin/index.php', array('lang'=>$CFG->lang, 'agreelicense'=>1)), get_string('continue'), 'get');
|
||||
echo $OUTPUT->confirm(get_string('doyouagree'), $continue, "http://docs.moodle.org/dev/License");
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
}
|
||||
if (empty($confirmrelease)) {
|
||||
require_once($CFG->libdir.'/environmentlib.php');
|
||||
list($envstatus, $environment_results) = check_moodle_environment(normalize_version($release), ENV_SELECT_RELEASE);
|
||||
$strcurrentrelease = get_string('currentrelease');
|
||||
|
||||
$PAGE->navbar->add($strcurrentrelease);
|
||||
$PAGE->set_title($strinstallation);
|
||||
$PAGE->set_heading($strinstallation . ' - Moodle ' . $CFG->target_release);
|
||||
$PAGE->set_cacheable(false);
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading("Moodle $release");
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->install_environment_page($maturity, $envstatus, $environment_results, $release);
|
||||
die();
|
||||
if (isset($maturity)) {
|
||||
// main version.php declares moodle code maturity
|
||||
if ($maturity < MATURITY_STABLE) {
|
||||
$maturitylevel = get_string('maturity'.$maturity, 'admin');
|
||||
echo $OUTPUT->box(
|
||||
$OUTPUT->container(get_string('maturitycorewarning', 'admin', $maturitylevel)) .
|
||||
$OUTPUT->container($OUTPUT->doc_link('admin/versions', get_string('morehelp'))),
|
||||
'generalbox maturitywarning');
|
||||
}
|
||||
}
|
||||
|
||||
$releasenoteslink = get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/dev/Releases');
|
||||
$releasenoteslink = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $releasenoteslink); // extremely ugly validation hack
|
||||
echo $OUTPUT->box($releasenoteslink, 'generalbox releasenoteslink');
|
||||
|
||||
require_once($CFG->libdir.'/environmentlib.php');
|
||||
if (!check_moodle_environment(normalize_version($release), $environment_results, true, ENV_SELECT_RELEASE)) {
|
||||
print_upgrade_reload("index.php?agreelicense=1&lang=$CFG->lang");
|
||||
} else {
|
||||
echo $OUTPUT->notification(get_string('environmentok', 'admin'), 'notifysuccess');
|
||||
echo $OUTPUT->continue_button(new moodle_url('/admin/index.php', array('agreelicense'=>1, 'confirmrelease'=>1, 'lang'=>$CFG->lang)));
|
||||
}
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
}
|
||||
|
||||
//TODO: add a page with list of non-standard plugins here
|
||||
|
||||
$strdatabasesetup = get_string('databasesetup');
|
||||
upgrade_init_javascript();
|
||||
|
||||
$PAGE->navbar->add($strdatabasesetup);
|
||||
$PAGE->set_title($strinstallation.' - Moodle '.$CFG->target_release);
|
||||
$PAGE->set_heading($strinstallation);
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->header();
|
||||
echo $OUTPUT->header();
|
||||
|
||||
if (!$DB->setup_is_unicodedb()) {
|
||||
if (!$DB->change_db_encoding()) {
|
||||
@@ -190,45 +198,78 @@ if ($version > $CFG->version) { // upgrade
|
||||
$PAGE->set_pagelayout('maintenance');
|
||||
$PAGE->set_popup_notification_allowed(false);
|
||||
|
||||
if (empty($confirmupgrade)) {
|
||||
$a->oldversion = "$CFG->release ($CFG->version)";
|
||||
$a->newversion = "$release ($version)";
|
||||
$strdatabasechecking = get_string('databasechecking', '', $a);
|
||||
$a->oldversion = "$CFG->release ($CFG->version)";
|
||||
$a->newversion = "$release ($version)";
|
||||
$strdatabasechecking = get_string('databasechecking', '', $a);
|
||||
|
||||
if (empty($confirmupgrade)) {
|
||||
$PAGE->set_title($stradministration);
|
||||
$PAGE->set_heading($strdatabasechecking);
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->upgrade_confirm_page($a->newversion, $maturity);
|
||||
die();
|
||||
echo $OUTPUT->header();
|
||||
if (isset($maturity)) {
|
||||
// main version.php declares moodle code maturity
|
||||
if ($maturity < MATURITY_STABLE) {
|
||||
$maturitylevel = get_string('maturity'.$maturity, 'admin');
|
||||
echo $OUTPUT->box(
|
||||
$OUTPUT->container(get_string('maturitycorewarning', 'admin', $maturitylevel)) .
|
||||
$OUTPUT->container($OUTPUT->doc_link('admin/versions', get_string('morehelp'))),
|
||||
'generalbox maturitywarning');
|
||||
}
|
||||
}
|
||||
$continueurl = new moodle_url('index.php', array('confirmupgrade' => 1));
|
||||
$cancelurl = new moodle_url('index.php');
|
||||
echo $OUTPUT->confirm(get_string('upgradesure', 'admin', $a->newversion), $continueurl, $cancelurl);
|
||||
echo $OUTPUT->footer();
|
||||
exit;
|
||||
|
||||
} else if (empty($confirmrelease)){
|
||||
require_once($CFG->libdir.'/environmentlib.php');
|
||||
list($envstatus, $environment_results) = check_moodle_environment($release, ENV_SELECT_RELEASE);
|
||||
$strcurrentrelease = get_string('currentrelease');
|
||||
|
||||
$PAGE->navbar->add($strcurrentrelease);
|
||||
$PAGE->set_title($strcurrentrelease);
|
||||
$PAGE->set_heading($strcurrentrelease);
|
||||
$PAGE->set_cacheable(false);
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading("Moodle $release");
|
||||
$releasenoteslink = get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/dev/Releases');
|
||||
$releasenoteslink = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $releasenoteslink); // extremely ugly validation hack
|
||||
echo $OUTPUT->box($releasenoteslink);
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->upgrade_environment_page($release, $envstatus, $environment_results);
|
||||
die();
|
||||
require_once($CFG->libdir.'/environmentlib.php');
|
||||
if (!check_moodle_environment($release, $environment_results, true, ENV_SELECT_RELEASE)) {
|
||||
print_upgrade_reload('index.php?confirmupgrade=1');
|
||||
} else {
|
||||
echo $OUTPUT->notification(get_string('environmentok', 'admin'), 'notifysuccess');
|
||||
if (empty($CFG->skiplangupgrade)) {
|
||||
echo $OUTPUT->box_start('generalbox', 'notice');
|
||||
print_string('langpackwillbeupdated', 'admin');
|
||||
echo $OUTPUT->box_end();
|
||||
}
|
||||
echo $OUTPUT->continue_button('index.php?confirmupgrade=1&confirmrelease=1');
|
||||
}
|
||||
|
||||
} else if (empty($confirmplugins)) {
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
|
||||
} elseif (empty($confirmplugins)) {
|
||||
$strplugincheck = get_string('plugincheck');
|
||||
|
||||
$PAGE->navbar->add($strplugincheck);
|
||||
$PAGE->set_title($strplugincheck);
|
||||
$PAGE->set_heading($strplugincheck);
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->upgrade_plugin_check_page(plugin_manager::instance(), $version, $showallplugins,
|
||||
new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1)),
|
||||
new moodle_url('/admin/index.php', array('confirmupgrade'=>1, 'confirmrelease'=>1, 'confirmplugincheck'=>1)));
|
||||
$pluginman = plugin_manager::instance();
|
||||
|
||||
echo $output->header();
|
||||
echo $output->box_start('generalbox');
|
||||
echo $output->container(get_string('pluginchecknotice', 'core_plugin'), 'generalbox', 'notice');
|
||||
echo $output->plugins_check($pluginman->get_plugins(), array('full' => $showallplugins));
|
||||
echo $output->box_end();
|
||||
print_upgrade_reload('index.php?confirmupgrade=1&confirmrelease=1');
|
||||
$button = new single_button(new moodle_url('index.php', array('confirmupgrade'=>1, 'confirmrelease'=>1, 'confirmplugincheck'=>1)), get_string('upgradestart', 'admin'), 'get');
|
||||
$button->class = 'continuebutton';
|
||||
echo $output->render($button);
|
||||
echo $output->footer();
|
||||
die();
|
||||
|
||||
} else {
|
||||
@@ -249,19 +290,26 @@ if (moodle_needs_upgrading()) {
|
||||
if (!$PAGE->headerprinted) {
|
||||
// means core upgrade or installation was not already done
|
||||
if (!$confirmplugins) {
|
||||
$strplugincheck = get_string('plugincheck');
|
||||
|
||||
$PAGE->set_pagelayout('maintenance');
|
||||
$PAGE->set_popup_notification_allowed(false);
|
||||
$strplugincheck = get_string('plugincheck');
|
||||
$PAGE->navbar->add($strplugincheck);
|
||||
$PAGE->set_title($strplugincheck);
|
||||
$PAGE->set_heading($strplugincheck);
|
||||
$PAGE->set_cacheable(false);
|
||||
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->upgrade_plugin_check_page(plugin_manager::instance(), $version, $showallplugins,
|
||||
new moodle_url('/admin/index.php'),
|
||||
new moodle_url('/admin/index.php', array('confirmplugincheck'=>1)));
|
||||
$pluginman = plugin_manager::instance();
|
||||
|
||||
echo $output->header();
|
||||
echo $output->box_start('generalbox');
|
||||
echo $output->container(get_string('pluginchecknotice', 'core_plugin'), 'generalbox', 'notice');
|
||||
echo $output->plugins_check($pluginman->get_plugins(), array('full' => $showallplugins));
|
||||
echo $output->box_end();
|
||||
print_upgrade_reload('index.php');
|
||||
$button = new single_button(new moodle_url('index.php', array('confirmplugincheck'=>1)), get_string('upgradestart', 'admin'), 'get');
|
||||
$button->class = 'continuebutton';
|
||||
echo $output->render($button);
|
||||
echo $output->footer();
|
||||
die();
|
||||
}
|
||||
}
|
||||
@@ -297,8 +345,8 @@ if (during_initial_install()) {
|
||||
}
|
||||
}
|
||||
|
||||
// at this stage there can be only one admin unless more were added by install - users may change username, so do not rely on that
|
||||
$adminuser = get_complete_user_data('id', reset(explode(',', $CFG->siteadmins)));
|
||||
// at this stage there can be only one admin - users may change username, so do not rely on that
|
||||
$adminuser = get_complete_user_data('id', $CFG->siteadmins);
|
||||
|
||||
if ($adminuser->password === 'adminsetuppending') {
|
||||
// prevent installation hijacking
|
||||
@@ -307,7 +355,7 @@ if (during_initial_install()) {
|
||||
}
|
||||
// login user and let him set password and admin details
|
||||
$adminuser->newadminuser = 1;
|
||||
complete_user_login($adminuser);
|
||||
complete_user_login($adminuser, false);
|
||||
redirect("$CFG->wwwroot/user/editadvanced.php?id=$adminuser->id"); // Edit thyself
|
||||
|
||||
} else {
|
||||
@@ -356,14 +404,64 @@ if (any_new_admin_settings($adminroot)){
|
||||
// Everything should now be set up, and the user is an admin
|
||||
|
||||
// Print default admin page with notifications.
|
||||
$errorsdisplayed = defined('WARN_DISPLAY_ERRORS_ENABLED');
|
||||
|
||||
$lastcron = $DB->get_field_sql('SELECT MAX(lastcron) FROM {modules}');
|
||||
$cronoverdue = ($lastcron < time() - 3600 * 24);
|
||||
$dbproblems = $DB->diagnose();
|
||||
$maintenancemode = !empty($CFG->maintenance_enabled);
|
||||
|
||||
admin_externalpage_setup('adminnotifications');
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
|
||||
$cronoverdue, $dbproblems, $maintenancemode);
|
||||
echo $OUTPUT->header();
|
||||
|
||||
// Unstable code warning
|
||||
if (isset($maturity)) {
|
||||
if ($maturity < MATURITY_STABLE) {
|
||||
$maturitylevel = get_string('maturity'.$maturity, 'admin');
|
||||
echo $OUTPUT->box(
|
||||
get_string('maturitycoreinfo', 'admin', $maturitylevel) . ' ' .
|
||||
$OUTPUT->doc_link('admin/versions', get_string('morehelp')),
|
||||
'generalbox adminwarning maturityinfo');
|
||||
}
|
||||
}
|
||||
|
||||
if ($insecuredataroot == INSECURE_DATAROOT_WARNING) {
|
||||
echo $OUTPUT->box(get_string('datarootsecuritywarning', 'admin', $CFG->dataroot), 'generalbox adminwarning');
|
||||
} else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
|
||||
echo $OUTPUT->box(get_string('datarootsecurityerror', 'admin', $CFG->dataroot), 'generalbox adminerror');
|
||||
|
||||
}
|
||||
|
||||
if (defined('WARN_DISPLAY_ERRORS_ENABLED')) {
|
||||
echo $OUTPUT->box(get_string('displayerrorswarning', 'admin'), 'generalbox adminwarning');
|
||||
}
|
||||
|
||||
// If no recently cron run
|
||||
$lastcron = $DB->get_field_sql('SELECT MAX(lastcron) FROM {modules}');
|
||||
if (time() - $lastcron > 3600 * 24) {
|
||||
$helpbutton = $OUTPUT->help_icon('cron', 'admin');
|
||||
echo $OUTPUT->box(get_string('cronwarning', 'admin').' '.$helpbutton, 'generalbox adminwarning');
|
||||
}
|
||||
|
||||
// Hidden bloglevel upgrade
|
||||
$showbloglevelupgrade = ($CFG->bloglevel == BLOG_COURSE_LEVEL || $CFG->bloglevel == BLOG_GROUP_LEVEL) && empty($CFG->bloglevel_upgrade_complete);
|
||||
if ($showbloglevelupgrade) {
|
||||
echo $OUTPUT->box(get_string('bloglevelupgradenotice', 'admin'), 'generalbox adminwarning');
|
||||
}
|
||||
|
||||
// diagnose DB, especially the sloppy MyISAM tables
|
||||
$diagnose = $DB->diagnose();
|
||||
if ($diagnose !== NULL) {
|
||||
echo $OUTPUT->box($diagnose, 'generalbox adminwarning');
|
||||
}
|
||||
|
||||
// Alert if we are currently in maintenance mode
|
||||
if (!empty($CFG->maintenance_enabled)) {
|
||||
echo $OUTPUT->box(get_string('sitemaintenancewarning2', 'admin', "$CFG->wwwroot/$CFG->admin/settings.php?section=maintenancemode"), 'generalbox adminwarning');
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//// IT IS ILLEGAL AND A VIOLATION OF THE GPL TO HIDE, REMOVE OR MODIFY THIS COPYRIGHT NOTICE ///
|
||||
$copyrighttext = '<a href="http://moodle.org/">Moodle</a> '.
|
||||
'<a href="http://docs.moodle.org/dev/Releases" title="'.$CFG->version.'">'.$CFG->release.'</a><br />'.
|
||||
'Copyright © 1999 onwards, Martin Dougiamas<br />'.
|
||||
'and <a href="http://docs.moodle.org/dev/Credits">many other contributors</a>.<br />'.
|
||||
'<a href="http://docs.moodle.org/dev/License">GNU Public License</a>';
|
||||
echo $OUTPUT->box($copyrighttext, 'copyright');
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('toinodb');
|
||||
|
||||
$confirm = optional_param('confirm', 0, PARAM_BOOL);
|
||||
|
||||
require_login();
|
||||
|
||||
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading('Convert all MySQL tables from MYISAM to InnoDB');
|
||||
|
||||
if ($DB->get_dbfamily() != 'mysql') {
|
||||
notice('This function is for MySQL databases only!', 'index.php');
|
||||
}
|
||||
|
||||
if (data_submitted() and $confirm and confirm_sesskey()) {
|
||||
|
||||
echo $OUTPUT->notification('Please be patient and wait for this to complete...', 'notifysuccess');
|
||||
|
||||
if ($tables = $DB->get_tables()) {
|
||||
$DB->set_debug(true);
|
||||
foreach ($tables as $table) {
|
||||
$fulltable = $DB->get_prefix().$table;
|
||||
$DB->change_database_structure("ALTER TABLE $fulltable TYPE=INNODB");
|
||||
}
|
||||
$DB->set_debug(false);
|
||||
}
|
||||
echo $OUTPUT->notification('... done.', 'notifysuccess');
|
||||
echo $OUTPUT->continue_button('index.php');
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
} else {
|
||||
$optionsyes = array('confirm'=>'1', 'sesskey'=>sesskey());
|
||||
$formcontinue = new single_button(new moodle_url('/admin/innodb.php', $optionsyes), get_string('yes'));
|
||||
$formcancel = new single_button(new moodle_url('/admin/index.php'), get_string('no'), 'get');
|
||||
echo $OUTPUT->confirm('Are you sure you want convert all your tables to the InnoDB format?', $formcontinue, $formcancel);
|
||||
echo $OUTPUT->footer();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,341 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Fetches language packages from download.moodle.org server
|
||||
*
|
||||
* Language packages are available at http://download.moodle.org/langpack/
|
||||
* in ZIP format together with a file languages.md5 containing their hashes
|
||||
* and meta info.
|
||||
* Locally, language packs are saved into $CFG->dataroot/lang/
|
||||
*
|
||||
* @package core
|
||||
* @copyright 2005 Yu Zhang
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require_once(dirname(dirname(__FILE__)).'/config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/filelib.php');
|
||||
require_once($CFG->libdir.'/componentlib.class.php');
|
||||
|
||||
admin_externalpage_setup('langimport');
|
||||
|
||||
if (!empty($CFG->skiplangupgrade)) {
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->box(get_string('langimportdisabled', 'admin'));
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
}
|
||||
|
||||
$mode = optional_param('mode', 0, PARAM_INT); // action
|
||||
$pack = optional_param('pack', array(), PARAM_SAFEDIR); // pack to install
|
||||
$uninstalllang = optional_param('uninstalllang', '', PARAM_LANG); // installed pack to uninstall
|
||||
$confirm = optional_param('confirm', 0, PARAM_BOOL); // uninstallation confirmation
|
||||
|
||||
define('INSTALLATION_OF_SELECTED_LANG', 2);
|
||||
define('DELETION_OF_SELECTED_LANG', 4);
|
||||
define('UPDATE_ALL_LANG', 5);
|
||||
|
||||
get_string_manager()->reset_caches();
|
||||
|
||||
$notice_ok = array();
|
||||
$notice_error = array();
|
||||
|
||||
if (($mode == INSTALLATION_OF_SELECTED_LANG) and confirm_sesskey() and !empty($pack)) {
|
||||
set_time_limit(0);
|
||||
make_upload_directory('temp');
|
||||
make_upload_directory('lang');
|
||||
|
||||
$installer = new lang_installer($pack);
|
||||
$results = $installer->run();
|
||||
foreach ($results as $langcode => $langstatus) {
|
||||
switch ($langstatus) {
|
||||
case lang_installer::RESULT_DOWNLOADERROR:
|
||||
$a = new stdClass();
|
||||
$a->url = $installer->lang_pack_url($langcode);
|
||||
$a->dest = $CFG->dataroot.'/lang';
|
||||
print_error('remotedownloaderror', 'error', 'langimport.php', $a);
|
||||
break;
|
||||
case lang_installer::RESULT_INSTALLED:
|
||||
$notice_ok[] = get_string('langpackinstalled', 'admin', $langcode);
|
||||
break;
|
||||
case lang_installer::RESULT_UPTODATE:
|
||||
$notice_ok[] = get_string('langpackuptodate', 'admin', $langcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode == DELETION_OF_SELECTED_LANG and !empty($uninstalllang)) {
|
||||
if ($uninstalllang == 'en') {
|
||||
$notice_error[] = 'English language pack can not be uninstalled';
|
||||
|
||||
} else if (!$confirm and confirm_sesskey()) {
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->confirm(get_string('uninstallconfirm', 'admin', $uninstalllang),
|
||||
'langimport.php?mode='.DELETION_OF_SELECTED_LANG.'&uninstalllang='.$uninstalllang.'&confirm=1',
|
||||
'langimport.php');
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
|
||||
} else if (confirm_sesskey()) {
|
||||
$dest1 = $CFG->dataroot.'/lang/'.$uninstalllang;
|
||||
$dest2 = $CFG->dirroot.'/lang/'.$uninstalllang;
|
||||
$rm1 = false;
|
||||
$rm2 = false;
|
||||
if (file_exists($dest1)){
|
||||
$rm1 = remove_dir($dest1);
|
||||
}
|
||||
if (file_exists($dest2)){
|
||||
$rm2 = remove_dir($dest2);
|
||||
}
|
||||
if ($rm1 or $rm2) {
|
||||
$notice_ok[] = get_string('langpackremoved','admin');
|
||||
} else { //nothing deleted, possibly due to permission error
|
||||
$notice_error[] = 'An error has occurred, language pack is not completely uninstalled, please check file permissions';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode == UPDATE_ALL_LANG) {
|
||||
set_time_limit(0);
|
||||
|
||||
$installer = new lang_installer();
|
||||
|
||||
if (!$availablelangs = $installer->get_remote_list_of_languages()) {
|
||||
print_error('cannotdownloadlanguageupdatelist', 'error');
|
||||
}
|
||||
$md5array = array(); // (string)langcode => (string)md5
|
||||
foreach ($availablelangs as $alang) {
|
||||
$md5array[$alang[0]] = $alang[1];
|
||||
}
|
||||
|
||||
// filter out unofficial packs
|
||||
$currentlangs = array_keys(get_string_manager()->get_list_of_translations(true));
|
||||
$updateablelangs = array();
|
||||
foreach ($currentlangs as $clang) {
|
||||
if (!array_key_exists($clang, $md5array)) {
|
||||
$notice_ok[] = get_string('langpackupdateskipped', 'admin', $clang);
|
||||
continue;
|
||||
}
|
||||
$dest1 = $CFG->dataroot.'/lang/'.$clang;
|
||||
$dest2 = $CFG->dirroot.'/lang/'.$clang;
|
||||
|
||||
if (file_exists($dest1.'/langconfig.php') || file_exists($dest2.'/langconfig.php')){
|
||||
$updateablelangs[] = $clang;
|
||||
}
|
||||
}
|
||||
|
||||
// then filter out packs that have the same md5 key
|
||||
$neededlangs = array(); // all the packs that needs updating
|
||||
foreach ($updateablelangs as $ulang) {
|
||||
if (!is_installed_lang($ulang, $md5array[$ulang])) {
|
||||
$neededlangs[] = $ulang;
|
||||
}
|
||||
}
|
||||
|
||||
make_upload_directory('temp');
|
||||
make_upload_directory('lang');
|
||||
|
||||
// clean-up currently installed versions of the packs
|
||||
foreach ($neededlangs as $packindex => $pack) {
|
||||
if ($pack == 'en') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// delete old directories
|
||||
$dest1 = $CFG->dataroot.'/lang/'.$pack;
|
||||
$dest2 = $CFG->dirroot.'/lang/'.$pack;
|
||||
$rm1 = false;
|
||||
$rm2 = false;
|
||||
if (file_exists($dest1)) {
|
||||
if (!remove_dir($dest1)) {
|
||||
$notice_error[] = 'Could not delete old directory '.$dest1.', update of '.$pack.' failed, please check permissions.';
|
||||
unset($neededlangs[$packindex]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (file_exists($dest2)) {
|
||||
if (!remove_dir($dest2)) {
|
||||
$notice_error[] = 'Could not delete old directory '.$dest2.', update of '.$pack.' failed, please check permissions.';
|
||||
unset($neededlangs[$packindex]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// install all needed language packs
|
||||
$installer->set_queue($neededlangs);
|
||||
$results = $installer->run();
|
||||
$updated = false; // any packs updated?
|
||||
foreach ($results as $langcode => $langstatus) {
|
||||
switch ($langstatus) {
|
||||
case lang_installer::RESULT_DOWNLOADERROR:
|
||||
$a = new stdClass();
|
||||
$a->url = $installer->lang_pack_url($langcode);
|
||||
$a->dest = $CFG->dataroot.'/lang';
|
||||
print_error('remotedownloaderror', 'error', 'langimport.php', $a);
|
||||
break;
|
||||
case lang_installer::RESULT_INSTALLED:
|
||||
$updated = true;
|
||||
$notice_ok[] = get_string('langpackinstalled', 'admin', $langcode);
|
||||
break;
|
||||
case lang_installer::RESULT_UPTODATE:
|
||||
$notice_ok[] = get_string('langpackuptodate', 'admin', $langcode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($updated) {
|
||||
$notice_ok[] = get_string('langupdatecomplete','admin');
|
||||
} else {
|
||||
$notice_ok[] = get_string('nolangupdateneeded','admin');
|
||||
}
|
||||
|
||||
unset($installer);
|
||||
}
|
||||
get_string_manager()->reset_caches();
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading(get_string('langimport', 'admin'));
|
||||
|
||||
$installedlangs = get_string_manager()->get_list_of_translations(true);
|
||||
|
||||
$missingparents = array();
|
||||
foreach ($installedlangs as $installedlang => $unused) {
|
||||
$parent = get_parent_language($installedlang);
|
||||
if (empty($parent)) {
|
||||
continue;
|
||||
}
|
||||
if (!isset($installedlangs[$parent])) {
|
||||
$missingparents[$installedlang] = $parent;
|
||||
}
|
||||
}
|
||||
|
||||
$installer = new lang_installer();
|
||||
|
||||
if ($availablelangs = $installer->get_remote_list_of_languages()) {
|
||||
$remote = true;
|
||||
} else {
|
||||
$remote = false;
|
||||
$availablelangs = array();
|
||||
echo $OUTPUT->box_start();
|
||||
print_string('remotelangnotavailable', 'admin', $CFG->dataroot.'/lang/');
|
||||
echo $OUTPUT->box_end();
|
||||
}
|
||||
|
||||
if ($notice_ok) {
|
||||
$info = implode('<br />', $notice_ok);
|
||||
echo $OUTPUT->notification($info, 'notifysuccess');
|
||||
}
|
||||
|
||||
if ($notice_error) {
|
||||
$info = implode('<br />', $notice_error);
|
||||
echo $OUTPUT->notification($info, 'notifyproblem');
|
||||
}
|
||||
|
||||
if ($missingparents) {
|
||||
foreach ($missingparents as $l=>$parent) {
|
||||
$a = new stdClass();
|
||||
$a->lang = $installedlangs[$l];
|
||||
$a->parent = $parent;
|
||||
foreach ($availablelangs as $alang) {
|
||||
if ($alang[0] == $parent) {
|
||||
$shortlang = $alang[0];
|
||||
$a->parent = $alang[2].' ('.$shortlang.')';
|
||||
}
|
||||
}
|
||||
$info = get_string('missinglangparent', 'admin', $a);
|
||||
echo $OUTPUT->notification($info, 'notifyproblem');
|
||||
}
|
||||
}
|
||||
|
||||
echo $OUTPUT->box_start();
|
||||
|
||||
echo html_writer::start_tag('table');
|
||||
echo html_writer::start_tag('tr');
|
||||
|
||||
// list of installed languages
|
||||
$url = new moodle_url('/admin/langimport.php', array('mode' => DELETION_OF_SELECTED_LANG));
|
||||
echo html_writer::start_tag('td', array('valign' => 'top'));
|
||||
echo html_writer::start_tag('form', array('id' => 'uninstallform', 'action' => $url->out(), 'method' => 'post'));
|
||||
echo html_writer::start_tag('fieldset');
|
||||
echo html_writer::label(get_string('installedlangs','admin'), 'uninstalllang');
|
||||
echo html_writer::empty_tag('br');
|
||||
echo html_writer::select($installedlangs, 'uninstalllang', '', false, array('size' => 15));
|
||||
echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
|
||||
echo html_writer::empty_tag('br');
|
||||
echo html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('uninstall','admin')));
|
||||
echo html_writer::end_tag('fieldset');
|
||||
echo html_writer::end_tag('form');
|
||||
if ($remote) {
|
||||
$url = new moodle_url('/admin/langimport.php', array('mode' => UPDATE_ALL_LANG));
|
||||
echo html_writer::start_tag('form', array('id' => 'updateform', 'action' => $url->out(), 'method' => 'post'));
|
||||
echo html_writer::tag('fieldset', html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('updatelangs','admin'))));
|
||||
echo html_writer::end_tag('form');
|
||||
}
|
||||
echo html_writer::end_tag('td');
|
||||
|
||||
// list of available languages
|
||||
$options = array();
|
||||
foreach ($availablelangs as $alang) {
|
||||
if (!empty($alang[0]) and trim($alang[0]) !== 'en' and !is_installed_lang($alang[0], $alang[1])) {
|
||||
$options[$alang[0]] = $alang[2].' ('.$alang[0].')';
|
||||
}
|
||||
}
|
||||
if (!empty($options)) {
|
||||
echo html_writer::start_tag('td', array('valign' => 'top'));
|
||||
$url = new moodle_url('/admin/langimport.php', array('mode' => INSTALLATION_OF_SELECTED_LANG));
|
||||
echo html_writer::start_tag('form', array('id' => 'installform', 'action' => $url->out(), 'method' => 'post'));
|
||||
echo html_writer::start_tag('fieldset');
|
||||
echo html_writer::label(get_string('availablelangs','install'), 'pack');
|
||||
echo html_writer::empty_tag('br');
|
||||
echo html_writer::select($options, 'pack[]', '', false, array('size' => 15, 'multiple' => 'multiple'));
|
||||
echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
|
||||
echo html_writer::empty_tag('br');
|
||||
echo html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('install','admin')));
|
||||
echo html_writer::end_tag('fieldset');
|
||||
echo html_writer::end_tag('form');
|
||||
echo html_writer::end_tag('td');
|
||||
}
|
||||
|
||||
echo html_writer::end_tag('tr');
|
||||
echo html_writer::end_tag('table');
|
||||
echo $OUTPUT->box_end();
|
||||
echo $OUTPUT->footer();
|
||||
die();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Local functions /////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* checks the md5 of the zip file, grabbed from download.moodle.org,
|
||||
* against the md5 of the local language file from last update
|
||||
* @param string $lang
|
||||
* @param string $md5check
|
||||
* @return bool
|
||||
*/
|
||||
function is_installed_lang($lang, $md5check) {
|
||||
global $CFG;
|
||||
$md5file = $CFG->dataroot.'/lang/'.$lang.'/'.$lang.'.md5';
|
||||
if (file_exists($md5file)){
|
||||
return (file_get_contents($md5file) == $md5check);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
+1
-12
@@ -35,16 +35,5 @@ function admin_page_type_list($pagetype, $parentcontext, $currentcontext) {
|
||||
'admin-*' => get_string('page-admin-x', 'pagetype'),
|
||||
$pagetype => get_string('page-admin-current', 'pagetype')
|
||||
);
|
||||
// Add the missing * (any page) option for them. MDL-30340
|
||||
// TODO: These pages are really 'pagetype-varying' - MDL-30564 -
|
||||
// and some day we should stop behaving that way, so proper pagetypes
|
||||
// can be specified for it (like course-category-* or so).
|
||||
// Luckly... the option we are introducing '*' is independent
|
||||
// of that varying behavior, so will work.
|
||||
if ($pagetype == 'admin-course-category') {
|
||||
$array += array(
|
||||
'*' => get_string('page-x', 'pagetype')
|
||||
);
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@ require_once($CFG->libdir.'/tablelib.php');
|
||||
|
||||
admin_externalpage_setup('managelocalplugins');
|
||||
|
||||
$delete = optional_param('delete', '', PARAM_PLUGIN);
|
||||
$delete = optional_param('delete', '', PARAM_SAFEDIR);
|
||||
$confirm = optional_param('confirm', '', PARAM_BOOL);
|
||||
|
||||
/// If data submitted, then process and store.
|
||||
@@ -89,7 +89,7 @@ foreach (get_plugin_list('local') as $plugin => $plugindir) {
|
||||
}
|
||||
$plugins[$plugin] = $strpluginname;
|
||||
}
|
||||
collatorlib::asort($plugins);
|
||||
textlib_get_instance()->asort($plugins);
|
||||
|
||||
foreach ($plugins as $plugin => $name) {
|
||||
$delete = new moodle_url($PAGE->url, array('delete' => $plugin, 'sesskey' => sesskey()));
|
||||
|
||||
@@ -203,18 +203,17 @@ echo get_string('username') . ":\n";
|
||||
if (!empty($formerror['username'])) {
|
||||
echo '<span class="error"> * </span>';
|
||||
}
|
||||
echo html_writer::label(get_string('username'), 'menuusername', false, array('class' => 'accesshide'));
|
||||
echo '<input id="menuusername" type="text" name="username" size="20" maxlength="100" />';
|
||||
echo '<input type="text" name="username" size="20" maxlength="100" />';
|
||||
|
||||
// choose a remote host
|
||||
echo " " . html_writer::label(get_string('remotehost', 'mnet'), 'menumnet_host_id') . ":\n";
|
||||
echo " " . get_string('remotehost', 'mnet') . ":\n";
|
||||
if (!empty($formerror['mnet_host_id'])) {
|
||||
echo '<span class="error"> * </span>';
|
||||
}
|
||||
echo html_writer::select($mnethosts, 'mnet_host_id');
|
||||
|
||||
// choose an access level
|
||||
echo " " . html_writer::label(get_string('accesslevel', 'mnet'), 'menuaccessctrl') . ":\n";
|
||||
echo " " . get_string('accesslevel', 'mnet') . ":\n";
|
||||
if (!empty($formerror['accessctrl'])) {
|
||||
echo '<span class="error"> * </span>';
|
||||
}
|
||||
|
||||
+16
-25
@@ -38,10 +38,9 @@ class mnet_simple_host_form extends moodleform {
|
||||
|
||||
$mform = $this->_form;
|
||||
|
||||
$mform->addElement('text', 'wwwroot', get_string('hostname', 'mnet'), array('maxlength' => 255, 'size' => 50));
|
||||
$mform->addElement('text', 'wwwroot', get_string('hostname', 'mnet'));
|
||||
$mform->setType('wwwroot', PARAM_URL);
|
||||
$mform->addRule('wwwroot', null, 'required', null, 'client');
|
||||
$mform->addRule('wwwroot', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
|
||||
|
||||
$mform->addElement('select', 'applicationid', get_string('applicationtype', 'mnet'),
|
||||
$DB->get_records_menu('mnet_application', array(), 'id,display_name'));
|
||||
@@ -50,7 +49,7 @@ class mnet_simple_host_form extends moodleform {
|
||||
$this->add_action_buttons(false, get_string('addhost', 'mnet'));
|
||||
}
|
||||
|
||||
function validation($data, $files) {
|
||||
function validation($data) {
|
||||
global $DB;
|
||||
|
||||
$wwwroot = $data['wwwroot'];
|
||||
@@ -82,13 +81,11 @@ class mnet_review_host_form extends moodleform {
|
||||
$mform->addElement('hidden', 'applicationid');
|
||||
$mform->addElement('hidden', 'oldpublickey');
|
||||
|
||||
$mform->addElement('text', 'name', get_string('site'), array('maxlength' => 80, 'size' => 50));
|
||||
$mform->addElement('text', 'name', get_string('site'));
|
||||
$mform->setType('name', PARAM_NOTAGS);
|
||||
$mform->addRule('name', get_string('maximumchars', '', 80), 'maxlength', 80, 'client');
|
||||
|
||||
$mform->addElement('text', 'wwwroot', get_string('hostname', 'mnet'), array('maxlength' => 255, 'size' => 50));
|
||||
$mform->addElement('text', 'wwwroot', get_string('hostname', 'mnet'));
|
||||
$mform->setType('wwwroot', PARAM_URL);
|
||||
$mform->addRule('wwwroot', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
|
||||
|
||||
$themes = array('' => get_string('forceno'));
|
||||
foreach (array_keys(get_plugin_list('theme')) as $themename) {
|
||||
@@ -98,7 +95,15 @@ class mnet_review_host_form extends moodleform {
|
||||
|
||||
$mform->addElement('textarea', 'public_key', get_string('publickey', 'mnet'), array('rows' => 17, 'cols' => 100, 'class' => 'smalltext'));
|
||||
$mform->setType('public_key', PARAM_PEM);
|
||||
$mform->addRule('public_key', get_string('required'), 'required');
|
||||
|
||||
if ($mnet_peer && !empty($mnet_peer->deleted)) {
|
||||
$radioarray = array();
|
||||
$radioarray[] = MoodleQuickForm::createElement('radio', 'deleted', '', get_string('yes'), 1);
|
||||
$radioarray[] = MoodleQuickForm::createElement('radio', 'deleted', '', get_string('no'), 0);
|
||||
$mform->addGroup($radioarray, 'radioar', get_string('deleted'), array(' '), false);
|
||||
} else {
|
||||
$mform->addElement('hidden', 'deleted');
|
||||
}
|
||||
|
||||
// finished with form controls, now the static informational stuff
|
||||
if ($mnet_peer && !empty($mnet_peer->bootstrapped)) {
|
||||
@@ -135,35 +140,21 @@ class mnet_review_host_form extends moodleform {
|
||||
}
|
||||
}
|
||||
|
||||
$mform->addElement('static', 'certdetails', get_string('certdetails', 'mnet'),
|
||||
$OUTPUT->box('<pre>' . $credstr . '</pre>', 'generalbox certdetails'));
|
||||
}
|
||||
|
||||
if ($mnet_peer && !empty($mnet_peer->deleted)) {
|
||||
$radioarray = array();
|
||||
$radioarray[] = MoodleQuickForm::createElement('static', 'deletedinfo', '',
|
||||
$OUTPUT->container(get_string('deletedhostinfo', 'mnet'), 'deletedhostinfo'));
|
||||
$radioarray[] = MoodleQuickForm::createElement('radio', 'deleted', '', get_string('yes'), 1);
|
||||
$radioarray[] = MoodleQuickForm::createElement('radio', 'deleted', '', get_string('no'), 0);
|
||||
$mform->addGroup($radioarray, 'radioar', get_string('deleted'), array(' ', ' '), false);
|
||||
} else {
|
||||
$mform->addElement('hidden', 'deleted');
|
||||
$mform->addElement('static', 'certdetails', get_string('certdetails', 'mnet'), $OUTPUT->box('<pre>' . $credstr . '</pre>'));
|
||||
}
|
||||
|
||||
// finished with static stuff, print save button
|
||||
$this->add_action_buttons(false);
|
||||
}
|
||||
|
||||
function validation($data, $files) {
|
||||
function validation($data) {
|
||||
$errors = array();
|
||||
if ($data['oldpublickey'] == $data['public_key']) {
|
||||
return;
|
||||
}
|
||||
$mnet_peer = new mnet_peer(); // idiotic api
|
||||
$mnet_peer->wwwroot = $data['wwwroot']; // just hard-set this rather than bootstrap the object
|
||||
if (empty($data['public_key'])) {
|
||||
$errors['public_key'] = get_string('publickeyrequired', 'mnet');
|
||||
} else if (!$credentials = $mnet_peer->check_credentials($data['public_key'])) {
|
||||
if (!$credentials = $mnet_peer->check_credentials($data['public_key'])) {
|
||||
$errmsg = '';
|
||||
foreach ($mnet_peer->error as $err) {
|
||||
$errmsg .= $err['code'] . ': ' . $err['text'].'<br />';
|
||||
|
||||
+5
-20
@@ -30,7 +30,7 @@
|
||||
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->dirroot.'/mnet/lib.php');
|
||||
require_once($CFG->dirroot.'/'.$CFG->admin.'/mnet/peer_forms.php');
|
||||
require_once($CFG->dirroot.'/admin/mnet/peer_forms.php');
|
||||
|
||||
require_login();
|
||||
|
||||
@@ -190,7 +190,7 @@ if ($formdata = $reviewform->get_data()) {
|
||||
|
||||
// normal flow - just display all hosts with links
|
||||
echo $OUTPUT->header();
|
||||
$hosts = mnet_get_hosts(true);
|
||||
$hosts = mnet_get_hosts();
|
||||
|
||||
// print the table to display the register all hosts setting
|
||||
$table = new html_table();
|
||||
@@ -231,43 +231,28 @@ $table->head = array(
|
||||
);
|
||||
$table->wrap = array('nowrap', 'nowrap', 'nowrap', 'nowrap');
|
||||
$baseurl = new moodle_url('/admin/mnet/peers.php');
|
||||
$deleted = array();
|
||||
foreach($hosts as $host) {
|
||||
$hosturl = new moodle_url($baseurl, array('hostid' => $host->id));
|
||||
if (trim($host->name) === '') {
|
||||
// should not happen but...
|
||||
$host->name = '???';
|
||||
}
|
||||
// process all hosts first since it's the easiest
|
||||
if ($host->id == $CFG->mnet_all_hosts_id) {
|
||||
$table->data[] = array(html_writer::link($hosturl, get_string('allhosts', 'core_mnet')), '*', '', '');
|
||||
continue;
|
||||
}
|
||||
|
||||
// populate the list of deleted hosts
|
||||
if ($host->deleted) {
|
||||
$deleted[] = html_writer::link($hosturl, $host->name);
|
||||
$table->data[] = array(html_writer::tag('a', $host->name, array('href'=>$hosturl)), '', '', '');
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($host->last_connect_time == 0) {
|
||||
$last_connect = get_string('never');
|
||||
} else {
|
||||
$last_connect = userdate($host->last_connect_time, get_string('strftimedatetime', 'core_langconfig'));
|
||||
$last_connect = date('H:i:s d/m/Y', $host->last_connect_time);
|
||||
}
|
||||
$table->data[] = array(
|
||||
html_writer::link($hosturl, $host->name),
|
||||
html_writer::link($host->wwwroot, $host->wwwroot),
|
||||
html_writer::link($hosturl, $host->wwwroot),
|
||||
$last_connect,
|
||||
$OUTPUT->single_button(new moodle_url('/admin/mnet/delete.php', array('hostid' => $host->id)), get_string('delete'))
|
||||
);
|
||||
}
|
||||
echo html_writer::table($table);
|
||||
|
||||
if ($deleted) {
|
||||
echo $OUTPUT->box(get_string('deletedhosts', 'core_mnet', join(', ', $deleted)), 'deletedhosts');
|
||||
}
|
||||
|
||||
// finally, print the initial form to add a new host
|
||||
echo $OUTPUT->box_start();
|
||||
echo $OUTPUT->heading(get_string('addnewhost', 'mnet'), 3);
|
||||
|
||||
@@ -39,15 +39,6 @@ class mnet_profile_form extends moodleform {
|
||||
global $CFG;
|
||||
$mform =& $this->_form;
|
||||
|
||||
$mnetprofileimportfields = '';
|
||||
if (isset($CFG->mnetprofileimportfields)) {
|
||||
$mnetprofileimportfields = str_replace(',', ', ', $CFG->mnetprofileimportfields);
|
||||
}
|
||||
|
||||
$mnetprofileexportfields = '';
|
||||
if (isset($CFG->mnetprofileexportfields)) {
|
||||
$mnetprofileexportfields = str_replace(',', ', ', $CFG->mnetprofileexportfields);
|
||||
}
|
||||
|
||||
$mform->addElement('hidden', 'hostid', $this->_customdata['hostid']);
|
||||
$fields = mnet_profile_field_options();
|
||||
@@ -58,7 +49,7 @@ class mnet_profile_form extends moodleform {
|
||||
$select = $mform->addElement('select', 'importfields', get_string('importfields', 'mnet'), $fields['optional']);
|
||||
$select->setMultiple(true);
|
||||
|
||||
$mform->addElement('checkbox', 'importdefault', get_string('leavedefault', 'mnet'), $mnetprofileimportfields);
|
||||
$mform->addElement('checkbox', 'importdefault', get_string('leavedefault', 'mnet'), str_replace(',', ', ', $CFG->mnetprofileimportfields));
|
||||
|
||||
// Fields to export ----------------------------------------------------
|
||||
$mform->addElement('header', 'export', get_string('exportfields', 'mnet'));
|
||||
@@ -66,7 +57,7 @@ class mnet_profile_form extends moodleform {
|
||||
$select = $mform->addElement('select', 'exportfields', get_string('exportfields', 'mnet'), $fields['optional']);
|
||||
$select->setMultiple(true);
|
||||
|
||||
$mform->addElement('checkbox', 'exportdefault', get_string('leavedefault', 'mnet'), $mnetprofileexportfields);
|
||||
$mform->addElement('checkbox', 'exportdefault', get_string('leavedefault', 'mnet'), str_replace(',', ', ', $CFG->mnetprofileexportfields));
|
||||
|
||||
$this->add_action_buttons();
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class mnet_services_form extends moodleform {
|
||||
function definition() {
|
||||
$mform =& $this->_form;
|
||||
$mnet_peer =& $this->_customdata['peer'];
|
||||
$myservices = mnet_get_service_info($mnet_peer);
|
||||
$myservices =& mnet_get_service_info($mnet_peer);
|
||||
|
||||
$mform->addElement('hidden', 'hostid', $mnet_peer->id);
|
||||
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ $strmnetlog = get_string('mnetlog', 'mnet');
|
||||
$strmnetedithost = get_string('reviewhostdetails', 'mnet');
|
||||
|
||||
$logurl = $CFG->wwwroot.
|
||||
'/report/log/index.php?chooselog=1&showusers=1&showcourses=1&host_course='.$mnet_peer->id.
|
||||
'/course/report/log/index.php?chooselog=1&showusers=1&showcourses=1&host_course='.$mnet_peer->id.
|
||||
'%2F1&user='.'0'.
|
||||
'&date=0'.
|
||||
'&modid=&modaction=0&logformat=showashtml';
|
||||
|
||||
+3
-4
@@ -11,9 +11,9 @@
|
||||
|
||||
admin_externalpage_setup('managemodules');
|
||||
|
||||
$show = optional_param('show', '', PARAM_PLUGIN);
|
||||
$hide = optional_param('hide', '', PARAM_PLUGIN);
|
||||
$delete = optional_param('delete', '', PARAM_PLUGIN);
|
||||
$show = optional_param('show', '', PARAM_SAFEDIR);
|
||||
$hide = optional_param('hide', '', PARAM_SAFEDIR);
|
||||
$delete = optional_param('delete', '', PARAM_SAFEDIR);
|
||||
$confirm = optional_param('confirm', '', PARAM_BOOL);
|
||||
|
||||
|
||||
@@ -92,7 +92,6 @@
|
||||
}
|
||||
|
||||
uninstall_plugin('mod', $delete);
|
||||
$a = new stdClass();
|
||||
$a->module = $strmodulename;
|
||||
$a->directory = "$CFG->dirroot/mod/$delete";
|
||||
echo $OUTPUT->notification(get_string("moduledeletefiles", "", $a), 'notifysuccess');
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/// Search and replace strings throughout all texts in the whole database
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->dirroot.'/course/lib.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('multilangupgrade');
|
||||
|
||||
$go = optional_param('go', 0, PARAM_BOOL);
|
||||
|
||||
###################################################################
|
||||
echo $OUTPUT->header();
|
||||
|
||||
echo $OUTPUT->heading(get_string('multilangupgrade', 'admin'));
|
||||
|
||||
$strmultilangupgrade = get_String('multilangupgradeinfo', 'admin');
|
||||
|
||||
if (!$go or !data_submitted() or !confirm_sesskey()) { /// Print a form
|
||||
$optionsyes = array('go'=>1, 'sesskey'=>sesskey());
|
||||
echo $OUTPUT->confirm($strmultilangupgrade, new moodle_url('multilangupgrade.php', $optionsyes), 'index.php');
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
}
|
||||
|
||||
|
||||
if (!$tables = $DB->get_tables() ) { // No tables yet at all.
|
||||
print_error('notables', 'debug');
|
||||
}
|
||||
|
||||
echo $OUTPUT->box_start();
|
||||
|
||||
/// Turn off time limits, sometimes upgrades can be slow.
|
||||
|
||||
@set_time_limit(0);
|
||||
|
||||
echo '<strong>Progress:</strong>';
|
||||
$i = 0;
|
||||
$skiptables = array('config', 'user_students', 'user_teachers');
|
||||
|
||||
foreach ($tables as $table) {
|
||||
if (strpos($table,'pma') === 0) { // Not our tables
|
||||
continue;
|
||||
}
|
||||
if (in_array($table, $skiptables)) { // Don't process these
|
||||
continue;
|
||||
}
|
||||
$fulltable = $DB->get_prefix().$table;
|
||||
if ($columns = $DB->get_columns($table)) {
|
||||
if (!array_key_exists('id', $columns)) {
|
||||
continue; // moodle tables have id
|
||||
}
|
||||
foreach ($columns as $column => $data) {
|
||||
if (in_array($data->type, array('text','mediumtext','longtext','varchar'))) { // Text stuff only
|
||||
// first find candidate records
|
||||
$sql = "SELECT id, $column FROM $fulltable WHERE $column LIKE '%</lang>%' OR $column LIKE '%<span lang=%'";
|
||||
$rs = $DB->get_recordset_sql($sql);
|
||||
foreach ($rs as $data) {
|
||||
$text = $data->$column;
|
||||
$id = $data->id;
|
||||
if ($i % 600 == 0) {
|
||||
echo '<br />';
|
||||
}
|
||||
if ($i % 10 == 0) {
|
||||
echo '.';
|
||||
}
|
||||
$i++;
|
||||
|
||||
if (empty($text) or is_numeric($text)) {
|
||||
continue; // nothing to do
|
||||
}
|
||||
|
||||
$search = '/(<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)(\s*<(?:lang|span) lang="[a-zA-Z0-9_-]*".*?>.+?<\/(?:lang|span)>)+/is';
|
||||
$newtext = preg_replace_callback($search, 'multilangupgrade_impl', $text);
|
||||
|
||||
if (is_null($newtext)) {
|
||||
continue; // regex error
|
||||
}
|
||||
|
||||
if ($newtext != $text) {
|
||||
$DB->execute("UPDATE $fulltable SET $column=? WHERE id=?", array($newtext, $id));
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set conversion flag - switches to new plugin automatically
|
||||
set_config('filter_multilang_converted', 1);
|
||||
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
/// Rebuild course cache which might be incorrect now
|
||||
echo $OUTPUT->notification('Rebuilding course cache...', 'notifysuccess');
|
||||
rebuild_course_cache();
|
||||
echo $OUTPUT->notification('...finished', 'notifysuccess');
|
||||
|
||||
echo $OUTPUT->continue_button('index.php');
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
|
||||
|
||||
function multilangupgrade_impl($langblock) {
|
||||
$searchtosplit = '/<(?:lang|span) lang="([a-zA-Z0-9_-]*)".*?>(.+?)<\/(?:lang|span)>/is';
|
||||
preg_match_all($searchtosplit, $langblock[0], $rawlanglist);
|
||||
$return = '';
|
||||
foreach ($rawlanglist[1] as $index=>$lang) {
|
||||
$return .= '<span lang="'.$lang.'" class="multilang">'.$rawlanglist[2][$index].'</span>';
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
+8
-1
@@ -31,4 +31,11 @@ require_once($CFG->libdir . '/pluginlib.php');
|
||||
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
|
||||
admin_externalpage_setup('pluginsoverview');
|
||||
$output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->plugin_management_page(plugin_manager::instance());
|
||||
$pluginman = plugin_manager::instance();
|
||||
|
||||
echo $output->header();
|
||||
echo $output->heading(get_string('pluginsoverview', 'core_admin'));
|
||||
echo $output->box_start('generalbox');
|
||||
echo $output->plugins_control_panel($pluginman->get_plugins());
|
||||
echo $output->box_end();
|
||||
echo $output->footer();
|
||||
|
||||
@@ -197,7 +197,6 @@ if (($action == 'edit') || ($action == 'new')) {
|
||||
$currentaction = 'hide';
|
||||
}
|
||||
$select = new single_select(portfolio_action_url($pluginid, 'pf'), 'action', $actionchoicesforexisting, $currentaction, null, 'applyto' . $pluginid);
|
||||
$select->set_label(get_string('action'), array('class' => 'accesshide'));
|
||||
$table->data[] = array($pluginname, $OUTPUT->render($select), $settings);
|
||||
}
|
||||
if (!in_array($plugin, $usedplugins)) {
|
||||
@@ -219,7 +218,6 @@ if (($action == 'edit') || ($action == 'new')) {
|
||||
$insaneplugins[] = $p;
|
||||
} else {
|
||||
$select = new single_select(portfolio_action_url($p, 'pf'), 'action', $actionchoicesfornew, 'delete', null, 'applyto' . $p);
|
||||
$select->set_label(get_string('action'), array('class' => 'accesshide'));
|
||||
$table->data[] = array(portfolio_static_function($p, 'get_name'), $OUTPUT->render($select), '');
|
||||
}
|
||||
}
|
||||
|
||||
+21
-21
@@ -28,7 +28,6 @@
|
||||
require_once(dirname(__FILE__) . '/../config.php');
|
||||
require_once($CFG->libdir . '/questionlib.php');
|
||||
require_once($CFG->libdir . '/adminlib.php');
|
||||
require_once($CFG->libdir . '/pluginlib.php');
|
||||
require_once($CFG->libdir . '/tablelib.php');
|
||||
|
||||
// Check permissions.
|
||||
@@ -40,7 +39,6 @@ admin_externalpage_setup('manageqbehaviours');
|
||||
$thispageurl = new moodle_url('/admin/qbehaviours.php');
|
||||
|
||||
$behaviours = get_plugin_list('qbehaviour');
|
||||
$pluginmanager = plugin_manager::instance();
|
||||
|
||||
// Get some data we will need - question counts and which types are needed.
|
||||
$counts = $DB->get_records_sql_menu("
|
||||
@@ -52,16 +50,20 @@ foreach ($behaviours as $behaviour => $notused) {
|
||||
if (!array_key_exists($behaviour, $counts)) {
|
||||
$counts[$behaviour] = 0;
|
||||
}
|
||||
$needed[$behaviour] = ($counts[$behaviour] > 0) ||
|
||||
$pluginmanager->other_plugins_that_require('qbehaviour_' . $behaviour);
|
||||
$needed[$behaviour] = $counts[$behaviour] > 0;
|
||||
$archetypal[$behaviour] = question_engine::is_behaviour_archetypal($behaviour);
|
||||
}
|
||||
|
||||
foreach ($behaviours as $behaviour => $notused) {
|
||||
foreach (question_engine::get_behaviour_required_behaviours($behaviour) as $reqbehaviour) {
|
||||
$needed[$reqbehaviour] = true;
|
||||
}
|
||||
}
|
||||
foreach ($counts as $behaviour => $count) {
|
||||
if (!array_key_exists($behaviour, $behaviours)) {
|
||||
$counts['missing'] += $count;
|
||||
$counts['missingtype'] += $count;
|
||||
}
|
||||
}
|
||||
$needed['missing'] = true;
|
||||
|
||||
// Work of the correct sort order.
|
||||
$config = get_config('question');
|
||||
@@ -83,7 +85,7 @@ if (!empty($config->disabledbehaviours)) {
|
||||
// Process actions ============================================================
|
||||
|
||||
// Disable.
|
||||
if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
if (($disable = optional_param('disable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
|
||||
if (!isset($behaviours[$disable])) {
|
||||
print_error('unknownbehaviour', 'question', $thispageurl, $disable);
|
||||
}
|
||||
@@ -96,7 +98,7 @@ if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey(
|
||||
}
|
||||
|
||||
// Enable.
|
||||
if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
if (($enable = optional_param('enable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
|
||||
if (!isset($behaviours[$enable])) {
|
||||
print_error('unknownbehaviour', 'question', $thispageurl, $enable);
|
||||
}
|
||||
@@ -113,7 +115,7 @@ if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey())
|
||||
}
|
||||
|
||||
// Move up in order.
|
||||
if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
if (($up = optional_param('up', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
|
||||
if (!isset($behaviours[$up])) {
|
||||
print_error('unknownbehaviour', 'question', $thispageurl, $up);
|
||||
}
|
||||
@@ -125,7 +127,7 @@ if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
}
|
||||
|
||||
// Move down in order.
|
||||
if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
if (($down = optional_param('down', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
|
||||
if (!isset($behaviours[$down])) {
|
||||
print_error('unknownbehaviour', 'question', $thispageurl, $down);
|
||||
}
|
||||
@@ -137,7 +139,7 @@ if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
}
|
||||
|
||||
// Delete.
|
||||
if (($delete = optional_param('delete', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
if (($delete = optional_param('delete', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
|
||||
// Check it is OK to delete this question type.
|
||||
if ($delete == 'missing') {
|
||||
print_error('cannotdeletemissingbehaviour', 'question', $thispageurl);
|
||||
@@ -179,7 +181,7 @@ if (($delete = optional_param('delete', '', PARAM_PLUGIN)) && confirm_sesskey())
|
||||
unset($disabledbehaviours[$key]);
|
||||
set_config('disabledbehaviours', implode(',', $disabledbehaviours), 'question');
|
||||
}
|
||||
$behaviourorder = array_keys($sortedbehaviours);
|
||||
$behaviourorder = explode(',', $config->behavioursortorder);
|
||||
if (($key = array_search($delete, $behaviourorder)) !== false) {
|
||||
unset($behaviourorder[$key]);
|
||||
set_config('behavioursortorder', implode(',', $behaviourorder), 'question');
|
||||
@@ -191,7 +193,6 @@ if (($delete = optional_param('delete', '', PARAM_PLUGIN)) && confirm_sesskey())
|
||||
// Remove event handlers and dequeue pending events
|
||||
events_uninstall('qbehaviour_' . $delete);
|
||||
|
||||
$a = new stdClass();
|
||||
$a->behaviour = $behaviourname;
|
||||
$a->directory = get_plugin_directory('qbehaviour', $delete);
|
||||
echo $OUTPUT->box(get_string('qbehaviourdeletefiles', 'question', $a), 'generalbox', 'notice');
|
||||
@@ -237,19 +238,18 @@ foreach ($sortedbehaviours as $behaviour => $behaviourname) {
|
||||
}
|
||||
|
||||
// Other question types required by this one.
|
||||
$plugin = $pluginmanager->get_plugin_info('qbehaviour_' . $behaviour);
|
||||
$required = $plugin->get_other_required_plugins();
|
||||
if (!empty($required)) {
|
||||
$strrequired = array();
|
||||
foreach ($required as $component => $notused) {
|
||||
$strrequired[] = $pluginmanager->plugin_name($component);
|
||||
$requiredbehaviours = question_engine::get_behaviour_required_behaviours($behaviour);
|
||||
if (!empty($requiredbehaviours)) {
|
||||
$strrequiredbehaviours = array();
|
||||
foreach ($requiredbehaviours as $required) {
|
||||
$strrequiredbehaviours[] = $sortedbehaviours[$required];
|
||||
}
|
||||
$row[] = implode(', ', $strrequired);
|
||||
$row[] = implode(', ', $strrequiredbehaviours);
|
||||
} else {
|
||||
$row[] = '';
|
||||
}
|
||||
|
||||
// Are people allowed to select this behaviour?
|
||||
// Are people allowed to create new questions of this type?
|
||||
$rowclass = '';
|
||||
if ($archetypal[$behaviour]) {
|
||||
$enabled = array_search($behaviour, $disabledbehaviours) === false;
|
||||
|
||||
+15
-15
@@ -28,7 +28,6 @@
|
||||
require_once(dirname(__FILE__) . '/../config.php');
|
||||
require_once($CFG->libdir . '/questionlib.php');
|
||||
require_once($CFG->libdir . '/adminlib.php');
|
||||
require_once($CFG->libdir . '/pluginlib.php');
|
||||
require_once($CFG->libdir . '/tablelib.php');
|
||||
|
||||
// Check permissions.
|
||||
@@ -41,7 +40,6 @@ admin_externalpage_setup('manageqtypes');
|
||||
$thispageurl = new moodle_url('/admin/qtypes.php');
|
||||
|
||||
$qtypes = question_bank::get_all_qtypes();
|
||||
$pluginmanager = plugin_manager::instance();
|
||||
|
||||
// Get some data we will need - question counts and which types are needed.
|
||||
$counts = $DB->get_records_sql("
|
||||
@@ -54,11 +52,15 @@ foreach ($qtypes as $qtypename => $qtype) {
|
||||
$counts[$qtypename]->numquestions = 0;
|
||||
$counts[$qtypename]->numhidden = 0;
|
||||
}
|
||||
$needed[$qtypename] = $counts[$qtypename]->numquestions > 0 ||
|
||||
$pluginmanager->other_plugins_that_require($qtype->plugin_name());
|
||||
$needed[$qtypename] = $counts[$qtypename]->numquestions > 0;
|
||||
$counts[$qtypename]->numquestions -= $counts[$qtypename]->numhidden;
|
||||
}
|
||||
$needed['missingtype'] = true; // The system needs the missing question type.
|
||||
foreach ($qtypes as $qtypename => $qtype) {
|
||||
foreach ($qtype->requires_qtypes() as $reqtype) {
|
||||
$needed[$reqtype] = true;
|
||||
}
|
||||
}
|
||||
foreach ($counts as $qtypename => $count) {
|
||||
if (!isset($qtypes[$qtypename])) {
|
||||
$counts['missingtype']->numquestions += $count->numquestions - $count->numhidden;
|
||||
@@ -77,7 +79,7 @@ $sortedqtypes = question_bank::sort_qtype_array($sortedqtypes, $config);
|
||||
// Process actions ============================================================
|
||||
|
||||
// Disable.
|
||||
if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
if (($disable = optional_param('disable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
|
||||
if (!isset($qtypes[$disable])) {
|
||||
print_error('unknownquestiontype', 'question', $thispageurl, $disable);
|
||||
}
|
||||
@@ -87,7 +89,7 @@ if (($disable = optional_param('disable', '', PARAM_PLUGIN)) && confirm_sesskey(
|
||||
}
|
||||
|
||||
// Enable.
|
||||
if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
if (($enable = optional_param('enable', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
|
||||
if (!isset($qtypes[$enable])) {
|
||||
print_error('unknownquestiontype', 'question', $thispageurl, $enable);
|
||||
}
|
||||
@@ -101,7 +103,7 @@ if (($enable = optional_param('enable', '', PARAM_PLUGIN)) && confirm_sesskey())
|
||||
}
|
||||
|
||||
// Move up in order.
|
||||
if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
if (($up = optional_param('up', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
|
||||
if (!isset($qtypes[$up])) {
|
||||
print_error('unknownquestiontype', 'question', $thispageurl, $up);
|
||||
}
|
||||
@@ -112,7 +114,7 @@ if (($up = optional_param('up', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
}
|
||||
|
||||
// Move down in order.
|
||||
if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
if (($down = optional_param('down', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
|
||||
if (!isset($qtypes[$down])) {
|
||||
print_error('unknownquestiontype', 'question', $thispageurl, $down);
|
||||
}
|
||||
@@ -123,7 +125,7 @@ if (($down = optional_param('down', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
}
|
||||
|
||||
// Delete.
|
||||
if (($delete = optional_param('delete', '', PARAM_PLUGIN)) && confirm_sesskey()) {
|
||||
if (($delete = optional_param('delete', '', PARAM_SAFEDIR)) && confirm_sesskey()) {
|
||||
// Check it is OK to delete this question type.
|
||||
if ($delete == 'missingtype') {
|
||||
print_error('cannotdeletemissingqtype', 'question', $thispageurl);
|
||||
@@ -171,7 +173,6 @@ if (($delete = optional_param('delete', '', PARAM_PLUGIN)) && confirm_sesskey())
|
||||
// Remove event handlers and dequeue pending events
|
||||
events_uninstall('qtype_' . $delete);
|
||||
|
||||
$a = new stdClass();
|
||||
$a->qtype = $qtypename;
|
||||
$a->directory = $qtypes[$delete]->plugin_dir();
|
||||
echo $OUTPUT->box(get_string('qtypedeletefiles', 'question', $a), 'generalbox', 'notice');
|
||||
@@ -218,7 +219,7 @@ foreach ($sortedqtypes as $qtypename => $localname) {
|
||||
$strcount = $counts[$qtypename]->numquestions;
|
||||
}
|
||||
if ($canviewreports) {
|
||||
$row[] = html_writer::link(new moodle_url('/report/questioninstances/index.php',
|
||||
$row[] = html_writer::link(new moodle_url('/admin/report/questioninstances/index.php',
|
||||
array('qtype' => $qtypename)), $strcount, array('title' => get_string('showdetails', 'admin')));
|
||||
} else {
|
||||
$strcount;
|
||||
@@ -236,12 +237,11 @@ foreach ($sortedqtypes as $qtypename => $localname) {
|
||||
}
|
||||
|
||||
// Other question types required by this one.
|
||||
$plugin = $pluginmanager->get_plugin_info($qtype->plugin_name());
|
||||
$requiredtypes = $plugin->get_other_required_plugins();
|
||||
$requiredtypes = $qtype->requires_qtypes();
|
||||
$strtypes = array();
|
||||
if (!empty($requiredtypes)) {
|
||||
foreach ($requiredtypes as $required => $notused) {
|
||||
$strtypes[] = $pluginmanager->plugin_name($required);
|
||||
foreach ($requiredtypes as $required) {
|
||||
$strtypes[] = $qtypes[$required]->local_name();
|
||||
}
|
||||
$row[] = implode(', ', $strtypes);
|
||||
} else {
|
||||
|
||||
@@ -136,8 +136,8 @@ class hub_selector_form extends moodleform {
|
||||
$options = array();
|
||||
foreach ($hubs as $hub) {
|
||||
//to not display a name longer than 100 character (too big)
|
||||
if (textlib::strlen($hub['name']) > 100) {
|
||||
$hubname = textlib::substr($hub['name'], 0, 100);
|
||||
if (strlen($hub['name']) > 100) {
|
||||
$hubname = substr($hub['name'], 0, 100);
|
||||
$hubname = $hubname . "...";
|
||||
} else {
|
||||
$hubname = $hub['name'];
|
||||
@@ -283,7 +283,7 @@ class site_registration_form extends moodleform {
|
||||
$mform->addHelpButton('urlstring', 'siteurl', 'hub');
|
||||
|
||||
$languages = get_string_manager()->get_list_of_languages();
|
||||
collatorlib::asort($languages);
|
||||
textlib_get_instance()->asort($languages);
|
||||
$mform->addElement('select', 'language', get_string('sitelang', 'hub'),
|
||||
$languages);
|
||||
$mform->setType('language', PARAM_ALPHANUMEXT);
|
||||
|
||||
+11
-643
@@ -32,394 +32,6 @@ require_once($CFG->libdir . '/pluginlib.php');
|
||||
*/
|
||||
class core_admin_renderer extends plugin_renderer_base {
|
||||
|
||||
/**
|
||||
* Display the 'Do you acknowledge the terms of the GPL' page. The first page
|
||||
* during install.
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function install_licence_page() {
|
||||
global $CFG;
|
||||
$output = '';
|
||||
|
||||
$copyrightnotice = text_to_html(get_string('gpl3'));
|
||||
$copyrightnotice = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $copyrightnotice); // extremely ugly validation hack
|
||||
|
||||
$continue = new single_button(new moodle_url('/admin/index.php', array('lang'=>$CFG->lang, 'agreelicense'=>1)), get_string('continue'), 'get');
|
||||
|
||||
$output .= $this->header();
|
||||
$output .= $this->heading('<a href="http://moodle.org">Moodle</a> - Modular Object-Oriented Dynamic Learning Environment');
|
||||
$output .= $this->heading(get_string('copyrightnotice'));
|
||||
$output .= $this->box($copyrightnotice, 'copyrightnotice');
|
||||
$output .= html_writer::empty_tag('br');
|
||||
$output .= $this->confirm(get_string('doyouagree'), $continue, "http://docs.moodle.org/dev/License");
|
||||
$output .= $this->footer();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the 'environment check' page that is displayed during install.
|
||||
* @param int $maturity
|
||||
* @param boolean $envstatus final result of the check (true/false)
|
||||
* @param array $environment_results array of results gathered
|
||||
* @param string $release moodle release
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function install_environment_page($maturity, $envstatus, $environment_results, $release) {
|
||||
global $CFG;
|
||||
$output = '';
|
||||
|
||||
$output .= $this->header();
|
||||
$output .= $this->maturity_warning($maturity);
|
||||
$output .= $this->heading("Moodle $release");
|
||||
$output .= $this->release_notes_link();
|
||||
|
||||
$output .= $this->environment_check_table($envstatus, $environment_results);
|
||||
|
||||
if (!$envstatus) {
|
||||
$output .= $this->upgrade_reload(new moodle_url('/admin/index.php', array('agreelicense' => 1, 'lang' => $CFG->lang)));
|
||||
} else {
|
||||
$output .= $this->notification(get_string('environmentok', 'admin'), 'notifysuccess');
|
||||
$output .= $this->continue_button(new moodle_url('/admin/index.php', array('agreelicense'=>1, 'confirmrelease'=>1, 'lang'=>$CFG->lang)));
|
||||
}
|
||||
|
||||
$output .= $this->footer();
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the 'You are about to upgrade Moodle' page. The first page
|
||||
* during upgrade.
|
||||
* @param string $strnewversion
|
||||
* @param int $maturity
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function upgrade_confirm_page($strnewversion, $maturity) {
|
||||
$output = '';
|
||||
|
||||
$continueurl = new moodle_url('index.php', array('confirmupgrade' => 1));
|
||||
$cancelurl = new moodle_url('index.php');
|
||||
|
||||
$output .= $this->header();
|
||||
$output .= $this->maturity_warning($maturity);
|
||||
$output .= $this->confirm(get_string('upgradesure', 'admin', $strnewversion), $continueurl, $cancelurl);
|
||||
$output .= $this->footer();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the environment page during the upgrade process.
|
||||
* @param string $release
|
||||
* @param boolean $envstatus final result of env check (true/false)
|
||||
* @param array $environment_results array of results gathered
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function upgrade_environment_page($release, $envstatus, $environment_results) {
|
||||
global $CFG;
|
||||
$output = '';
|
||||
|
||||
$output .= $this->header();
|
||||
$output .= $this->heading("Moodle $release");
|
||||
$output .= $this->release_notes_link();
|
||||
$output .= $this->environment_check_table($envstatus, $environment_results);
|
||||
|
||||
if (!$envstatus) {
|
||||
$output .= $this->upgrade_reload(new moodle_url('/admin/index.php'), array('confirmupgrade' => 1));
|
||||
|
||||
} else {
|
||||
$output .= $this->notification(get_string('environmentok', 'admin'), 'notifysuccess');
|
||||
|
||||
if (empty($CFG->skiplangupgrade) and current_language() !== 'en') {
|
||||
$output .= $this->box(get_string('langpackwillbeupdated', 'admin'), 'generalbox', 'notice');
|
||||
}
|
||||
|
||||
$output .= $this->continue_button(new moodle_url('/admin/index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1)));
|
||||
}
|
||||
|
||||
$output .= $this->footer();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the upgrade page that lists all the plugins that require attention.
|
||||
* @param plugin_manager $pluginman provides information about the plugins.
|
||||
* @param int $version the version of the Moodle code from version.php.
|
||||
* @param bool $showallplugins
|
||||
* @param moodle_url $reloadurl
|
||||
* @param moodle_url $continueurl
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function upgrade_plugin_check_page(plugin_manager $pluginman, $version, $showallplugins, $reloadurl, $continueurl) {
|
||||
$output = '';
|
||||
|
||||
$output .= $this->header();
|
||||
$output .= $this->box_start('generalbox');
|
||||
$output .= $this->container(get_string('pluginchecknotice', 'core_plugin'), 'generalbox', 'notice');
|
||||
$output .= $this->plugins_check_table($pluginman, $version, array('full' => $showallplugins));
|
||||
$output .= $this->box_end();
|
||||
$output .= $this->upgrade_reload($reloadurl);
|
||||
|
||||
if ($pluginman->all_plugins_ok($version)) {
|
||||
$button = new single_button($continueurl, get_string('upgradestart', 'admin'), 'get');
|
||||
$button->class = 'continuebutton';
|
||||
$output .= $this->render($button);
|
||||
} else {
|
||||
$output .= $this->box(get_string('pluginschecktodo', 'admin'), 'environmentbox errorbox');
|
||||
}
|
||||
|
||||
$output .= $this->footer();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the admin notifications page.
|
||||
* @param int $maturity
|
||||
* @param bool $insecuredataroot warn dataroot is invalid
|
||||
* @param bool $errorsdisplayed warn invalid dispaly error setting
|
||||
* @param bool $cronoverdue warn cron not running
|
||||
* @param bool $dbproblems warn db has problems
|
||||
* @param bool $maintenancemode warn in maintenance mode
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
|
||||
$cronoverdue, $dbproblems, $maintenancemode) {
|
||||
$output = '';
|
||||
|
||||
$output .= $this->header();
|
||||
$output .= $this->maturity_info($maturity);
|
||||
$output .= $this->insecure_dataroot_warning($insecuredataroot);
|
||||
$output .= $this->display_errors_warning($errorsdisplayed);
|
||||
$output .= $this->cron_overdue_warning($cronoverdue);
|
||||
$output .= $this->db_problems($dbproblems);
|
||||
$output .= $this->maintenance_mode_warning($maintenancemode);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//// IT IS ILLEGAL AND A VIOLATION OF THE GPL TO HIDE, REMOVE OR MODIFY THIS COPYRIGHT NOTICE ///
|
||||
$output .= $this->moodle_copyright();
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$output .= $this->footer();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the plugin management page (admin/plugins.php).
|
||||
* @param plugin_manager $pluginman
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function plugin_management_page(plugin_manager $pluginman) {
|
||||
$output = '';
|
||||
|
||||
$output .= $this->header();
|
||||
$output .= $this->heading(get_string('pluginsoverview', 'core_admin'));
|
||||
$output .= $this->box_start('generalbox');
|
||||
$output .= $this->plugins_control_panel($pluginman);
|
||||
$output .= $this->box_end();
|
||||
$output .= $this->footer();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the plugin management page (admin/environment.php).
|
||||
* @param array $versions
|
||||
* @param string $version
|
||||
* @param boolean $envstatus final result of env check (true/false)
|
||||
* @param array $environment_results array of results gathered
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function environment_check_page($versions, $version, $envstatus, $environment_results) {
|
||||
$output = '';
|
||||
$output .= $this->header();
|
||||
|
||||
// Print the component download link
|
||||
$output .= html_writer::tag('div', html_writer::link(
|
||||
new moodle_url('/admin/environment.php', array('action' => 'updatecomponent', 'sesskey' => sesskey())),
|
||||
get_string('updatecomponent', 'admin')),
|
||||
array('class' => 'reportlink'));
|
||||
|
||||
// Heading.
|
||||
$output .= $this->heading(get_string('environment', 'admin'));
|
||||
|
||||
// Box with info and a menu to choose the version.
|
||||
$output .= $this->box_start();
|
||||
$output .= html_writer::tag('div', get_string('adminhelpenvironment'));
|
||||
$select = new single_select(new moodle_url('/admin/environment.php'), 'version', $versions, $version, null);
|
||||
$select->label = get_string('moodleversion');
|
||||
$output .= $this->render($select);
|
||||
$output .= $this->box_end();
|
||||
|
||||
// The results
|
||||
$output .= $this->environment_check_table($envstatus, $environment_results);
|
||||
|
||||
$output .= $this->footer();
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a warning message, of the type that appears on the admin notifications page.
|
||||
* @param string $message the message to display.
|
||||
* @param string $type type class
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
protected function warning($message, $type = 'warning') {
|
||||
return $this->box($message, 'generalbox admin' . $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an appropriate message if dataroot is insecure.
|
||||
* @param bool $insecuredataroot
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
protected function insecure_dataroot_warning($insecuredataroot) {
|
||||
global $CFG;
|
||||
|
||||
if ($insecuredataroot == INSECURE_DATAROOT_WARNING) {
|
||||
return $this->warning(get_string('datarootsecuritywarning', 'admin', $CFG->dataroot));
|
||||
|
||||
} else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
|
||||
return $this->warning(get_string('datarootsecurityerror', 'admin', $CFG->dataroot), 'error');
|
||||
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an appropriate message if dataroot is insecure.
|
||||
* @param bool $errorsdisplayed
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
protected function display_errors_warning($errorsdisplayed) {
|
||||
if (!$errorsdisplayed) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->warning(get_string('displayerrorswarning', 'admin'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an appropriate message if cron has not been run recently.
|
||||
* @param bool $cronoverdue
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function cron_overdue_warning($cronoverdue) {
|
||||
if (!$cronoverdue) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->warning(get_string('cronwarning', 'admin') . ' ' .
|
||||
$this->help_icon('cron', 'admin'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an appropriate message if there are any problems with the DB set-up.
|
||||
* @param bool $dbproblems
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function db_problems($dbproblems) {
|
||||
if (!$dbproblems) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->warning($dbproblems);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an appropriate message if the site in in maintenance mode.
|
||||
* @param bool $maintenancemode
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function maintenance_mode_warning($maintenancemode) {
|
||||
if (!$maintenancemode) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$url = new moodle_url('/admin/settings.php', array('section' => 'maintenancemode'));
|
||||
$url = $url->out(); // get_string() does not support objects in params
|
||||
|
||||
return $this->warning(get_string('sitemaintenancewarning2', 'admin', $url));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a warning about installing development code if necesary.
|
||||
* @param int $maturity
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
protected function maturity_warning($maturity) {
|
||||
if ($maturity == MATURITY_STABLE) {
|
||||
return ''; // No worries.
|
||||
}
|
||||
|
||||
$maturitylevel = get_string('maturity' . $maturity, 'admin');
|
||||
return $this->box(
|
||||
$this->container(get_string('maturitycorewarning', 'admin', $maturitylevel)) .
|
||||
$this->container($this->doc_link('admin/versions', get_string('morehelp'))),
|
||||
'generalbox maturitywarning');
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the copyright notice.
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
protected function moodle_copyright() {
|
||||
global $CFG;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//// IT IS ILLEGAL AND A VIOLATION OF THE GPL TO HIDE, REMOVE OR MODIFY THIS COPYRIGHT NOTICE ///
|
||||
$copyrighttext = '<a href="http://moodle.org/">Moodle</a> '.
|
||||
'<a href="http://docs.moodle.org/dev/Releases" title="'.$CFG->version.'">'.$CFG->release.'</a><br />'.
|
||||
'Copyright © 1999 onwards, Martin Dougiamas<br />'.
|
||||
'and <a href="http://docs.moodle.org/dev/Credits">many other contributors</a>.<br />'.
|
||||
'<a href="http://docs.moodle.org/dev/License">GNU Public License</a>';
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
return $this->box($copyrighttext, 'copyright');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a warning about installing development code if necesary.
|
||||
* @param int $maturity
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
protected function maturity_info($maturity) {
|
||||
if ($maturity == MATURITY_STABLE) {
|
||||
return ''; // No worries.
|
||||
}
|
||||
|
||||
$maturitylevel = get_string('maturity' . $maturity, 'admin');
|
||||
return $this->box(
|
||||
get_string('maturitycoreinfo', 'admin', $maturitylevel) . ' ' .
|
||||
$this->doc_link('admin/versions', get_string('morehelp')),
|
||||
'generalbox adminwarning maturityinfo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a link to the release notes.
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
protected function release_notes_link() {
|
||||
$releasenoteslink = get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/dev/Releases');
|
||||
$releasenoteslink = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $releasenoteslink); // extremely ugly validation hack
|
||||
return $this->box($releasenoteslink, 'generalbox releasenoteslink');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the reload link that appears on several upgrade/install pages.
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
function upgrade_reload($url) {
|
||||
return html_writer::empty_tag('br') .
|
||||
html_writer::tag('div',
|
||||
html_writer::link($url, $this->pix_icon('i/reload', '') .
|
||||
get_string('reload'), array('title' => get_string('reload'))),
|
||||
array('class' => 'continuebutton')) . html_writer::empty_tag('br');
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays all known plugins and information about their installation or upgrade
|
||||
*
|
||||
@@ -427,13 +39,11 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
* options support:
|
||||
* (bool)full = false: whether to display up-to-date plugins, too
|
||||
*
|
||||
* @param plugin_manager $pluginman provides information about the plugins.
|
||||
* @param int $version the version of the Moodle code from version.php.
|
||||
* @param array $plugininfo as returned by {@see plugin_manager::get_plugins()}
|
||||
* @param array $options rendering options
|
||||
* @return string HTML code
|
||||
*/
|
||||
public function plugins_check_table(plugin_manager $pluginman, $version, array $options = null) {
|
||||
$plugininfo = $pluginman->get_plugins();
|
||||
public function plugins_check(array $plugininfo, array $options = null) {
|
||||
|
||||
if (empty($plugininfo)) {
|
||||
return '';
|
||||
@@ -445,6 +55,8 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
);
|
||||
}
|
||||
|
||||
$pluginman = plugin_manager::instance();
|
||||
|
||||
$table = new html_table();
|
||||
$table->id = 'plugins-check';
|
||||
$table->head = array(
|
||||
@@ -453,11 +65,10 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
get_string('source', 'core_plugin'),
|
||||
get_string('versiondb', 'core_plugin'),
|
||||
get_string('versiondisk', 'core_plugin'),
|
||||
get_string('requires', 'core_plugin'),
|
||||
get_string('status', 'core_plugin'),
|
||||
);
|
||||
$table->colclasses = array(
|
||||
'displayname', 'rootdir', 'source', 'versiondb', 'versiondisk', 'requires', 'status',
|
||||
'displayname', 'rootdir', 'source', 'versiondb', 'versiondisk', 'status',
|
||||
);
|
||||
$table->data = array();
|
||||
|
||||
@@ -515,13 +126,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
|
||||
$status = new html_table_cell(get_string('status_' . $statuscode, 'core_plugin'));
|
||||
|
||||
$requires = new html_table_cell($this->required_column($plugin, $pluginman, $version));
|
||||
|
||||
$statusisboring = in_array($statuscode, array(
|
||||
plugin_manager::PLUGIN_STATUS_NODB, plugin_manager::PLUGIN_STATUS_UPTODATE));
|
||||
$dependenciesok = $pluginman->are_dependencies_satisfied(
|
||||
$plugin->get_other_required_plugins());
|
||||
if ($isstandard and $statusisboring and $dependenciesok) {
|
||||
if ($isstandard and in_array($statuscode, array(plugin_manager::PLUGIN_STATUS_NODB, plugin_manager::PLUGIN_STATUS_UPTODATE))) {
|
||||
if (empty($options['full'])) {
|
||||
continue;
|
||||
}
|
||||
@@ -529,8 +134,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$numofhighlighted[$type]++;
|
||||
}
|
||||
|
||||
$row->cells = array($displayname, $rootdir, $source,
|
||||
$versiondb, $versiondisk, $requires, $status);
|
||||
$row->cells = array($displayname, $rootdir, $source, $versiondb, $versiondisk, $status);
|
||||
$plugintyperows[] = $row;
|
||||
}
|
||||
|
||||
@@ -572,75 +176,22 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the information that needs to go in the 'Requires' column.
|
||||
* @param plugin_information $plugin the plugin we are rendering the row for.
|
||||
* @param plugin_manager $pluginman provides data on all the plugins.
|
||||
* @param string $version
|
||||
* @return string HTML code
|
||||
*/
|
||||
protected function required_column(plugin_information $plugin, plugin_manager $pluginman, $version) {
|
||||
$requires = array();
|
||||
|
||||
if (!empty($plugin->versionrequires)) {
|
||||
if ($plugin->versionrequires <= $version) {
|
||||
$class = 'requires-ok';
|
||||
} else {
|
||||
$class = 'requires-failed';
|
||||
}
|
||||
$requires[] = html_writer::tag('li',
|
||||
get_string('moodleversion', 'core_plugin', $plugin->versionrequires),
|
||||
array('class' => $class));
|
||||
}
|
||||
|
||||
foreach ($plugin->get_other_required_plugins() as $component => $requiredversion) {
|
||||
$ok = true;
|
||||
$otherplugin = $pluginman->get_plugin_info($component);
|
||||
|
||||
if (is_null($otherplugin)) {
|
||||
$ok = false;
|
||||
} else if ($requiredversion != ANY_VERSION and $otherplugin->versiondisk < $requiredversion) {
|
||||
$ok = false;
|
||||
}
|
||||
|
||||
if ($ok) {
|
||||
$class = 'requires-ok';
|
||||
} else {
|
||||
$class = 'requires-failed';
|
||||
}
|
||||
|
||||
if ($requiredversion != ANY_VERSION) {
|
||||
$str = 'otherpluginversion';
|
||||
} else {
|
||||
$str = 'otherplugin';
|
||||
}
|
||||
$requires[] = html_writer::tag('li',
|
||||
get_string($str, 'core_plugin',
|
||||
array('component' => $component, 'version' => $requiredversion)),
|
||||
array('class' => $class));
|
||||
}
|
||||
|
||||
if (!$requires) {
|
||||
return '';
|
||||
}
|
||||
return html_writer::tag('ul', implode("\n", $requires));
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays all known plugins and links to manage them
|
||||
*
|
||||
* This default implementation renders all plugins into one big table.
|
||||
*
|
||||
* @param plugin_manager $pluginman provides information about the plugins.
|
||||
* @param array $plugininfo as returned by {@see plugin_manager::get_plugins()}
|
||||
* @return string HTML code
|
||||
*/
|
||||
public function plugins_control_panel(plugin_manager $pluginman) {
|
||||
$plugininfo = $pluginman->get_plugins();
|
||||
public function plugins_control_panel(array $plugininfo) {
|
||||
|
||||
if (empty($plugininfo)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$pluginman = plugin_manager::instance();
|
||||
|
||||
$table = new html_table();
|
||||
$table->id = 'plugins-control-panel';
|
||||
$table->head = array(
|
||||
@@ -726,12 +277,8 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
}
|
||||
|
||||
$uninstallurl = $plugin->get_uninstall_url();
|
||||
$requriedby = $pluginman->other_plugins_that_require($plugin->component);
|
||||
if (is_null($uninstallurl)) {
|
||||
$uninstall = new html_table_cell('');
|
||||
} else if ($requriedby) {
|
||||
$uninstall = new html_table_cell(get_string('requiredby', 'core_plugin', implode(', ', $requriedby)));
|
||||
$uninstall->attributes['class'] = 'requiredby';
|
||||
} else {
|
||||
$uninstall = html_writer::link($uninstallurl, get_string('uninstall', 'core_plugin'));
|
||||
$uninstall = new html_table_cell($uninstall);
|
||||
@@ -746,183 +293,4 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
|
||||
return html_writer::table($table);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will render one beautiful table with all the environmental
|
||||
* configuration and how it suits Moodle needs.
|
||||
*
|
||||
* @param boolean $result final result of the check (true/false)
|
||||
* @param array $environment_results array of results gathered
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
public function environment_check_table($result, $environment_results) {
|
||||
global $CFG;
|
||||
|
||||
// Table headers
|
||||
$servertable = new html_table();//table for server checks
|
||||
$servertable->head = array(
|
||||
get_string('name'),
|
||||
get_string('info'),
|
||||
get_string('report'),
|
||||
get_string('status'),
|
||||
);
|
||||
$servertable->align = array('center', 'center', 'left', 'center');
|
||||
$servertable->wrap = array('nowrap', '', '', 'nowrap');
|
||||
$servertable->size = array('10', 10, '100%', '10');
|
||||
$servertable->attributes['class'] = 'environmenttable generaltable';
|
||||
|
||||
$serverdata = array('ok'=>array(), 'warn'=>array(), 'error'=>array());
|
||||
|
||||
$othertable = new html_table();//table for custom checks
|
||||
$othertable->head = array(
|
||||
get_string('info'),
|
||||
get_string('report'),
|
||||
get_string('status'),
|
||||
);
|
||||
$othertable->align = array('center', 'left', 'center');
|
||||
$othertable->wrap = array('', '', 'nowrap');
|
||||
$othertable->size = array(10, '100%', '10');
|
||||
$othertable->attributes['class'] = 'environmenttable generaltable';
|
||||
|
||||
$otherdata = array('ok'=>array(), 'warn'=>array(), 'error'=>array());
|
||||
|
||||
// Iterate over each environment_result
|
||||
$continue = true;
|
||||
foreach ($environment_results as $environment_result) {
|
||||
$errorline = false;
|
||||
$warningline = false;
|
||||
$stringtouse = '';
|
||||
if ($continue) {
|
||||
$type = $environment_result->getPart();
|
||||
$info = $environment_result->getInfo();
|
||||
$status = $environment_result->getStatus();
|
||||
$error_code = $environment_result->getErrorCode();
|
||||
// Process Report field
|
||||
$rec = new stdClass();
|
||||
// Something has gone wrong at parsing time
|
||||
if ($error_code) {
|
||||
$stringtouse = 'environmentxmlerror';
|
||||
$rec->error_code = $error_code;
|
||||
$status = get_string('error');
|
||||
$errorline = true;
|
||||
$continue = false;
|
||||
}
|
||||
|
||||
if ($continue) {
|
||||
if ($rec->needed = $environment_result->getNeededVersion()) {
|
||||
// We are comparing versions
|
||||
$rec->current = $environment_result->getCurrentVersion();
|
||||
if ($environment_result->getLevel() == 'required') {
|
||||
$stringtouse = 'environmentrequireversion';
|
||||
} else {
|
||||
$stringtouse = 'environmentrecommendversion';
|
||||
}
|
||||
|
||||
} else if ($environment_result->getPart() == 'custom_check') {
|
||||
// We are checking installed & enabled things
|
||||
if ($environment_result->getLevel() == 'required') {
|
||||
$stringtouse = 'environmentrequirecustomcheck';
|
||||
} else {
|
||||
$stringtouse = 'environmentrecommendcustomcheck';
|
||||
}
|
||||
|
||||
} else if ($environment_result->getPart() == 'php_setting') {
|
||||
if ($status) {
|
||||
$stringtouse = 'environmentsettingok';
|
||||
} else if ($environment_result->getLevel() == 'required') {
|
||||
$stringtouse = 'environmentmustfixsetting';
|
||||
} else {
|
||||
$stringtouse = 'environmentshouldfixsetting';
|
||||
}
|
||||
|
||||
} else {
|
||||
if ($environment_result->getLevel() == 'required') {
|
||||
$stringtouse = 'environmentrequireinstall';
|
||||
} else {
|
||||
$stringtouse = 'environmentrecommendinstall';
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the status value
|
||||
if ($environment_result->getBypassStr() != '') { //Handle bypassed result (warning)
|
||||
$status = get_string('bypassed');
|
||||
$warningline = true;
|
||||
} else if ($environment_result->getRestrictStr() != '') { //Handle restricted result (error)
|
||||
$status = get_string('restricted');
|
||||
$errorline = true;
|
||||
} else {
|
||||
if ($status) { //Handle ok result (ok)
|
||||
$status = get_string('ok');
|
||||
} else {
|
||||
if ($environment_result->getLevel() == 'optional') {//Handle check result (warning)
|
||||
$status = get_string('check');
|
||||
$warningline = true;
|
||||
} else { //Handle error result (error)
|
||||
$status = get_string('check');
|
||||
$errorline = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build the text
|
||||
$linkparts = array();
|
||||
$linkparts[] = 'admin/environment';
|
||||
$linkparts[] = $type;
|
||||
if (!empty($info)){
|
||||
$linkparts[] = $info;
|
||||
}
|
||||
if (empty($CFG->docroot)) {
|
||||
$report = get_string($stringtouse, 'admin', $rec);
|
||||
} else {
|
||||
$report = $this->doc_link(join($linkparts, '/'), get_string($stringtouse, 'admin', $rec));
|
||||
}
|
||||
|
||||
// Format error or warning line
|
||||
if ($errorline || $warningline) {
|
||||
$messagetype = $errorline? 'error':'warn';
|
||||
} else {
|
||||
$messagetype = 'ok';
|
||||
}
|
||||
$status = '<span class="'.$messagetype.'">'.$status.'</span>';
|
||||
// Here we'll store all the feedback found
|
||||
$feedbacktext = '';
|
||||
// Append the feedback if there is some
|
||||
$feedbacktext .= $environment_result->strToReport($environment_result->getFeedbackStr(), $messagetype);
|
||||
//Append the bypass if there is some
|
||||
$feedbacktext .= $environment_result->strToReport($environment_result->getBypassStr(), 'warn');
|
||||
//Append the restrict if there is some
|
||||
$feedbacktext .= $environment_result->strToReport($environment_result->getRestrictStr(), 'error');
|
||||
|
||||
$report .= $feedbacktext;
|
||||
|
||||
// Add the row to the table
|
||||
if ($environment_result->getPart() == 'custom_check'){
|
||||
$otherdata[$messagetype][] = array ($info, $report, $status);
|
||||
} else {
|
||||
$serverdata[$messagetype][] = array ($type, $info, $report, $status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//put errors first in
|
||||
$servertable->data = array_merge($serverdata['error'], $serverdata['warn'], $serverdata['ok']);
|
||||
$othertable->data = array_merge($otherdata['error'], $otherdata['warn'], $otherdata['ok']);
|
||||
|
||||
// Print table
|
||||
$output = '';
|
||||
$output .= $this->heading(get_string('serverchecks', 'admin'));
|
||||
$output .= html_writer::table($servertable);
|
||||
if (count($othertable->data)){
|
||||
$output .= $this->heading(get_string('customcheck', 'admin'));
|
||||
$output .= html_writer::table($othertable);
|
||||
}
|
||||
|
||||
// Finally, if any error has happened, print the summary box
|
||||
if (!$result) {
|
||||
$output .= $this->box(get_string('environmenterrortodo', 'admin'), 'environmentbox errorbox');
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/// Search and replace strings throughout all texts in the whole database
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->dirroot.'/course/lib.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('replace');
|
||||
|
||||
$search = optional_param('search', '', PARAM_RAW);
|
||||
$replace = optional_param('replace', '', PARAM_RAW);
|
||||
$sure = optional_param('sure', 0, PARAM_BOOL);
|
||||
|
||||
###################################################################
|
||||
echo $OUTPUT->header();
|
||||
|
||||
echo $OUTPUT->heading('Search and replace text throughout the whole database');
|
||||
|
||||
if ($DB->get_dbfamily() !== 'mysql' and $DB->get_dbfamily() !== 'postgres') {
|
||||
//TODO: add $DB->text_replace() to DML drivers
|
||||
echo $OUTPUT->notification('Sorry, this feature is implemented only for MySQL and PostgreSQL databases.');
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
}
|
||||
|
||||
if (!data_submitted() or !$search or !$replace or !confirm_sesskey() or !$sure) { /// Print a form
|
||||
echo $OUTPUT->notification('This script is not supported, always make complete backup before proceeding!<br />This operation can not be reverted!');
|
||||
|
||||
echo $OUTPUT->box_start();
|
||||
echo '<div class="mdl-align">';
|
||||
echo '<form action="replace.php" method="post"><div>';
|
||||
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
|
||||
echo '<div><label for="search">Search whole database for: </label><input id="search" type="text" name="search" size="40" /> (usually previous server URL)</div>';
|
||||
echo '<div><label for="replace">Replace with this string: </label><input type="text" id="replace" name="replace" size="40" /> (usually new server URL)</div>';
|
||||
echo '<div><label for="sure">I understand the risks of this operation: </label><input type="checkbox" id="sure" name="sure" value="1" /></div>';
|
||||
echo '<div class="buttons"><input type="submit" class="singlebutton" value="Yes, do it now" /></div>';
|
||||
echo '</div></form>';
|
||||
echo '</div>';
|
||||
echo $OUTPUT->box_end();
|
||||
echo $OUTPUT->footer();
|
||||
die;
|
||||
}
|
||||
|
||||
echo $OUTPUT->box_start();
|
||||
db_replace($search, $replace);
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
/// Rebuild course cache which might be incorrect now
|
||||
echo $OUTPUT->notification('Rebuilding course cache...', 'notifysuccess');
|
||||
rebuild_course_cache();
|
||||
echo $OUTPUT->notification('...finished', 'notifysuccess');
|
||||
|
||||
echo $OUTPUT->continue_button('index.php');
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
// index.php - scheduled backup logs
|
||||
|
||||
require_once('../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->dirroot.'/backup/lib.php');
|
||||
|
||||
$courseid = optional_param('courseid', 0, PARAM_INT);
|
||||
|
||||
admin_externalpage_setup('reportbackups');
|
||||
echo $OUTPUT->header();
|
||||
|
||||
/// Automated backups aren't active by the site admin
|
||||
$backup_config = backup_get_config();
|
||||
if (empty($backup_config->backup_auto_active)) {
|
||||
echo $OUTPUT->notification(get_string('automatedbackupsinactive', 'backup'));
|
||||
}
|
||||
|
||||
/// Get needed strings
|
||||
$backuploglaststatus = get_string("backuploglaststatus");
|
||||
$backuplogdetailed = get_string("backuplogdetailed");
|
||||
$stradmin = get_string("administration");
|
||||
$strconfiguration = get_string("configuration");
|
||||
$strbackup = get_string("backup");
|
||||
$strbackupdetails = get_string("backupdetails");
|
||||
$strlogs = get_string("logs");
|
||||
$strftimedatetime = get_string("strftimerecent");
|
||||
$strftimetime = get_string("strftimetime").":%S";
|
||||
$strerror = get_string("error");
|
||||
$strok = get_string("ok");
|
||||
$strunfinished = get_string("unfinished");
|
||||
$strskipped = get_string("skipped");
|
||||
$strcourse = get_string("course");
|
||||
$strtimetaken = get_string("timetaken","quiz");
|
||||
$strstatus = get_string("status");
|
||||
$strnext = get_string("backupnext");
|
||||
|
||||
/// Decide when to show last execution logs or detailed logs
|
||||
/// Lastlog view
|
||||
if (!$courseid) {
|
||||
echo $OUTPUT->heading($backuploglaststatus);
|
||||
echo $OUTPUT->box_start();
|
||||
/// Now, get every record from backup_courses
|
||||
$courses = $DB->get_records("backup_courses");
|
||||
|
||||
if (!$courses) {
|
||||
echo $OUTPUT->notification(get_string('nologsfound'));
|
||||
} else {
|
||||
echo "<table border=\"0\" align=\"center\" cellpadding=\"3\" cellspacing=\"3\">";
|
||||
//Print table header
|
||||
echo "<tr>";
|
||||
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"3\">$strcourse</font></td>";
|
||||
echo "<td nowrap=\"nowrap\" align=\"center\" colspan=\"3\"><font size=\"3\">$strtimetaken</font></td>";
|
||||
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"3\">$strstatus</font></td>";
|
||||
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"3\">$strnext</font></td></tr>";
|
||||
foreach ($courses as $course) {
|
||||
/// Get the course shortname
|
||||
$coursename = $DB->get_field ("course", "fullname", array("id"=>$course->courseid));
|
||||
if ($coursename) {
|
||||
echo "<tr>";
|
||||
echo "<td nowrap=\"nowrap\"><font size=\"2\"><a href=\"index.php?courseid=$course->courseid\">".$coursename."</a></font></td>";
|
||||
echo "<td nowrap=\"nowrap\"><font size=\"2\">".userdate($course->laststarttime,$strftimedatetime)."</font></td>";
|
||||
echo "<td nowrap=\"nowrap\"><font size=\"2\"> - </font></td>";
|
||||
echo "<td nowrap=\"nowrap\"><font size=\"2\">".userdate($course->lastendtime,$strftimedatetime)."</font></td>";
|
||||
if ($course->laststatus == 1) {
|
||||
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"2\" color=\"green\">".$strok."</font></td>";
|
||||
} else if ($course->laststatus == 2) {
|
||||
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"2\" color=\"red\">".$strunfinished."</font></td>";
|
||||
} else if ($course->laststatus == 3) {
|
||||
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"2\" color=\"green\">".$strskipped."</font></td>";
|
||||
} else {
|
||||
echo "<td nowrap=\"nowrap\" align=\"center\"><font size=\"2\" color=\"red\">".$strerror."</font></td>";
|
||||
}
|
||||
echo "<td nowrap=\"nowrap\"><font size=\"2\">".userdate($course->nextstarttime,$strftimedatetime)."</font></td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
echo $OUTPUT->box_end();
|
||||
/// Detailed View !!
|
||||
} else {
|
||||
echo $OUTPUT->heading($backuplogdetailed);
|
||||
|
||||
$coursename = $DB->get_field("course", "fullname", array("id"=>"$courseid"));
|
||||
echo $OUTPUT->heading("$strcourse: $coursename");
|
||||
|
||||
echo $OUTPUT->box_start();
|
||||
|
||||
/// First, me get all the distinct backups for that course in backup_log
|
||||
$executions = $DB->get_records_sql("SELECT DISTINCT laststarttime
|
||||
FROM {backup_log}
|
||||
WHERE courseid = ? AND backuptype = ?
|
||||
ORDER BY laststarttime DESC", array($courseid,'scheduledbackup'));
|
||||
|
||||
/// Iterate over backup executions
|
||||
if (!$executions) {
|
||||
echo $OUTPUT->notification(get_string('nologsfound'));
|
||||
} else {
|
||||
echo "<table border=\"0\" align=\"center\" cellpadding=\"3\" cellspacing=\"3\">";
|
||||
foreach($executions as $execution) {
|
||||
echo "<tr>";
|
||||
echo "<td nowrap=\"nowrap\" align=\"center\" colspan=\"3\">";
|
||||
echo $OUTPUT->box(userdate($execution->laststarttime));
|
||||
echo "</td>";
|
||||
echo "</tr>";
|
||||
$logs = $DB->get_records_sql("SELECT *
|
||||
FROM {backup_log}
|
||||
WHERE courseid = ? AND laststarttime = ? AND backuptype = ?
|
||||
ORDER BY id", array($courseid, $execution->laststarttime,'scheduledbackup'));
|
||||
if ($logs) {
|
||||
foreach ($logs as $log) {
|
||||
echo "<tr>";
|
||||
echo "<td nowrap=\"nowrap\"><font size=\"2\">".userdate($log->time,$strftimetime)."</font></td>";
|
||||
$log->info = str_replace("- ERROR!!","- <font color=\"red\">ERROR!!</font>",$log->info);
|
||||
$log->info = str_replace("- OK","- <font color=\"green\">OK</font>",$log->info);
|
||||
echo "<td nowrap=\"nowrap\"><font size=\"2\">".str_replace(" "," ",$log->info)."</font></td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
}
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
echo $OUTPUT->box_end();
|
||||
}
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$ADMIN->add('reports', new admin_externalpage('reportbackups', get_string('backups', 'admin'), "$CFG->wwwroot/$CFG->admin/report/backups/index.php",'moodle/backup:backupcourse'));
|
||||
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
/**
|
||||
* For a given capability, show what permission it has for every role, and
|
||||
* everywhere that it is overridden.
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package roles
|
||||
*/
|
||||
|
||||
/** */
|
||||
require_once(dirname(__FILE__).'/../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
// Check permissions.
|
||||
require_login();
|
||||
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
require_capability('moodle/role:manage', $systemcontext);
|
||||
|
||||
// Get URL parameters.
|
||||
$capability = optional_param('capability', '', PARAM_CAPABILITY);
|
||||
$roleids = optional_param('roles', array('0'), PARAM_INTEGER);
|
||||
|
||||
// Clean the passed in list of role ids. If 'All' selected as an option, or
|
||||
// if none were selected, do all roles.
|
||||
$allroles = get_all_roles();
|
||||
$cleanedroleids = array();
|
||||
foreach ($roleids as $roleid) {
|
||||
if ($roleid == 0) {
|
||||
$cleanedroleids = array_keys($allroles);
|
||||
break;
|
||||
}
|
||||
if (array_key_exists($roleid, $allroles)) {
|
||||
$cleanedroleids[] = $roleid;
|
||||
}
|
||||
}
|
||||
if (empty($cleanedroleids)) {
|
||||
$cleanedroleids = array_keys($allroles);
|
||||
}
|
||||
|
||||
// Include the required JavaScript.
|
||||
$PAGE->requires->js_init_call('M.report_capability.init', array(get_string('search')));
|
||||
|
||||
// Log.
|
||||
add_to_log(SITEID, "admin", "report capability", "report/capability/index.php?capability=$capability", $capability);
|
||||
|
||||
// Print the header.
|
||||
admin_externalpage_setup('reportcapability');
|
||||
echo $OUTPUT->header();
|
||||
|
||||
// Prepare the list of capabilities to choose from
|
||||
$allcapabilities = fetch_context_capabilities($systemcontext);
|
||||
$capabilitychoices = array();
|
||||
foreach ($allcapabilities as $cap) {
|
||||
$capabilitychoices[$cap->name] = $cap->name . ': ' . get_capability_string($cap->name);
|
||||
}
|
||||
|
||||
// Prepare the list of roles to choose from
|
||||
$rolechoices = array('0' => get_string('all'));
|
||||
foreach ($allroles as $role) {
|
||||
$rolechoices[$role->id] = $role->name;
|
||||
}
|
||||
if (count($cleanedroleids) == count($allroles)) {
|
||||
// Select 'All', rather than each role individually.
|
||||
$selectedroleids = array('0');
|
||||
} else {
|
||||
$selectedroleids = $cleanedroleids;
|
||||
}
|
||||
|
||||
// Print the settings form.
|
||||
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
|
||||
echo '<form method="get" action="." id="settingsform"><div>';
|
||||
echo $OUTPUT->heading(get_string('reportsettings', 'report_capability'));
|
||||
echo '<p id="intro">', get_string('intro', 'report_capability') , '</p>';
|
||||
echo '<p><label for="menucapability"> ' . get_string('capabilitylabel', 'report_capability') . '</label></p>';
|
||||
echo html_writer::select($capabilitychoices, 'capability', $capability, array(''=>'choose'), array('size'=>10));
|
||||
echo '<p><label for="menuroles"> ' . get_string('roleslabel', 'report_capability') . '</label></p>';
|
||||
echo html_writer::select($rolechoices, 'roles[]', $selectedroleids, false, array('size'=>10, 'multiple'=>'multiple'));
|
||||
echo '<p><input type="submit" id="settingssubmit" value="' . get_string('getreport', 'report_capability') . '" /></p>';
|
||||
echo '</div></form>';
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
// If we have a capability, generate the report.
|
||||
if ($capability) {
|
||||
|
||||
// Work out the bits needed for the SQL WHERE clauses.
|
||||
$params = array($capability);
|
||||
$sqlroletest = '';
|
||||
if (count($cleanedroleids) != count($allroles)) {
|
||||
list($sqlroletest, $roleparams) = $DB->get_in_or_equal($cleanedroleids);
|
||||
$params = array_merge($params, $roleparams);
|
||||
$sqlroletest = 'AND roleid ' . $sqlroletest;
|
||||
}
|
||||
|
||||
// Get all the role_capabilities rows for this capability - that is, all
|
||||
// role definitions, and all role overrides.
|
||||
$rolecaps = $DB->get_records_sql("
|
||||
SELECT id, roleid, contextid, permission
|
||||
FROM {role_capabilities}
|
||||
WHERE capability = ? $sqlroletest", $params);
|
||||
|
||||
// In order to display a nice tree of contexts, we need to get all the
|
||||
// ancestors of all the contexts in the query we just did.
|
||||
$relevantpaths = $DB->get_records_sql_menu("
|
||||
SELECT DISTINCT con.path, 1
|
||||
FROM {context} con JOIN {role_capabilities} rc ON rc.contextid = con.id
|
||||
WHERE capability = ? $sqlroletest", $params);
|
||||
$requiredcontexts = array($systemcontext->id);
|
||||
foreach ($relevantpaths as $path => $notused) {
|
||||
$requiredcontexts = array_merge($requiredcontexts, explode('/', trim($path, '/')));
|
||||
}
|
||||
$requiredcontexts = array_unique($requiredcontexts);
|
||||
|
||||
// Now load those contexts.
|
||||
list($sqlcontexttest, $contextparams) = $DB->get_in_or_equal($requiredcontexts);
|
||||
$contexts = get_sorted_contexts('ctx.id ' . $sqlcontexttest, $contextparams);
|
||||
|
||||
// Prepare some empty arrays to hold the data we are about to compute.
|
||||
foreach ($contexts as $conid => $con) {
|
||||
$contexts[$conid]->children = array();
|
||||
$contexts[$conid]->rolecapabilities = array();
|
||||
}
|
||||
|
||||
// Put the contexts into a tree structure.
|
||||
foreach ($contexts as $conid => $con) {
|
||||
$parentcontextid = get_parent_contextid($con);
|
||||
if ($parentcontextid) {
|
||||
$contexts[$parentcontextid]->children[] = $conid;
|
||||
}
|
||||
}
|
||||
|
||||
// Put the role capabilities into the context tree.
|
||||
foreach ($rolecaps as $rolecap) {
|
||||
$contexts[$rolecap->contextid]->rolecapabilities[$rolecap->roleid] = $rolecap->permission;
|
||||
}
|
||||
|
||||
// Fill in any missing rolecaps for the system context.
|
||||
foreach ($cleanedroleids as $roleid) {
|
||||
if (!isset($contexts[$systemcontext->id]->rolecapabilities[$roleid])) {
|
||||
$contexts[$systemcontext->id]->rolecapabilities[$roleid] = CAP_INHERIT;
|
||||
}
|
||||
}
|
||||
|
||||
// Print the report heading.
|
||||
echo $OUTPUT->heading(get_string('reportforcapability', 'report_capability', get_capability_string($capability)), 2, 'main', 'report');
|
||||
if (count($cleanedroleids) != count($allroles)) {
|
||||
$rolenames = array();
|
||||
foreach ($cleanedroleids as $roleid) {
|
||||
$rolenames[] = $allroles[$roleid]->name;
|
||||
}
|
||||
echo '<p>', get_string('forroles', 'report_capability', implode(', ', $rolenames)), '</p>';
|
||||
}
|
||||
|
||||
// Now, recursively print the contexts, and the role information.
|
||||
print_report_tree($systemcontext->id, $contexts, $allroles);
|
||||
}
|
||||
|
||||
// Footer.
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
function print_report_tree($contextid, $contexts, $allroles) {
|
||||
global $CFG;
|
||||
|
||||
// Array for holding lang strings.
|
||||
static $strpermissions = null;
|
||||
if (is_null($strpermissions)) {
|
||||
$strpermissions = array(
|
||||
CAP_INHERIT => get_string('notset','role'),
|
||||
CAP_ALLOW => get_string('allow','role'),
|
||||
CAP_PREVENT => get_string('prevent','role'),
|
||||
CAP_PROHIBIT => get_string('prohibit','role')
|
||||
);
|
||||
}
|
||||
|
||||
// Start the list item, and print the context name as a link to the place to
|
||||
// make changes.
|
||||
if ($contextid == get_system_context()->id) {
|
||||
$url = "$CFG->wwwroot/$CFG->admin/roles/manage.php";
|
||||
$title = get_string('changeroles', 'report_capability');
|
||||
} else {
|
||||
$url = "$CFG->wwwroot/$CFG->admin/roles/override.php?contextid=$contextid";
|
||||
$title = get_string('changeoverrides', 'report_capability');
|
||||
}
|
||||
echo '<h3><a href="' . $url . '" title="' . $title . '">', print_context_name($contexts[$contextid]), '</a></h3>';
|
||||
|
||||
// If there are any role overrides here, print them.
|
||||
if (!empty($contexts[$contextid]->rolecapabilities)) {
|
||||
$rowcounter = 0;
|
||||
echo '<table class="generaltable rolecaps"><tbody>';
|
||||
foreach ($allroles as $role) {
|
||||
if (isset($contexts[$contextid]->rolecapabilities[$role->id])) {
|
||||
$permission = $contexts[$contextid]->rolecapabilities[$role->id];
|
||||
echo '<tr class="r' . ($rowcounter % 2) . '"><th class="cell">', $role->name,
|
||||
'</th><td class="cell">' . $strpermissions[$permission] . '</td></tr>';
|
||||
$rowcounter++;
|
||||
}
|
||||
}
|
||||
echo '</tbody></table>';
|
||||
}
|
||||
|
||||
// After we have done the site context, change the string for CAP_INHERIT
|
||||
// from 'notset' to 'inherit'.
|
||||
$strpermissions[CAP_INHERIT] = get_string('inherit','role');
|
||||
|
||||
// If there are any child contexts, print them recursively.
|
||||
if (!empty($contexts[$contextid]->children)) {
|
||||
echo '<ul>';
|
||||
foreach ($contexts[$contextid]->children as $childcontextid) {
|
||||
echo '<li>';
|
||||
print_report_tree($childcontextid, $contexts, $allroles);
|
||||
echo '</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Strings for component 'report_capability', language 'en', branch 'MOODLE_20_STABLE'
|
||||
*
|
||||
* @package report_capability
|
||||
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['capabilitylabel'] = 'Capability:';
|
||||
$string['capabilityreport'] = 'Capability report';
|
||||
$string['forroles'] = 'For roles {$a}';
|
||||
$string['getreport'] = 'Get the report';
|
||||
$string['changeoverrides'] = 'Change overrides in this context';
|
||||
$string['changeroles'] = 'Change role definitions';
|
||||
$string['intro'] = 'This report shows, for a particular capability, what permission that capability has in the definition of every role (or a selection of roles), and everywhere in the site where that capability is overridden.';
|
||||
$string['pluginname'] = 'Capability report';
|
||||
$string['reportforcapability'] = 'Report for capability \'{$a}\'';
|
||||
$string['reportsettings'] = 'Report settings';
|
||||
$string['roleslabel'] = 'Roles:';
|
||||
@@ -0,0 +1,75 @@
|
||||
|
||||
M.report_capability = {
|
||||
select: null,
|
||||
input: null,
|
||||
button: null,
|
||||
|
||||
init: function(Y, strsearch) {
|
||||
var context = M.report_capability;
|
||||
|
||||
// Find the form controls.
|
||||
context.select = document.getElementById('menucapability');
|
||||
context.button = document.getElementById('settingssubmit');
|
||||
|
||||
// Create a div to hold the search UI.
|
||||
var div = document.createElement('div');
|
||||
div.id = 'capabilitysearchui';
|
||||
|
||||
// Find the capability search input.
|
||||
var input = document.createElement('input');
|
||||
input.type = 'text';
|
||||
input.id = 'capabilitysearch';
|
||||
context.input = input;
|
||||
|
||||
// Create a label for the search input.
|
||||
var label = document.createElement('label');
|
||||
label.htmlFor = input.id;
|
||||
label.appendChild(document.createTextNode(strsearch + ' '));
|
||||
|
||||
// Tie it all together
|
||||
div.appendChild(label);
|
||||
div.appendChild(input);
|
||||
context.select.parentNode.insertBefore(div, context.select);
|
||||
Y.on('keyup', context.typed, input);
|
||||
Y.on('change', context.validate, context.select);
|
||||
context.select.options[0].style.display = 'none';
|
||||
context.validate();
|
||||
},
|
||||
|
||||
typed: function() {
|
||||
var context = M.report_capability;
|
||||
|
||||
var filtertext = context.input.value;
|
||||
var options = context.select.options;
|
||||
var onlycapability = -1;
|
||||
for (var i = 1; i < options.length; i++) {
|
||||
if (options[i].text.indexOf(filtertext) >= 0) {
|
||||
options[i].disabled = false;
|
||||
options[i].style.display = 'block';
|
||||
if (onlycapability == -1) {
|
||||
onlycapability = i;
|
||||
} else {
|
||||
onlycapability = -2;
|
||||
}
|
||||
} else {
|
||||
options[i].disabled = true;
|
||||
options[i].selected = false;
|
||||
options[i].style.display = 'none';
|
||||
}
|
||||
}
|
||||
if (onlycapability >= 0) {
|
||||
options[onlycapability].selected = true;
|
||||
}
|
||||
if (onlycapability == -1) {
|
||||
context.input.className = "error";
|
||||
} else {
|
||||
context.input.className = "";
|
||||
}
|
||||
context.validate();
|
||||
},
|
||||
|
||||
validate: function() {
|
||||
var context = M.report_capability;
|
||||
context.button.disabled = (context.select.value == '');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$ADMIN->add('roles', new admin_externalpage('reportcapability', get_string('pluginname', 'report_capability'), "$CFG->wwwroot/$CFG->admin/report/capability/index.php",'moodle/role:manage'));
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
require_once(dirname(__FILE__).'/../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
// page parameters
|
||||
$page = optional_param('page', 0, PARAM_INT);
|
||||
$perpage = optional_param('perpage', 30, PARAM_INT); // how many per page
|
||||
$sort = optional_param('sort', 'timemodified', PARAM_ALPHA);
|
||||
$dir = optional_param('dir', 'DESC', PARAM_ALPHA);
|
||||
|
||||
admin_externalpage_setup('reportconfiglog');
|
||||
echo $OUTPUT->header();
|
||||
|
||||
echo $OUTPUT->heading(get_string('configlog', 'report_configlog'));
|
||||
|
||||
$changescount = $DB->count_records('config_log');
|
||||
|
||||
$columns = array('firstname' => get_string('firstname'),
|
||||
'lastname' => get_string('lastname'),
|
||||
'timemodified' => get_string('timemodified', 'report_configlog'),
|
||||
'plugin' => get_string('plugin', 'report_configlog'),
|
||||
'name' => get_string('setting', 'report_configlog'),
|
||||
'value' => get_string('value', 'report_configlog'),
|
||||
'oldvalue' => get_string('oldvalue', 'report_configlog'),
|
||||
);
|
||||
$hcolumns = array();
|
||||
|
||||
|
||||
if (!isset($columns[$sort])) {
|
||||
$sort = 'lastname';
|
||||
}
|
||||
|
||||
foreach ($columns as $column=>$strcolumn) {
|
||||
if ($sort != $column) {
|
||||
$columnicon = '';
|
||||
if ($column == 'lastaccess') {
|
||||
$columndir = 'DESC';
|
||||
} else {
|
||||
$columndir = 'ASC';
|
||||
}
|
||||
} else {
|
||||
$columndir = $dir == 'ASC' ? 'DESC':'ASC';
|
||||
if ($column == 'lastaccess') {
|
||||
$columnicon = $dir == 'ASC' ? 'up':'down';
|
||||
} else {
|
||||
$columnicon = $dir == 'ASC' ? 'down':'up';
|
||||
}
|
||||
$columnicon = " <img src=\"" . $OUTPUT->pix_url('t/' . $columnicon) . "\" alt=\"\" />";
|
||||
|
||||
}
|
||||
$hcolumns[$column] = "<a href=\"index.php?sort=$column&dir=$columndir&page=$page&perpage=$perpage\">".$strcolumn."</a>$columnicon";
|
||||
}
|
||||
|
||||
$baseurl = new moodle_url('index.php', array('sort' => $sort, 'dir' => $dir, 'perpage' => $perpage));
|
||||
echo $OUTPUT->paging_bar($changescount, $page, $perpage, $baseurl);
|
||||
|
||||
$override = new stdClass();
|
||||
$override->firstname = 'firstname';
|
||||
$override->lastname = 'lastname';
|
||||
$fullnamelanguage = get_string('fullnamedisplay', '', $override);
|
||||
if (($CFG->fullnamedisplay == 'firstname lastname') or
|
||||
($CFG->fullnamedisplay == 'firstname') or
|
||||
($CFG->fullnamedisplay == 'language' and $fullnamelanguage == 'firstname lastname' )) {
|
||||
$fullnamedisplay = $hcolumns['firstname'].' / '.$hcolumns['lastname'];
|
||||
} else { // ($CFG->fullnamedisplay == 'language' and $fullnamelanguage == 'lastname firstname')
|
||||
$fullnamedisplay = $hcolumns['lastname'].' / '.$hcolumns['firstname'];
|
||||
}
|
||||
|
||||
$table = new html_table();
|
||||
$table->head = array($hcolumns['timemodified'], $fullnamedisplay, $hcolumns['plugin'], $hcolumns['name'], $hcolumns['value'], $hcolumns['oldvalue']);
|
||||
$table->align = array('left', 'left', 'left', 'left', 'left', 'left');
|
||||
$table->size = array('30%', '10%', '10%', '10%', '20%', '20%');
|
||||
$table->width = '95%';
|
||||
$table->data = array();
|
||||
|
||||
if ($sort == 'firstname' or $sort == 'lastname') {
|
||||
$orderby = "u.$sort $dir";
|
||||
} else {
|
||||
$orderby = "cl.$sort $dir";
|
||||
}
|
||||
|
||||
$ufields = user_picture::fields('u');
|
||||
$sql = "SELECT $ufields,
|
||||
cl.timemodified, cl.plugin, cl.name, cl.value, cl.oldvalue
|
||||
FROM {config_log} cl
|
||||
JOIN {user} u ON u.id = cl.userid
|
||||
ORDER BY $orderby";
|
||||
|
||||
$rs = $DB->get_recordset_sql($sql, array(), $page*$perpage, $perpage);
|
||||
foreach ($rs as $log) {
|
||||
$row = array();
|
||||
$row[] = userdate($log->timemodified);
|
||||
$row[] = fullname($log);
|
||||
if (is_null($log->plugin)) {
|
||||
$row[] = 'core';
|
||||
} else {
|
||||
$row[] = $log->plugin;
|
||||
}
|
||||
$row[] = $log->name;
|
||||
$row[] = s($log->value);
|
||||
$row[] = s($log->oldvalue);
|
||||
|
||||
$table->data[] = $row;
|
||||
}
|
||||
$rs->close();
|
||||
|
||||
echo html_writer::table($table);
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
+3
-4
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@@ -17,16 +18,14 @@
|
||||
/**
|
||||
* Strings for component 'report_configlog', language 'en', branch 'MOODLE_20_STABLE'
|
||||
*
|
||||
* @package report
|
||||
* @subplugin configlog
|
||||
* @copyright 2009 petr Skoda
|
||||
* @package report_configlog
|
||||
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['configlog'] = 'Config changes';
|
||||
$string['oldvalue'] = 'Original value';
|
||||
$string['plugin'] = 'Plugin';
|
||||
$string['pluginname'] = 'Config changes';
|
||||
$string['setting'] = 'Setting';
|
||||
$string['timemodified'] = 'Date';
|
||||
$string['value'] = 'New value';
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$ADMIN->add('reports', new admin_externalpage('reportconfiglog', get_string('configlog', 'report_configlog'), "$CFG->wwwroot/$CFG->admin/report/configlog/index.php"));
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.com //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$capabilities = array(
|
||||
|
||||
'report/courseoverview:view' => array(
|
||||
'riskbitmask' => RISK_PERSONAL,
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'archetypes' => array(
|
||||
'teacher' => CAP_ALLOW,
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
'manager' => CAP_ALLOW
|
||||
),
|
||||
|
||||
'clonepermissionsfrom' => 'moodle/site:viewreports',
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
require_once('../../../config.php');
|
||||
require_once($CFG->dirroot.'/lib/statslib.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
$report = optional_param('report', STATS_REPORT_ACTIVE_COURSES, PARAM_INT);
|
||||
$time = optional_param('time', 0, PARAM_INT);
|
||||
$numcourses = optional_param('numcourses', 20, PARAM_INT);
|
||||
|
||||
if (empty($CFG->enablestats)) {
|
||||
if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
|
||||
redirect("$CFG->wwwroot/$CFG->admin/settings.php?section=stats", get_string('mustenablestats', 'admin'), 3);
|
||||
} else {
|
||||
print_error('statsdisable');
|
||||
}
|
||||
}
|
||||
|
||||
admin_externalpage_setup('reportcourseoverview');
|
||||
echo $OUTPUT->header();
|
||||
|
||||
$course = get_site();
|
||||
stats_check_uptodate($course->id);
|
||||
|
||||
$strreports = get_string('reports');
|
||||
$strcourseoverview = get_string('courseoverview');
|
||||
|
||||
$reportoptions = stats_get_report_options($course->id,STATS_MODE_RANKED);
|
||||
|
||||
$earliestday = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_daily}');
|
||||
$earliestweek = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_weekly}');
|
||||
$earliestmonth = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_monthly}');
|
||||
|
||||
if (empty($earliestday)) $earliestday = time();
|
||||
if (empty($earliestweek)) $earliestweek = time();
|
||||
if (empty($earliestmonth)) $earliestmonth = time();
|
||||
|
||||
$now = stats_get_base_daily();
|
||||
$lastweekend = stats_get_base_weekly();
|
||||
$lastmonthend = stats_get_base_monthly();
|
||||
|
||||
$timeoptions = stats_get_time_options($now,$lastweekend,$lastmonthend,$earliestday,$earliestweek,$earliestmonth);
|
||||
|
||||
if (empty($timeoptions)) {
|
||||
print_error('nostatstodisplay', 'error', $CFG->wwwroot.'/course/view.php?id='.$course->id);
|
||||
}
|
||||
|
||||
echo '<form action="index.php" method="post">'."\n";
|
||||
echo '<div>';
|
||||
|
||||
$table = new html_table();
|
||||
$table->width = '*';
|
||||
$table->align = array('left','left','left','left','left','left');
|
||||
|
||||
$reporttypemenu = html_writer::select($reportoptions,'report',$report, false);
|
||||
$timeoptionsmenu = html_writer::select($timeoptions,'time',$time, false);
|
||||
|
||||
$table->data[] = array(get_string('statsreporttype'),$reporttypemenu,
|
||||
get_string('statstimeperiod'),$timeoptionsmenu,
|
||||
'<input type="text" name="numcourses" size="3" maxlength="2" value="'.$numcourses.'" />',
|
||||
'<input type="submit" value="'.get_string('view').'" />') ;
|
||||
|
||||
echo html_writer::table($table);
|
||||
echo '</div>';
|
||||
echo '</form>';
|
||||
|
||||
echo $OUTPUT->heading($reportoptions[$report]);
|
||||
|
||||
|
||||
if (!empty($report) && !empty($time)) {
|
||||
$param = stats_get_parameters($time,$report,SITEID,STATS_MODE_RANKED);
|
||||
if (!empty($param->sql)) {
|
||||
$sql = $param->sql;
|
||||
} else {
|
||||
$sql = "SELECT courseid,".$param->fields."
|
||||
FROM {".'stats_'.$param->table."}
|
||||
WHERE timeend >= $param->timeafter AND stattype = 'activity' AND roleid = 0
|
||||
GROUP BY courseid
|
||||
$param->extras
|
||||
ORDER BY $param->orderby";
|
||||
}
|
||||
|
||||
$courses = $DB->get_records_sql($sql, $param->params, 0, $numcourses);
|
||||
|
||||
if (empty($courses)) {
|
||||
echo $OUTPUT->notification(get_string('statsnodata'));
|
||||
echo '</td></tr></table>';
|
||||
|
||||
} else {
|
||||
if (empty($CFG->gdversion)) {
|
||||
echo '<div class="graph">(' . get_string("gdneed") .')</div>';
|
||||
} else {
|
||||
echo '<div class="graph"><img alt="'.get_string('courseoverviewgraph').'" src="'.$CFG->wwwroot.'/'.$CFG->admin.'/report/courseoverview/reportsgraph.php?time='.$time.'&report='.$report.'&numcourses='.$numcourses.'" /></div>';
|
||||
}
|
||||
|
||||
$table = new html_table();
|
||||
$table->align = array('left','center','center','center');
|
||||
$table->head = array(get_string('course'),$param->line1);
|
||||
if (!empty($param->line2)) {
|
||||
$table->head[] = $param->line2;
|
||||
}
|
||||
if (!empty($param->line3)) {
|
||||
$table->head[] = $param->line3;
|
||||
}
|
||||
|
||||
foreach ($courses as $c) {
|
||||
$a = array();
|
||||
$a[] = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$c->courseid.'">'.$DB->get_field('course', 'shortname', array('id'=>$c->courseid)).'</a>';
|
||||
|
||||
$a[] = $c->line1;
|
||||
if (isset($c->line2)) {
|
||||
$a[] = $c->line2;
|
||||
}
|
||||
if (isset($c->line3)) {
|
||||
$a[] = round($c->line3,2);
|
||||
}
|
||||
$table->data[] = $a;
|
||||
}
|
||||
echo html_writer::table($table);
|
||||
}
|
||||
}
|
||||
echo $OUTPUT->footer();
|
||||
@@ -0,0 +1,27 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Strings for component 'report_courseoverview', language 'en', branch 'MOODLE_20_STABLE'
|
||||
*
|
||||
* @package report_courseoverview
|
||||
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['courseoverview:view'] = 'View course overview report';
|
||||
$string['pluginname'] = 'Course overview';
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
require_once('../../../config.php');
|
||||
require_once($CFG->dirroot.'/lib/statslib.php');
|
||||
require_once($CFG->dirroot.'/lib/graphlib.php');
|
||||
|
||||
$report = required_param('report', PARAM_INT);
|
||||
$time = required_param('time', PARAM_INT);
|
||||
$numcourses = required_param('numcourses', PARAM_INT);
|
||||
|
||||
require_login();
|
||||
|
||||
require_capability('report/courseoverview:view', get_context_instance(CONTEXT_SYSTEM));
|
||||
|
||||
stats_check_uptodate();
|
||||
|
||||
$param = stats_get_parameters($time,$report,SITEID,STATS_MODE_RANKED);
|
||||
|
||||
if (!empty($param->sql)) {
|
||||
$sql = $param->sql;
|
||||
} else {
|
||||
$sql = "SELECT courseid, $param->fields
|
||||
FROM {".'stats_'.$param->table."}
|
||||
WHERE timeend >= $param->timeafter AND stattype = 'activity' AND roleid = 0
|
||||
GROUP BY courseid
|
||||
$param->extras
|
||||
ORDER BY $param->orderby";
|
||||
}
|
||||
|
||||
$courses = $DB->get_records_sql($sql, $param->params, 0, $numcourses);
|
||||
|
||||
if (empty($courses)) {
|
||||
$PAGE->set_url('/admin/report/courseoverview/index.php');
|
||||
print_error('statsnodata', 'error', $PAGE->url->out());
|
||||
}
|
||||
|
||||
|
||||
$graph = new graph(750,400);
|
||||
|
||||
$graph->parameter['legend'] = 'outside-right';
|
||||
$graph->parameter['legend_size'] = 10;
|
||||
$graph->parameter['x_axis_angle'] = 90;
|
||||
$graph->parameter['title'] = false; // moodle will do a nicer job.
|
||||
$graph->y_tick_labels = null;
|
||||
$graph->offset_relation = null;
|
||||
if ($report != STATS_REPORT_ACTIVE_COURSES) {
|
||||
$graph->parameter['y_decimal_left'] = 2;
|
||||
}
|
||||
|
||||
foreach ($courses as $c) {
|
||||
$graph->x_data[] = $DB->get_field('course', 'shortname', array('id'=>$c->courseid));
|
||||
$graph->y_data['bar1'][] = $c->{$param->graphline};
|
||||
}
|
||||
$graph->y_order = array('bar1');
|
||||
$graph->y_format['bar1'] = array('colour' => 'blue','bar' => 'fill','legend' => $param->{$param->graphline});
|
||||
|
||||
$graph->draw_stack();
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$ADMIN->add('reports', new admin_externalpage('reportcourseoverview', get_string('pluginname', 'report_courseoverview'), "$CFG->wwwroot/$CFG->admin/report/courseoverview/index.php",'report/courseoverview:view'));
|
||||
@@ -0,0 +1,27 @@
|
||||
<?PHP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.com //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$plugin->version = 2010090501;
|
||||
$plugin->requires = 2010090501;
|
||||
@@ -0,0 +1,51 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Defines the capabilities used by the Language customization admin report
|
||||
*
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$capabilities = array(
|
||||
|
||||
/* allows the user to view the current language customization */
|
||||
'report/customlang:view' => array(
|
||||
'riskbitmask' => RISK_CONFIG,
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'archetypes' => array(
|
||||
'manager' => CAP_ALLOW
|
||||
),
|
||||
),
|
||||
|
||||
/* allows the user to edit the current language customization */
|
||||
'report/customlang:edit' => array(
|
||||
'riskbitmask' => RISK_CONFIG | RISK_XSS,
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'archetypes' => array(
|
||||
'manager' => CAP_ALLOW
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<XMLDB PATH="admin/report/customlang/db" VERSION="20110419" COMMENT="XMLDB file for Moodle admin/report/customlang"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
|
||||
>
|
||||
<TABLES>
|
||||
<TABLE NAME="report_customlang" COMMENT="Contains the working checkout of all strings and their customization" NEXT="report_customlang_components">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="lang"/>
|
||||
<FIELD NAME="lang" TYPE="char" LENGTH="20" NOTNULL="true" SEQUENCE="false" COMMENT="The code of the language this string belongs to. Like en, cs or es" PREVIOUS="id" NEXT="componentid"/>
|
||||
<FIELD NAME="componentid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The id of the component" PREVIOUS="lang" NEXT="stringid"/>
|
||||
<FIELD NAME="stringid" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The identifier of the string" PREVIOUS="componentid" NEXT="original"/>
|
||||
<FIELD NAME="original" TYPE="text" LENGTH="big" NOTNULL="true" SEQUENCE="false" COMMENT="English original of the string" PREVIOUS="stringid" NEXT="master"/>
|
||||
<FIELD NAME="master" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="Master translation of the string as is distributed in the official lang pack, null if not translated" PREVIOUS="original" NEXT="local"/>
|
||||
<FIELD NAME="local" TYPE="text" LENGTH="big" NOTNULL="false" SEQUENCE="false" COMMENT="Local customization of the string, null if not customized" PREVIOUS="master" NEXT="timemodified"/>
|
||||
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" COMMENT="The timestamp of when the original or master was recently modified" PREVIOUS="local" NEXT="timecustomized"/>
|
||||
<FIELD NAME="timecustomized" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" COMMENT="The timestamp of when the value of the local translation was recently modified, null if not customized yet" PREVIOUS="timemodified" NEXT="outdated"/>
|
||||
<FIELD NAME="outdated" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Either the English original or the master translation changed and the customization may be outdated" PREVIOUS="timecustomized" NEXT="modified"/>
|
||||
<FIELD NAME="modified" TYPE="int" LENGTH="3" NOTNULL="false" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Has the string been modified via the translator?" PREVIOUS="outdated"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="fk_component"/>
|
||||
<KEY NAME="fk_component" TYPE="foreign" FIELDS="componentid" REFTABLE="report_customlang_components" REFFIELDS="id" PREVIOUS="primary"/>
|
||||
</KEYS>
|
||||
<INDEXES>
|
||||
<INDEX NAME="uq_lang_component_string" UNIQUE="true" FIELDS="lang, componentid, stringid" COMMENT="For a given language and component, string identifiers must be unique"/>
|
||||
</INDEXES>
|
||||
</TABLE>
|
||||
<TABLE NAME="report_customlang_components" COMMENT="Contains the list of all installed plugins that provide their own language pack" PREVIOUS="report_customlang">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="name"/>
|
||||
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="The normalized name of the plugin" PREVIOUS="id" NEXT="version"/>
|
||||
<FIELD NAME="version" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="The checked out version of the plugin, null if the version is unknown" PREVIOUS="name"/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?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 customization report upgrades
|
||||
*
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david.mudrak@gmail.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
function xmldb_report_customlang_upgrade($oldversion) {
|
||||
global $CFG, $DB, $OUTPUT;
|
||||
|
||||
$dbman = $DB->get_manager();
|
||||
$result = true;
|
||||
|
||||
/**
|
||||
* Use proper plugin prefix for tables
|
||||
*/
|
||||
if ($oldversion < 2010111200) {
|
||||
if ($dbman->table_exists('customlang')) {
|
||||
$dbman->rename_table(new xmldb_table('customlang'), 'report_customlang');
|
||||
}
|
||||
if ($dbman->table_exists('customlang_components')) {
|
||||
$dbman->rename_table(new xmldb_table('customlang_components'), 'report_customlang_components');
|
||||
}
|
||||
upgrade_plugin_savepoint(true, 2010111200, 'report', 'customlang');
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate the foreign key after the tables rename
|
||||
*/
|
||||
if ($oldversion < 2010111500) {
|
||||
$table = new xmldb_table('report_customlang');
|
||||
$oldkey = new xmldb_key('fk_component', XMLDB_KEY_FOREIGN, array('componentid'), 'customlang_components', array('id'));
|
||||
$newkey = new xmldb_key('fk_component', XMLDB_KEY_FOREIGN, array('componentid'), 'report_customlang_components', array('id'));
|
||||
|
||||
$dbman->drop_key($table, $oldkey);
|
||||
$dbman->add_key($table, $newkey);
|
||||
|
||||
upgrade_plugin_savepoint(true, 2010111500, 'report', 'customlang');
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the version field from integer to varchar
|
||||
*/
|
||||
if ($oldversion < 2011041900) {
|
||||
$table = new xmldb_table('report_customlang_components');
|
||||
$field = new xmldb_field('version', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'name');
|
||||
|
||||
$dbman->change_field_type($table, $field);
|
||||
|
||||
upgrade_plugin_savepoint(true, 2011041900, 'report', 'customlang');
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
require(dirname(dirname(dirname(dirname(__FILE__)))).'/config.php');
|
||||
require_once($CFG->dirroot.'/'.$CFG->admin.'/report/customlang/locallib.php');
|
||||
require_once($CFG->dirroot.'/'.$CFG->admin.'/report/customlang/filter_form.php');
|
||||
|
||||
require_login(SITEID, false);
|
||||
require_capability('report/customlang:edit', get_system_context());
|
||||
|
||||
$lng = required_param('lng', PARAM_LANG);
|
||||
$currentpage = optional_param('p', 0, PARAM_INT);
|
||||
$translatorsubmitted = optional_param('translatorsubmitted', 0, PARAM_BOOL);
|
||||
|
||||
$PAGE->set_pagelayout('standard');
|
||||
$PAGE->set_url('/admin/report/customlang/edit.php', array('lng' => $lng));
|
||||
navigation_node::override_active_url(new moodle_url('/admin/report/customlang/index.php'));
|
||||
$PAGE->set_title(get_string('pluginname', 'report_customlang'));
|
||||
$PAGE->set_heading(get_string('pluginname', 'report_customlang'));
|
||||
$PAGE->requires->js_init_call('M.report_customlang.init_editor', array(), true);
|
||||
|
||||
if (empty($lng)) {
|
||||
// PARAM_LANG validation failed
|
||||
print_error('missingparameter');
|
||||
}
|
||||
|
||||
// pre-output processing
|
||||
$filter = new report_customlang_filter_form($PAGE->url, null, 'post', '', array('class'=>'filterform'));
|
||||
$filterdata = report_customlang_utils::load_filter($USER);
|
||||
$filter->set_data($filterdata);
|
||||
|
||||
if ($filter->is_cancelled()) {
|
||||
redirect($PAGE->url);
|
||||
|
||||
} elseif ($submitted = $filter->get_data()) {
|
||||
report_customlang_utils::save_filter($submitted, $USER);
|
||||
redirect(new moodle_url($PAGE->url, array('p'=>0)));
|
||||
}
|
||||
|
||||
if ($translatorsubmitted) {
|
||||
$strings = optional_param('cust', array(), PARAM_RAW);
|
||||
$updates = optional_param('updates', array(), PARAM_INT);
|
||||
$checkin = optional_param('savecheckin', false, PARAM_RAW);
|
||||
|
||||
if ($checkin === false) {
|
||||
$nexturl = $PAGE->url;
|
||||
} else {
|
||||
$nexturl = new moodle_url('/admin/report/customlang/index.php', array('action'=>'checkin', 'lng' => $lng, 'sesskey'=>sesskey()));
|
||||
}
|
||||
|
||||
if (!is_array($strings)) {
|
||||
$strings = array();
|
||||
}
|
||||
$current = $DB->get_records_list('report_customlang', 'id', array_keys($strings));
|
||||
$now = time();
|
||||
|
||||
foreach ($strings as $recordid => $customization) {
|
||||
$customization = trim($customization);
|
||||
|
||||
if (empty($customization) and !is_null($current[$recordid]->local)) {
|
||||
$current[$recordid]->local = null;
|
||||
$current[$recordid]->modified = 1;
|
||||
$current[$recordid]->outdated = 0;
|
||||
$current[$recordid]->timecustomized = null;
|
||||
$DB->update_record('report_customlang', $current[$recordid]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($customization)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($customization !== $current[$recordid]->local) {
|
||||
$current[$recordid]->local = $customization;
|
||||
$current[$recordid]->modified = 1;
|
||||
$current[$recordid]->outdated = 0;
|
||||
$current[$recordid]->timecustomized = $now;
|
||||
$DB->update_record('report_customlang', $current[$recordid]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_array($updates)) {
|
||||
$updates = array();
|
||||
}
|
||||
if (!empty($updates)) {
|
||||
list($sql, $params) = $DB->get_in_or_equal($updates);
|
||||
$DB->set_field_select('report_customlang', 'outdated', 0, "local IS NOT NULL AND id $sql", $params);
|
||||
}
|
||||
|
||||
redirect($nexturl);
|
||||
}
|
||||
|
||||
$translator = new report_customlang_translator($PAGE->url, $lng, $filterdata, $currentpage);
|
||||
|
||||
// output starts here
|
||||
$output = $PAGE->get_renderer('report_customlang');
|
||||
$paginator = $output->paging_bar($translator->numofrows, $currentpage, report_customlang_translator::PERPAGE, $PAGE->url, 'p');
|
||||
|
||||
echo $output->header();
|
||||
$filter->display();
|
||||
echo $paginator;
|
||||
echo $output->render($translator);
|
||||
echo $paginator;
|
||||
echo $output->footer();
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@@ -15,7 +16,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* @package tool
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
@@ -28,51 +29,51 @@ require_once($CFG->dirroot . '/lib/formslib.php');
|
||||
/**
|
||||
* Form for filtering the strings to customize
|
||||
*/
|
||||
class tool_customlang_filter_form extends moodleform {
|
||||
class report_customlang_filter_form extends moodleform {
|
||||
|
||||
function definition() {
|
||||
$mform = $this->_form;
|
||||
$current = $this->_customdata['current'];
|
||||
|
||||
$mform->addElement('header', 'filtersettings', get_string('filter', 'tool_customlang'));
|
||||
$mform->addElement('header', 'filtersettings', get_string('filter', 'report_customlang'));
|
||||
|
||||
// Component
|
||||
$options = array();
|
||||
foreach (tool_customlang_utils::list_components() as $component => $normalized) {
|
||||
foreach (report_customlang_utils::list_components() as $component => $normalized) {
|
||||
list($type, $plugin) = normalize_component($normalized);
|
||||
if ($type == 'core' and is_null($plugin)) {
|
||||
$plugin = 'moodle';
|
||||
}
|
||||
$options[$type][$normalized] = $component.'.php';
|
||||
}
|
||||
$mform->addElement('selectgroups', 'component', get_string('filtercomponent', 'tool_customlang'), $options,
|
||||
$mform->addElement('selectgroups', 'component', get_string('filtercomponent', 'report_customlang'), $options,
|
||||
array('multiple'=>'multiple', 'size'=>7));
|
||||
|
||||
// Customized only
|
||||
$mform->addElement('advcheckbox', 'customized', get_string('filtercustomized', 'tool_customlang'));
|
||||
$mform->addElement('advcheckbox', 'customized', get_string('filtercustomized', 'report_customlang'));
|
||||
$mform->setType('customized', PARAM_BOOL);
|
||||
$mform->setDefault('customized', 0);
|
||||
|
||||
// Only helps
|
||||
$mform->addElement('advcheckbox', 'helps', get_string('filteronlyhelps', 'tool_customlang'));
|
||||
$mform->addElement('advcheckbox', 'helps', get_string('filteronlyhelps', 'report_customlang'));
|
||||
$mform->setType('helps', PARAM_BOOL);
|
||||
$mform->setDefault('helps', 0);
|
||||
|
||||
// Modified only
|
||||
$mform->addElement('advcheckbox', 'modified', get_string('filtermodified', 'tool_customlang'));
|
||||
$mform->addElement('advcheckbox', 'modified', get_string('filtermodified', 'report_customlang'));
|
||||
$mform->setType('filtermodified', PARAM_BOOL);
|
||||
$mform->setDefault('filtermodified', 0);
|
||||
|
||||
// Substring
|
||||
$mform->addElement('text', 'substring', get_string('filtersubstring', 'tool_customlang'));
|
||||
$mform->addElement('text', 'substring', get_string('filtersubstring', 'report_customlang'));
|
||||
$mform->setType('substring', PARAM_RAW);
|
||||
|
||||
// String identifier
|
||||
$mform->addElement('text', 'stringid', get_string('filterstringid', 'tool_customlang'));
|
||||
$mform->addElement('text', 'stringid', get_string('filterstringid', 'report_customlang'));
|
||||
$mform->setType('stringid', PARAM_STRINGID);
|
||||
|
||||
// Show strings - submit button
|
||||
$mform->addElement('submit', 'submit', get_string('filtershowstrings', 'tool_customlang'));
|
||||
$mform->addElement('submit', 'submit', get_string('filtershowstrings', 'report_customlang'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
<?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 checkout of the strings into the translation table
|
||||
*
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true); // progress bar is used here
|
||||
|
||||
require(dirname(dirname(dirname(dirname(__FILE__)))).'/config.php');
|
||||
require_once($CFG->dirroot.'/'.$CFG->admin.'/report/customlang/locallib.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
require_login(SITEID, false);
|
||||
require_capability('report/customlang:view', get_system_context());
|
||||
|
||||
$action = optional_param('action', '', PARAM_ALPHA);
|
||||
$confirm = optional_param('confirm', false, PARAM_BOOL);
|
||||
$lng = optional_param('lng', '', PARAM_LANG);
|
||||
|
||||
admin_externalpage_setup('reportcustomlang');
|
||||
$langs = get_string_manager()->get_list_of_translations();
|
||||
|
||||
// pre-output actions
|
||||
if ($action === 'checkout') {
|
||||
require_sesskey();
|
||||
require_capability('report/customlang:edit', get_system_context());
|
||||
if (empty($lng)) {
|
||||
print_error('missingparameter');
|
||||
}
|
||||
|
||||
$PAGE->set_cacheable(false); // progress bar is used here
|
||||
$output = $PAGE->get_renderer('report_customlang');
|
||||
echo $output->header();
|
||||
echo $output->heading(get_string('pluginname', 'report_customlang'));
|
||||
$progressbar = new progress_bar();
|
||||
$progressbar->create(); // prints the HTML code of the progress bar
|
||||
|
||||
// we may need a bit of extra execution time and memory here
|
||||
@set_time_limit(HOURSECS);
|
||||
raise_memory_limit(MEMORY_EXTRA);
|
||||
report_customlang_utils::checkout($lng, $progressbar);
|
||||
|
||||
echo $output->continue_button(new moodle_url('/admin/report/customlang/edit.php', array('lng' => $lng)), 'get');
|
||||
echo $output->footer();
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'checkin') {
|
||||
require_sesskey();
|
||||
require_capability('report/customlang:edit', get_system_context());
|
||||
if (empty($lng)) {
|
||||
print_error('missingparameter');
|
||||
}
|
||||
|
||||
if (!$confirm) {
|
||||
$output = $PAGE->get_renderer('report_customlang');
|
||||
echo $output->header();
|
||||
echo $output->heading(get_string('pluginname', 'report_customlang'));
|
||||
echo $output->heading($langs[$lng], 3);
|
||||
$numofmodified = report_customlang_utils::get_count_of_modified($lng);
|
||||
if ($numofmodified != 0) {
|
||||
echo $output->heading(get_string('modifiednum', 'report_customlang', $numofmodified), 3);
|
||||
echo $output->confirm(get_string('confirmcheckin', 'report_customlang'),
|
||||
new moodle_url($PAGE->url, array('action'=>'checkin', 'lng'=>$lng, 'confirm'=>1)),
|
||||
new moodle_url($PAGE->url, array('lng'=>$lng)));
|
||||
} else {
|
||||
echo $output->heading(get_string('modifiedno', 'report_customlang', $numofmodified), 3);
|
||||
echo $output->continue_button(new moodle_url($PAGE->url, array('lng' => $lng)));
|
||||
}
|
||||
echo $output->footer();
|
||||
die();
|
||||
|
||||
} else {
|
||||
report_customlang_utils::checkin($lng);
|
||||
redirect($PAGE->url);
|
||||
}
|
||||
}
|
||||
|
||||
$output = $PAGE->get_renderer('report_customlang');
|
||||
|
||||
// output starts here
|
||||
echo $output->header();
|
||||
echo $output->heading(get_string('pluginname', 'report_customlang'));
|
||||
|
||||
if (empty($lng)) {
|
||||
$s = new single_select($PAGE->url, 'lng', $langs);
|
||||
$s->label = get_accesshide(get_string('language'));
|
||||
$s->class = 'langselector';
|
||||
echo $output->box($OUTPUT->render($s), 'langselectorbox');
|
||||
echo $OUTPUT->footer();
|
||||
exit;
|
||||
}
|
||||
|
||||
echo $output->heading($langs[$lng], 3);
|
||||
|
||||
$numofmodified = report_customlang_utils::get_count_of_modified($lng);
|
||||
|
||||
if ($numofmodified != 0) {
|
||||
echo $output->heading(get_string('modifiednum', 'report_customlang', $numofmodified), 3);
|
||||
}
|
||||
|
||||
$menu = array();
|
||||
if (has_capability('report/customlang:edit', get_system_context())) {
|
||||
$menu['checkout'] = array(
|
||||
'title' => get_string('checkout', 'report_customlang'),
|
||||
'url' => new moodle_url($PAGE->url, array('action' => 'checkout', 'lng' => $lng)),
|
||||
'method' => 'post',
|
||||
);
|
||||
if ($numofmodified != 0) {
|
||||
$menu['checkin'] = array(
|
||||
'title' => get_string('checkin', 'report_customlang'),
|
||||
'url' => new moodle_url($PAGE->url, array('action' => 'checkin', 'lng' => $lng)),
|
||||
'method' => 'post',
|
||||
);
|
||||
}
|
||||
}
|
||||
echo $output->render(new report_customlang_menu($menu));
|
||||
|
||||
echo $output->footer();
|
||||
@@ -0,0 +1,61 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Strings for Language customization admin report
|
||||
*
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['checkin'] = 'Check in strings into disk';
|
||||
$string['checkout'] = 'Check out strings into the translator';
|
||||
$string['checkoutdone'] = 'Strings checked out successfully into the translator';
|
||||
$string['checkoutinprogress'] = 'Checking out strings into the translator';
|
||||
$string['confirmcheckin'] = 'You are about to check in modified strings into your local language pack. This will export the customized strings from the translator into the data directory and Moodle will start using the modified strings. Press \'Continue\' button to proceed check in.';
|
||||
$string['customlang:edit'] = 'Edit local translation';
|
||||
$string['customlang:view'] = 'View local translation';
|
||||
$string['filter'] = 'Filter strings';
|
||||
$string['filtercomponent'] = 'Show strings of these components';
|
||||
$string['filtercustomized'] = 'Customized only';
|
||||
$string['filtermodified'] = 'Modified only';
|
||||
$string['filteronlyhelps'] = 'Help only';
|
||||
$string['filtershowstrings'] = 'Show strings';
|
||||
$string['filterstringid'] = 'String identifier';
|
||||
$string['filtersubstring'] = 'Only strings containing';
|
||||
$string['headingcomponent'] = 'Component';
|
||||
$string['headinglocal'] = 'Local customization';
|
||||
$string['headingstandard'] = 'Standard text';
|
||||
$string['headingstringid'] = 'String';
|
||||
$string['markinguptodate'] = 'Marking the customization as up-to-date';
|
||||
$string['markinguptodate_help'] = 'The customized translation may get outdated if either the English original or the master translation has modified since the string was customized on your site. Review the customized 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 check in.';
|
||||
$string['modifiednum'] = 'There are {$a} modified strings. You must check in them into disk to store them permanently.';
|
||||
$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.
|
||||
|
||||
It is important to copy them exactly as they are in the original string. Do not translate them nor change their left-to-right orientation.';
|
||||
$string['placeholderwarning'] = 'string contains a placeholder';
|
||||
$string['pluginname'] = 'Language customization';
|
||||
$string['savecheckin'] = 'Save and check in strings into files';
|
||||
$string['savecontinue'] = 'Save and continue editing';
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
@@ -0,0 +1,535 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Definition of classes used by language customization admin report
|
||||
*
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Provides various utilities to be used by the plugin
|
||||
*
|
||||
* All the public methods here are static ones, this class can not be instantiated
|
||||
*/
|
||||
class report_customlang_utils {
|
||||
|
||||
/**
|
||||
* Rough number of strings that are being processed during a full checkout.
|
||||
* This is used to estimate the progress of the checkout.
|
||||
*/
|
||||
const ROUGH_NUMBER_OF_STRINGS = 16500;
|
||||
|
||||
/** @var array cache of {@link self::list_components()} results */
|
||||
protected static $components = null;
|
||||
|
||||
/**
|
||||
* This class can not be instantiated
|
||||
*/
|
||||
private function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all components installed on the server
|
||||
*
|
||||
* @return array (string)legacyname => (string)frankenstylename
|
||||
*/
|
||||
public static function list_components() {
|
||||
|
||||
$list['moodle'] = 'core';
|
||||
|
||||
$coresubsystems = get_core_subsystems();
|
||||
ksort($coresubsystems); // should be but just in case
|
||||
foreach ($coresubsystems as $name => $location) {
|
||||
if ($name != 'moodle.org') {
|
||||
$list[$name] = 'core_'.$name;
|
||||
}
|
||||
}
|
||||
|
||||
$plugintypes = get_plugin_types();
|
||||
foreach ($plugintypes as $type => $location) {
|
||||
$pluginlist = get_plugin_list($type);
|
||||
foreach ($pluginlist as $name => $ununsed) {
|
||||
if ($type == 'mod') {
|
||||
if (array_key_exists($name, $list)) {
|
||||
throw new Exception('Activity module and core subsystem name collision');
|
||||
}
|
||||
$list[$name] = $type.'_'.$name;
|
||||
} else {
|
||||
$list[$type.'_'.$name] = $type.'_'.$name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the translator database with the strings from files
|
||||
*
|
||||
* This should be executed each time before going to the translation page
|
||||
*
|
||||
* @param string $lang language code to checkout
|
||||
* @param progress_bar $progressbar optionally, the given progress bar can be updated
|
||||
*/
|
||||
public static function checkout($lang, progress_bar $progressbar = null) {
|
||||
global $DB;
|
||||
|
||||
// make sure that all components are registered
|
||||
$current = $DB->get_records('report_customlang_components', null, 'name', 'name,version,id');
|
||||
foreach (self::list_components() as $component) {
|
||||
if (empty($current[$component])) {
|
||||
$record = new stdclass();
|
||||
$record->name = $component;
|
||||
if (!$version = get_component_version($component)) {
|
||||
$record->version = null;
|
||||
} else {
|
||||
$record->version = $version;
|
||||
}
|
||||
$DB->insert_record('report_customlang_components', $record);
|
||||
} elseif ($version = get_component_version($component)) {
|
||||
if (is_null($current[$component]->version) or ($version > $current[$component]->version)) {
|
||||
$DB->set_field('report_customlang_components', 'version', $version, array('id' => $current[$component]->id));
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($current);
|
||||
|
||||
// initialize the progress counter - stores the number of processed strings
|
||||
$done = 0;
|
||||
$strinprogress = get_string('checkoutinprogress', 'report_customlang');
|
||||
|
||||
// reload components and fetch their strings
|
||||
$stringman = get_string_manager();
|
||||
$components = $DB->get_records('report_customlang_components');
|
||||
foreach ($components as $component) {
|
||||
$sql = "SELECT stringid, id, lang, componentid, original, master, local, timemodified, timecustomized, outdated, modified
|
||||
FROM {report_customlang} s
|
||||
WHERE lang = ? AND componentid = ?
|
||||
ORDER BY stringid";
|
||||
$current = $DB->get_records_sql($sql, array($lang, $component->id));
|
||||
$english = $stringman->load_component_strings($component->name, 'en', true, true);
|
||||
if ($lang == 'en') {
|
||||
$master =& $english;
|
||||
} else {
|
||||
$master = $stringman->load_component_strings($component->name, $lang, true, true);
|
||||
}
|
||||
$local = $stringman->load_component_strings($component->name, $lang, true, false);
|
||||
|
||||
foreach ($english as $stringid => $stringoriginal) {
|
||||
$stringmaster = isset($master[$stringid]) ? $master[$stringid] : null;
|
||||
$stringlocal = isset($local[$stringid]) ? $local[$stringid] : null;
|
||||
$now = time();
|
||||
|
||||
if (!is_null($progressbar)) {
|
||||
$done++;
|
||||
$donepercent = floor(min($done, self::ROUGH_NUMBER_OF_STRINGS) / self::ROUGH_NUMBER_OF_STRINGS * 100);
|
||||
$progressbar->update_full($donepercent, $strinprogress);
|
||||
}
|
||||
|
||||
if (isset($current[$stringid])) {
|
||||
$needsupdate = false;
|
||||
$currentoriginal = $current[$stringid]->original;
|
||||
$currentmaster = $current[$stringid]->master;
|
||||
$currentlocal = $current[$stringid]->local;
|
||||
|
||||
if ($currentoriginal !== $stringoriginal or $currentmaster !== $stringmaster) {
|
||||
$needsupdate = true;
|
||||
$current[$stringid]->original = $stringoriginal;
|
||||
$current[$stringid]->master = $stringmaster;
|
||||
$current[$stringid]->timemodified = $now;
|
||||
$current[$stringid]->outdated = 1;
|
||||
}
|
||||
|
||||
if ($stringmaster !== $stringlocal) {
|
||||
$needsupdate = true;
|
||||
$current[$stringid]->local = $stringlocal;
|
||||
$current[$stringid]->timecustomized = $now;
|
||||
}
|
||||
|
||||
if ($needsupdate) {
|
||||
$DB->update_record('report_customlang', $current[$stringid]);
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
$record = new stdclass();
|
||||
$record->lang = $lang;
|
||||
$record->componentid = $component->id;
|
||||
$record->stringid = $stringid;
|
||||
$record->original = $stringoriginal;
|
||||
$record->master = $stringmaster;
|
||||
$record->timemodified = $now;
|
||||
$record->outdated = 0;
|
||||
if ($stringmaster !== $stringlocal) {
|
||||
$record->local = $stringlocal;
|
||||
$record->timecustomized = $now;
|
||||
} else {
|
||||
$record->local = null;
|
||||
$record->timecustomized = null;
|
||||
}
|
||||
|
||||
$DB->insert_record('report_customlang', $record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_null($progressbar)) {
|
||||
$progressbar->update_full(100, get_string('checkoutdone', 'report_customlang'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the translator database into disk files
|
||||
*
|
||||
* @param mixed $lang language code
|
||||
*/
|
||||
public static function checkin($lang) {
|
||||
global $DB, $USER, $CFG;
|
||||
require_once($CFG->libdir.'/filelib.php');
|
||||
|
||||
if ($lang !== clean_param($lang, PARAM_LANG)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get all customized strings from updated components
|
||||
$sql = "SELECT s.*, c.name AS component
|
||||
FROM {report_customlang} s
|
||||
JOIN {report_customlang_components} c ON s.componentid = c.id
|
||||
WHERE s.lang = ?
|
||||
AND (s.local IS NOT NULL OR s.modified = 1)
|
||||
ORDER BY componentid, stringid";
|
||||
$strings = $DB->get_records_sql($sql, array($lang));
|
||||
|
||||
$files = array();
|
||||
foreach ($strings as $string) {
|
||||
if (!is_null($string->local)) {
|
||||
$files[$string->component][$string->stringid] = $string->local;
|
||||
}
|
||||
}
|
||||
|
||||
fulldelete(self::get_localpack_location($lang));
|
||||
foreach ($files as $component => $strings) {
|
||||
self::dump_strings($lang, $component, $strings);
|
||||
}
|
||||
|
||||
$DB->set_field_select('report_customlang', 'modified', 0, 'lang = ?', array($lang));
|
||||
$sm = get_string_manager();
|
||||
$sm->reset_caches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns full path to the directory where local packs are dumped into
|
||||
*
|
||||
* @param string $lang language code
|
||||
* @return string full path
|
||||
*/
|
||||
protected static function get_localpack_location($lang) {
|
||||
global $CFG;
|
||||
|
||||
return $CFG->langlocalroot.'/'.$lang.'_local';
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes strings into a local language pack file
|
||||
*
|
||||
* @param string $component the name of the component
|
||||
* @param array $strings
|
||||
*/
|
||||
protected static function dump_strings($lang, $component, $strings) {
|
||||
global $CFG;
|
||||
|
||||
if ($lang !== clean_param($lang, PARAM_LANG)) {
|
||||
debugging('Unable to dump local strings for non-installed language pack .'.s($lang));
|
||||
return false;
|
||||
}
|
||||
if ($component !== clean_param($component, PARAM_SAFEDIR)) {
|
||||
throw new coding_exception('Incorrect component name');
|
||||
}
|
||||
if (!$filename = self::get_component_filename($component)) {
|
||||
debugging('Unable to find the filename for the component '.s($component));
|
||||
return false;
|
||||
}
|
||||
if ($filename !== clean_param($filename, PARAM_FILE)) {
|
||||
throw new coding_exception('Incorrect file name '.s($filename));
|
||||
}
|
||||
list($package, $subpackage) = normalize_component($component);
|
||||
$packageinfo = " * @package $package";
|
||||
if (!is_null($subpackage)) {
|
||||
$packageinfo .= "\n * @subpackage $subpackage";
|
||||
}
|
||||
$filepath = self::get_localpack_location($lang);
|
||||
$filepath = $filepath.'/'.$filename;
|
||||
if (!is_dir(dirname($filepath))) {
|
||||
check_dir_exists(dirname($filepath));
|
||||
}
|
||||
|
||||
if (!$f = fopen($filepath, 'w')) {
|
||||
debugging('Unable to write '.s($filepath));
|
||||
return false;
|
||||
}
|
||||
fwrite($f, <<<EOF
|
||||
<?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 $CFG->wwwroot
|
||||
*
|
||||
$packageinfo
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
EOF
|
||||
);
|
||||
|
||||
foreach ($strings as $stringid => $text) {
|
||||
if ($stringid !== clean_param($stringid, PARAM_STRINGID)) {
|
||||
debugging('Invalid string identifier '.s($stringid));
|
||||
continue;
|
||||
}
|
||||
fwrite($f, '$string[\'' . $stringid . '\'] = ');
|
||||
fwrite($f, var_export($text, true));
|
||||
fwrite($f, ";\n");
|
||||
}
|
||||
fclose($f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the file where the component's local strings should be exported into
|
||||
*
|
||||
* @param string $component normalized name of the component, eg 'core' or 'mod_workshop'
|
||||
* @return string|boolean filename eg 'moodle.php' or 'workshop.php', false if not found
|
||||
*/
|
||||
protected static function get_component_filename($component) {
|
||||
if (is_null(self::$components)) {
|
||||
self::$components = self::list_components();
|
||||
}
|
||||
$return = false;
|
||||
foreach (self::$components as $legacy => $normalized) {
|
||||
if ($component === $normalized) {
|
||||
$return = $legacy.'.php';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of modified strings checked out in the translator
|
||||
*
|
||||
* @param string $lang language code
|
||||
* @return int
|
||||
*/
|
||||
public static function get_count_of_modified($lang) {
|
||||
global $DB;
|
||||
|
||||
return $DB->count_records('report_customlang', array('lang'=>$lang, 'modified'=>1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves filter data into a persistant storage such as user session
|
||||
*
|
||||
* @see self::load_filter()
|
||||
* @param stdclass $data filter values
|
||||
* @param stdclass $persistant storage object
|
||||
*/
|
||||
public static function save_filter(stdclass $data, stdclass $persistant) {
|
||||
if (!isset($persistant->report_customlang_filter)) {
|
||||
$persistant->report_customlang_filter = array();
|
||||
}
|
||||
foreach ($data as $key => $value) {
|
||||
if ($key !== 'submit') {
|
||||
$persistant->report_customlang_filter[$key] = serialize($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the previously saved filter settings from a persistent storage
|
||||
*
|
||||
* @see self::save_filter()
|
||||
* @param stdclass $persistant storage object
|
||||
* @return stdclass filter data
|
||||
*/
|
||||
public static function load_filter(stdclass $persistant) {
|
||||
$data = new stdclass();
|
||||
if (isset($persistant->report_customlang_filter)) {
|
||||
foreach ($persistant->report_customlang_filter as $key => $value) {
|
||||
$data->{$key} = unserialize($value);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the action menu of the report
|
||||
*/
|
||||
class report_customlang_menu implements renderable {
|
||||
|
||||
/** @var menu items */
|
||||
protected $items = array();
|
||||
|
||||
public function __construct(array $items = array()) {
|
||||
global $CFG;
|
||||
|
||||
foreach ($items as $itemkey => $item) {
|
||||
$this->add_item($itemkey, $item['title'], $item['url'], empty($item['method']) ? 'post' : $item['method']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the menu items
|
||||
*
|
||||
* @return array (string)key => (object)[->(string)title ->(moodle_url)url ->(string)method]
|
||||
*/
|
||||
public function get_items() {
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds item into the menu
|
||||
*
|
||||
* @param string $key item identifier
|
||||
* @param string $title localized action title
|
||||
* @param moodle_url $url action handler
|
||||
* @param string $method form method
|
||||
*/
|
||||
public function add_item($key, $title, moodle_url $url, $method) {
|
||||
if (isset($this->items[$key])) {
|
||||
throw new coding_exception('Menu item already exists');
|
||||
}
|
||||
if (empty($title) or empty($key)) {
|
||||
throw new coding_exception('Empty title or item key not allowed');
|
||||
}
|
||||
$item = new stdclass();
|
||||
$item->title = $title;
|
||||
$item->url = $url;
|
||||
$item->method = $method;
|
||||
$this->items[$key] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the translation tool
|
||||
*/
|
||||
class report_customlang_translator implements renderable {
|
||||
|
||||
/** @const int number of rows per page */
|
||||
const PERPAGE = 100;
|
||||
|
||||
/** @var int total number of the rows int the table */
|
||||
public $numofrows = 0;
|
||||
|
||||
/** @var moodle_url */
|
||||
public $handler;
|
||||
|
||||
/** @var string language code */
|
||||
public $lang;
|
||||
|
||||
/** @var int page to display, starting with page 0 */
|
||||
public $currentpage = 0;
|
||||
|
||||
/** @var array of stdclass strings to display */
|
||||
public $strings = array();
|
||||
|
||||
/** @var stdclass */
|
||||
protected $filter;
|
||||
|
||||
public function __construct(moodle_url $handler, $lang, $filter, $currentpage = 0) {
|
||||
global $DB;
|
||||
|
||||
$this->handler = $handler;
|
||||
$this->lang = $lang;
|
||||
$this->filter = $filter;
|
||||
$this->currentpage = $currentpage;
|
||||
|
||||
if (empty($filter) or empty($filter->component)) {
|
||||
// nothing to do
|
||||
$this->currentpage = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
list($insql, $inparams) = $DB->get_in_or_equal($filter->component, SQL_PARAMS_NAMED);
|
||||
|
||||
$csql = "SELECT COUNT(*)";
|
||||
$fsql = "SELECT s.id, s.*, c.name AS component";
|
||||
$sql = " FROM {report_customlang_components} c
|
||||
JOIN {report_customlang} s ON s.componentid = c.id
|
||||
WHERE s.lang = :lang
|
||||
AND c.name $insql";
|
||||
|
||||
$params = array_merge(array('lang' => $lang), $inparams);
|
||||
|
||||
if (!empty($filter->customized)) {
|
||||
$sql .= " AND s.local IS NOT NULL";
|
||||
}
|
||||
|
||||
if (!empty($filter->modified)) {
|
||||
$sql .= " AND s.modified = 1";
|
||||
}
|
||||
|
||||
if (!empty($filter->stringid)) {
|
||||
$sql .= " AND s.stringid = :stringid";
|
||||
$params['stringid'] = $filter->stringid;
|
||||
}
|
||||
|
||||
if (!empty($filter->substring)) {
|
||||
$sql .= " AND (".$DB->sql_like('s.original', ':substringoriginal', false)." OR
|
||||
".$DB->sql_like('s.master', ':substringmaster', false)." OR
|
||||
".$DB->sql_like('s.local', ':substringlocal', false).")";
|
||||
$params['substringoriginal'] = '%'.$filter->substring.'%';
|
||||
$params['substringmaster'] = '%'.$filter->substring.'%';
|
||||
$params['substringlocal'] = '%'.$filter->substring.'%';
|
||||
}
|
||||
|
||||
if (!empty($filter->helps)) {
|
||||
$sql .= " AND ".$DB->sql_like('s.stringid', ':help', false); //ILIKE
|
||||
$params['help'] = '%\_help';
|
||||
} else {
|
||||
$sql .= " AND ".$DB->sql_like('s.stringid', ':link', false, true, true); //NOT ILIKE
|
||||
$params['link'] = '%\_link';
|
||||
}
|
||||
|
||||
$osql = " ORDER BY c.name, s.stringid";
|
||||
|
||||
$this->numofrows = $DB->count_records_sql($csql.$sql, $params);
|
||||
$this->strings = $DB->get_records_sql($fsql.$sql.$osql, $params, ($this->currentpage) * self::PERPAGE, self::PERPAGE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// 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/>.
|
||||
|
||||
/**
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
M.report_customlang = M.report_customlang || {};
|
||||
|
||||
/**
|
||||
* YUI instance holder
|
||||
*/
|
||||
M.report_customlang.Y = {};
|
||||
|
||||
/**
|
||||
* Initialize JS support for the edit.php
|
||||
*
|
||||
* @param {Object} Y YUI instance
|
||||
*/
|
||||
M.report_customlang.init_editor = function(Y) {
|
||||
M.report_customlang.Y = Y;
|
||||
|
||||
Y.all('#translator .local textarea').each(function (textarea) {
|
||||
var cell = textarea.get('parentNode');
|
||||
textarea.setStyle('height', cell.getComputedStyle('height'));
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Output rendering of Language customization admin report
|
||||
*
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Rendering methods for the report widgets
|
||||
*/
|
||||
class report_customlang_renderer extends plugin_renderer_base {
|
||||
|
||||
/**
|
||||
* Renders customlang report menu
|
||||
*
|
||||
* @return string HTML
|
||||
*/
|
||||
protected function render_report_customlang_menu(report_customlang_menu $menu) {
|
||||
$output = '';
|
||||
foreach ($menu->get_items() as $item) {
|
||||
$output .= $this->single_button($item->url, $item->title, $item->method);
|
||||
}
|
||||
return $this->box($output, 'menu');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders customlang translation table
|
||||
*
|
||||
* @param report_customlang_translator $translator
|
||||
* @return string HTML
|
||||
*/
|
||||
protected function render_report_customlang_translator(report_customlang_translator $translator) {
|
||||
$output = '';
|
||||
|
||||
if (empty($translator->strings)) {
|
||||
return $this->heading(get_string('nostringsfound', 'report_customlang'), 3);
|
||||
}
|
||||
|
||||
$table = new html_table();
|
||||
$table->id = 'translator';
|
||||
$table->head = array(
|
||||
get_string('headingcomponent', 'report_customlang'),
|
||||
get_string('headingstringid', 'report_customlang'),
|
||||
get_string('headingstandard', 'report_customlang'),
|
||||
get_string('headinglocal', 'report_customlang'),
|
||||
);
|
||||
|
||||
foreach ($translator->strings as $string) {
|
||||
$cells = array();
|
||||
// component name
|
||||
$cells[0] = new html_table_cell($string->component);
|
||||
$cells[0]->attributes['class'] = 'component';
|
||||
// string identification code
|
||||
$cells[1] = new html_table_cell(html_writer::tag('div', s($string->stringid), array('class' => 'stringid')));
|
||||
$cells[1]->attributes['class'] = 'stringid';
|
||||
// master translation of the string
|
||||
$master = html_writer::tag('div', s($string->master), array('class' => 'preformatted'));
|
||||
$minheight = strlen($string->master) / 200;
|
||||
if (preg_match('/\{\$a(->.+)?\}/', $string->master)) {
|
||||
$master .= html_writer::tag('div', $this->help_icon('placeholder', 'report_customlang',
|
||||
get_string('placeholderwarning', 'report_customlang')), array('class' => 'placeholderinfo'));
|
||||
}
|
||||
$cells[2] = new html_table_cell($master);
|
||||
$cells[2]->attributes['class'] = 'standard master';
|
||||
// local customization of the string
|
||||
$textareaattributes = array('name'=>'cust['.$string->id.']', 'cols'=>40, 'rows'=>3);
|
||||
if ($minheight>1) {
|
||||
$textareaattributes['style'] = 'min-height:' . (int) 4*$minheight . 'em;';
|
||||
}
|
||||
$textarea = html_writer::tag('textarea', s($string->local), $textareaattributes);
|
||||
$cells[3] = new html_table_cell($textarea);
|
||||
if (!is_null($string->local) and $string->outdated) {
|
||||
$mark = html_writer::empty_tag('input', array('type' => 'checkbox', 'id' => 'update_' . $string->id,
|
||||
'name' => 'updates[]', 'value' => $string->id));
|
||||
$help = $this->help_icon('markinguptodate', 'report_customlang');
|
||||
$mark .= html_writer::tag('label', get_string('markuptodate', 'report_customlang') . $help,
|
||||
array('for' => 'update_' . $string->id));
|
||||
$mark = html_writer::tag('div', $mark, array('class' => 'uptodatewrapper'));
|
||||
} else {
|
||||
$mark = '';
|
||||
}
|
||||
$cells[3] = new html_table_cell($textarea."\n".$mark);
|
||||
$cells[3]->attributes['class'] = 'local';
|
||||
$cells[3]->id = 'id_'.$string->id;
|
||||
if (!is_null($string->local)) {
|
||||
$cells[3]->attributes['class'] .= ' customized';
|
||||
}
|
||||
if ($string->outdated) {
|
||||
$cells[3]->attributes['class'] .= ' outdated';
|
||||
}
|
||||
if ($string->modified) {
|
||||
$cells[3]->attributes['class'] .= ' modified';
|
||||
}
|
||||
|
||||
if ($string->original !== $string->master) {
|
||||
$cells[0]->rowspan = $cells[1]->rowspan = $cells[3]->rowspan = 2;
|
||||
}
|
||||
|
||||
$row = new html_table_row($cells);
|
||||
$table->data[] = $row;
|
||||
|
||||
if ($string->original !== $string->master) {
|
||||
$cells = array();
|
||||
// original of the string
|
||||
$cells[2] = new html_table_cell(html_writer::tag('div', s($string->original), array('class' => 'preformatted')));
|
||||
$cells[2]->attributes['class'] = 'standard original';
|
||||
$row = new html_table_row($cells);
|
||||
$table->data[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
$output .= html_writer::start_tag('form', array('method'=>'post', 'action'=>$translator->handler->out()));
|
||||
$output .= html_writer::start_tag('div');
|
||||
$output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'translatorsubmitted', 'value'=>1));
|
||||
$output .= html_writer::empty_tag('input', array('type'=>'hidden', 'name'=>'sesskey', 'value'=>sesskey()));
|
||||
$save1 = html_writer::empty_tag('input', array('type'=>'submit', 'name'=>'savecontinue', 'value'=>get_string('savecontinue', 'report_customlang')));
|
||||
$save2 = html_writer::empty_tag('input', array('type'=>'submit', 'name'=>'savecheckin', 'value'=>get_string('savecheckin', 'report_customlang')));
|
||||
$output .= html_writer::tag('fieldset', $save1.$save2, array('class'=>'buttonsbar'));
|
||||
$output .= html_writer::table($table);
|
||||
$output .= html_writer::tag('fieldset', $save1.$save2, array('class'=>'buttonsbar'));
|
||||
$output .= html_writer::end_tag('div');
|
||||
$output .= html_writer::end_tag('form');
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$ADMIN->add('language', new admin_externalpage('reportcustomlang', get_string('pluginname', 'report_customlang'), "$CFG->wwwroot/$CFG->admin/report/customlang/index.php", 'report/customlang:view'));
|
||||
@@ -0,0 +1,69 @@
|
||||
.path-admin-report-customlang .langselectorbox,
|
||||
.path-admin-report-customlang fieldset.buttonsbar,
|
||||
.path-admin-report-customlang .menu {
|
||||
margin: 5px auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.path-admin-report-customlang .menu .singlebutton,
|
||||
.path-admin-report-customlang .menu .singlebutton form,
|
||||
.path-admin-report-customlang .menu .singlebutton form div {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
|
||||
.path-admin-report-customlang .mform.filterform {
|
||||
width: 70%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.path-admin-report-customlang .mform.filterform .fitem .fitemtitle {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.path-admin-report-customlang .mform.filterform .fitem .felement {
|
||||
width: 60%;
|
||||
margin-left: 31%;
|
||||
}
|
||||
|
||||
.path-admin-report-customlang #translator {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.path-admin-report-customlang #translator .standard,
|
||||
.path-admin-report-customlang #translator .local {
|
||||
min-width: 35%;
|
||||
}
|
||||
|
||||
.path-admin-report-customlang #translator .customized {
|
||||
background-color: #e7f1c3;
|
||||
}
|
||||
|
||||
.path-admin-report-customlang #translator .customized.outdated {
|
||||
background-color: #f3f2aa;
|
||||
}
|
||||
|
||||
.path-admin-report-customlang #translator .modified {
|
||||
background-color: #ffd3d9;
|
||||
}
|
||||
|
||||
.path-admin-report-customlang #translator .customized.modified {
|
||||
background-color: #d2ebff;
|
||||
}
|
||||
|
||||
.path-admin-report-customlang #translator textarea {
|
||||
width: 100%;
|
||||
min-height: 4em;
|
||||
}
|
||||
|
||||
.path-admin-report-customlang #translator .placeholderinfo {
|
||||
text-align: center;
|
||||
border: 1px dotted #ddd;
|
||||
background-color: #f6f6f6;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
#page-admin-report-customlang-index .continuebutton {
|
||||
margin-top: 1em;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* @package report
|
||||
* @subpackage customlang
|
||||
* @copyright 2010 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2011041900;
|
||||
$plugin->requires = 2010120700;
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
// just a link to course report
|
||||
$ADMIN->add('reports', new admin_externalpage('reportlog', get_string('log', 'admin'), "$CFG->wwwroot/course/report/log/index.php?id=".SITEID, 'coursereport/log:view'));
|
||||
$ADMIN->add('reports', new admin_externalpage('reportloglive', get_string('loglive', 'coursereport_log'), "$CFG->wwwroot/course/report/log/indexlive.php?id=".SITEID, 'coursereport/log:viewlive'));
|
||||
@@ -0,0 +1,186 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* @package core
|
||||
* @subpackage profiling
|
||||
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
// TODO: Move all the DB stuff to profiling_db_xxxx() function in xhprof_moodle.php
|
||||
|
||||
require_once(dirname(__FILE__).'/../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir . '/xhprof/xhprof_moodle.php');
|
||||
|
||||
define('PROFILING_RUNSPERPAGE', 50);
|
||||
|
||||
// page parameters
|
||||
$script = optional_param('script', null, PARAM_PATH);
|
||||
$runid = optional_param('runid', null, PARAM_ALPHANUM);
|
||||
$runid2 = optional_param('runid2', null, PARAM_ALPHANUM);
|
||||
$listurl = optional_param('listurl', null, PARAM_PATH);
|
||||
$runreference= optional_param('runreference', 0, PARAM_INT);
|
||||
$runcomment = optional_param('runcomment', null, PARAM_TEXT);
|
||||
|
||||
$dbfields = 'runid, url, totalexecutiontime, totalcputime, ' .
|
||||
'totalcalls, totalmemory, runreference, runcomment, timecreated';
|
||||
|
||||
admin_externalpage_setup('reportprofiling');
|
||||
|
||||
// Always add listurl if available
|
||||
if ($listurl) {
|
||||
$listurlnav = new moodle_url('/admin/report/profiling/index.php', array('listurl' => $listurl));
|
||||
$PAGE->navbar->add($listurl, $listurlnav);
|
||||
}
|
||||
|
||||
// Header
|
||||
echo $OUTPUT->header();
|
||||
|
||||
// We have requested the last available run for one script
|
||||
if (isset($script)) {
|
||||
// Get the last available run for the given script
|
||||
$run = $DB->get_record_sql("SELECT $dbfields
|
||||
FROM {profiling}
|
||||
WHERE url = ?
|
||||
AND id = (SELECT MAX(id)
|
||||
FROM {profiling}
|
||||
WHERE url = ?)",
|
||||
array($script, $script), IGNORE_MISSING);
|
||||
|
||||
// No run found for script, warn and exit
|
||||
if (!$run) {
|
||||
notice(get_string('cannotfindanyrunforurl', 'report_profiling', $script), 'index.php');
|
||||
}
|
||||
|
||||
// Check if there is any previous run marked as reference one
|
||||
$prevreferences = $DB->get_records_select('profiling',
|
||||
'url = ? AND runreference = 1 AND timecreated < ?',
|
||||
array($run->url, $run->timecreated),
|
||||
'timecreated DESC', 'runid', 0, 1);
|
||||
$prevrunid = $prevreferences ? reset($prevreferences)->runid : false;
|
||||
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
|
||||
$header = get_string('lastrunof', 'report_profiling', $script);
|
||||
echo $OUTPUT->heading($header);
|
||||
$table = profiling_print_run($run, $prevrunid);
|
||||
echo $table;
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
|
||||
// We have requested the diff between 2 runs
|
||||
} else if (isset($runid) && isset($runid2)) {
|
||||
$run1 = $DB->get_record('profiling', array('runid'=>$runid), $dbfields, MUST_EXIST);
|
||||
$run2 = $DB->get_record('profiling', array('runid'=>$runid2), $dbfields, MUST_EXIST);
|
||||
if ($run1->url == $run2->url && $run1->runid != $run2->runid) {
|
||||
if ($run2->timecreated < $run1->timecreated) {
|
||||
$runtemp = $run1;
|
||||
$run1 = $run2;
|
||||
$run2 = $runtemp;
|
||||
}
|
||||
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
|
||||
$header = get_string('differencesbetween2runsof', 'report_profiling', $run1->url);
|
||||
echo $OUTPUT->heading($header);
|
||||
$table = profiling_print_rundiff($run1, $run2);
|
||||
echo $table;
|
||||
echo $OUTPUT->box_end();
|
||||
}
|
||||
|
||||
|
||||
// We have requested one run, invoke it
|
||||
} else if (isset($runid)) {
|
||||
// Check if we are trying to update the runreference/runcomment for the run
|
||||
if (isset($runcomment) && confirm_sesskey()) {
|
||||
$id = $DB->get_field('profiling', 'id', array('runid' => $runid), MUST_EXIST);
|
||||
$rec = new stdClass();
|
||||
$rec->id = $id;
|
||||
$rec->runreference = (bool)$runreference;
|
||||
$rec->runcomment = $runcomment;
|
||||
$DB->update_record('profiling', $rec);
|
||||
}
|
||||
// Get the requested runid
|
||||
$run = $DB->get_record('profiling', array('runid'=>$runid), $dbfields, IGNORE_MISSING);
|
||||
|
||||
// No run found for runid, warn and exit
|
||||
if (!$run) {
|
||||
notice(get_string('cannotfindanyrunforrunid', 'report_profiling', $runid), 'index.php');
|
||||
}
|
||||
|
||||
// Check if there is any previous run marked as reference one
|
||||
$prevreferences = $DB->get_records_select('profiling',
|
||||
'url = ? AND runreference = 1 AND timecreated < ?',
|
||||
array($run->url, $run->timecreated),
|
||||
'timecreated DESC', 'runid', 0, 1);
|
||||
$prevrunid = $prevreferences ? reset($prevreferences)->runid : false;
|
||||
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
|
||||
$header = get_string('summaryof', 'report_profiling', $run->url);
|
||||
echo $OUTPUT->heading($header);
|
||||
$table = profiling_print_run($run, $prevrunid);
|
||||
echo $table;
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
|
||||
// Default: List one page of runs
|
||||
} else {
|
||||
|
||||
// The flexitable that will root listings
|
||||
$table = new xhprof_table_sql('profiling-list-table');
|
||||
$baseurl = $CFG->wwwroot . '/admin/report/profiling/index.php';
|
||||
|
||||
// Check if we are listing all or some URL ones
|
||||
$sqlconditions = '';
|
||||
$sqlparams = array();
|
||||
if (!isset($listurl)) {
|
||||
$header = get_string('pluginname', 'report_profiling');
|
||||
$sqlconditions = '1 = 1';
|
||||
$table->set_listurlmode(false);
|
||||
} else {
|
||||
$header = get_string('profilingrunsfor', 'report_profiling', $listurl);
|
||||
$sqlconditions = 'url = :url';
|
||||
$sqlparams['url'] = $listurl;
|
||||
$table->set_listurlmode(true);
|
||||
$baseurl .= '?listurl=' . urlencode($listurl);
|
||||
}
|
||||
|
||||
echo $OUTPUT->heading($header);
|
||||
|
||||
// TODO: Fix flexitable to validate tsort/thide/tshow/tifirs/tilast/page
|
||||
// TODO: Fix table_sql to allow it to work without WHERE clause
|
||||
// add silly condition (1 = 1) because of table_sql bug
|
||||
$table->set_sql($dbfields, '{profiling}', $sqlconditions, $sqlparams);
|
||||
$table->set_count_sql("SELECT COUNT(*) FROM {profiling} WHERE $sqlconditions", $sqlparams);
|
||||
$columns = array(
|
||||
'url', 'timecreated', 'totalexecutiontime', 'totalcputime',
|
||||
'totalcalls', 'totalmemory', 'runcomment');
|
||||
$headers = array(
|
||||
get_string('url'), get_string('date'), get_string('executiontime', 'report_profiling'),
|
||||
get_string('cputime', 'report_profiling'), get_string('calls', 'report_profiling'),
|
||||
get_string('memory', 'report_profiling'), get_string('comment', 'report_profiling'));
|
||||
$table->define_columns($columns);
|
||||
$table->define_headers($headers);
|
||||
$table->sortable(true, 'timecreated', SORT_DESC);
|
||||
$table->define_baseurl($baseurl);
|
||||
$table->column_suppress('url');
|
||||
$table->out(PROFILING_RUNSPERPAGE, true);
|
||||
|
||||
// Print the controller block with different options
|
||||
echo profiling_list_controls($listurl);
|
||||
}
|
||||
|
||||
// Footer.
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Strings for component 'report_profiling', language 'en', branch 'MOODLE_20_STABLE'
|
||||
*
|
||||
* @package report_profiling
|
||||
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['calls'] = 'Function calls';
|
||||
$string['cannotfindanyrunforurl'] = 'Sorry, cannot find any profiling run for the \'{$a}\' URL';
|
||||
$string['cannotfindanyrunforrunid'] = 'Sorry, cannot find the \'{$a}\' profiling run';
|
||||
$string['comment'] = 'Comment';
|
||||
$string['differencesbetween2runsof'] = 'Differences between 2 runs of {$a}';
|
||||
$string['executiontime'] = 'Execution time';
|
||||
$string['cputime'] = 'CPU time';
|
||||
$string['lastrunof'] = 'Summary of last run of {$a}';
|
||||
$string['markreferencerun'] = 'Mark as reference run/comment';
|
||||
$string['memory'] = 'Memory used';
|
||||
$string['pluginname'] = 'Profiling runs';
|
||||
$string['profilingfocusscript'] = 'Focus on profiling runs for the script: {$a}';
|
||||
$string['profilingruns'] = 'Profiling runs';
|
||||
$string['profilingrunsfor'] = 'Profiling runs for {$a}';
|
||||
$string['referencerun'] = 'Reference run/comment';
|
||||
$string['runid'] = 'Run ID';
|
||||
$string['summaryof'] = 'Summary of {$a}';
|
||||
$string['viewdetails'] = 'View profiling details';
|
||||
$string['viewdiff'] = 'View profiling differences with last reference run';
|
||||
$string['viewdiffdetails'] = 'View profiling diff details';
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
// profiling report, added to development
|
||||
if (extension_loaded('xhprof') && function_exists('xhprof_enable') && (!empty($CFG->profilingenabled) || !empty($CFG->earlyprofilingenabled))) {
|
||||
$ADMIN->add('development', new admin_externalpage('reportprofiling', get_string('pluginname', 'report_profiling'), "$CFG->wwwroot/$CFG->admin/report/profiling/index.php", 'moodle/site:config'));
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/* report_profiling styles */
|
||||
|
||||
.path-admin-report-profiling .profilingruntable .label {
|
||||
font-weight: bold;
|
||||
}
|
||||
.path-admin-report-profiling .profiling_worse {
|
||||
color: red;
|
||||
}
|
||||
.path-admin-report-profiling .profiling_better {
|
||||
color: green;
|
||||
}
|
||||
.path-admin-report-profiling .profiling_same {
|
||||
color: dimgrey;
|
||||
}
|
||||
.path-admin-report-profiling .profiling_important,
|
||||
.path-admin-report-profiling .flexible .referencerun {
|
||||
font-weight: bold;
|
||||
}
|
||||
.path-admin-report-profiling .flexible .r1 .cell {
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
.path-admin-report-profiling .flexible {
|
||||
margin-left:auto;
|
||||
margin-right:auto
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.com //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$capabilities = array(
|
||||
|
||||
'report/questioninstances:view' => array(
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'archetypes' => array(
|
||||
'manager' => CAP_ALLOW
|
||||
),
|
||||
|
||||
'clonepermissionsfrom' => 'moodle/site:config',
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/**
|
||||
* For a given question type, list the number of
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package roles
|
||||
*/
|
||||
|
||||
/** */
|
||||
require_once(dirname(__FILE__).'/../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/questionlib.php');
|
||||
|
||||
// Get URL parameters.
|
||||
$requestedqtype = optional_param('qtype', '', PARAM_SAFEDIR);
|
||||
|
||||
// Print the header & check permissions.
|
||||
admin_externalpage_setup('reportquestioninstances');
|
||||
echo $OUTPUT->header();
|
||||
|
||||
// Log.
|
||||
add_to_log(SITEID, "admin", "report questioninstances", "report/questioninstances/index.php?qtype=$requestedqtype", $requestedqtype);
|
||||
|
||||
// Prepare the list of capabilities to choose from
|
||||
$qtypes = question_bank::get_all_qtypes();
|
||||
$qtypechoices = array();
|
||||
foreach ($qtypes as $qtype) {
|
||||
$qtypechoices[$qtype->name()] = $qtype->local_name();
|
||||
}
|
||||
|
||||
// Print the settings form.
|
||||
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter centerpara');
|
||||
echo '<form method="get" action="." id="settingsform"><div>';
|
||||
echo $OUTPUT->heading(get_string('reportsettings', 'report_questioninstances'));
|
||||
echo '<p id="intro">', get_string('intro', 'report_questioninstances') , '</p>';
|
||||
echo '<p><label for="menuqtype"> ' . get_string('questiontype', 'admin') . '</label> ';
|
||||
echo html_writer::select($qtypechoices, 'qtype', $requestedqtype, array('_all_'=>get_string('all')));
|
||||
echo '</p>';
|
||||
echo '<p><input type="submit" id="settingssubmit" value="' .
|
||||
get_string('getreport', 'report_questioninstances') . '" /></p>';
|
||||
echo '</div></form>';
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
// If we have a qtype to report on, generate the report.
|
||||
if ($requestedqtype) {
|
||||
|
||||
// Work out the bits needed for the SQL WHERE clauses.
|
||||
if ($requestedqtype == 'missingtype') {
|
||||
$othertypes = array_keys($qtypes);
|
||||
$key = array_search('missingtype', $othertypes);
|
||||
unset($othertypes[$key]);
|
||||
list($sqlqtypetest, $params) = $DB->get_in_or_equal($othertypes, SQL_PARAMS_QM, '', false);
|
||||
$sqlqtypetest = 'WHERE qtype ' . $sqlqtypetest;
|
||||
$title = get_string('reportformissingqtypes', 'report_questioninstances');
|
||||
} else if ($requestedqtype == '_all_') {
|
||||
$sqlqtypetest = '';
|
||||
$params = array();
|
||||
$title = get_string('reportforallqtypes', 'report_questioninstances');
|
||||
} else {
|
||||
$sqlqtypetest = 'WHERE qtype = ?';
|
||||
$params = array($requestedqtype);
|
||||
$title = get_string('reportforqtype', 'report_questioninstances',
|
||||
question_bank::get_qtype($requestedqtype)->local_name());
|
||||
}
|
||||
|
||||
// Get the question counts, and all the context information, for each
|
||||
// context. That is, rows of these results can be used as $context objects.
|
||||
$counts = $DB->get_records_sql("
|
||||
SELECT qc.contextid, count(1) as numquestions, sum(hidden) as numhidden, con.id, con.contextlevel, con.instanceid, con.path, con.depth
|
||||
FROM {question} q
|
||||
JOIN {question_categories} qc ON q.category = qc.id
|
||||
JOIN {context} con ON con.id = qc.contextid
|
||||
$sqlqtypetest
|
||||
GROUP BY contextid, con.id, con.contextlevel, con.instanceid, con.path, con.depth
|
||||
ORDER BY numquestions DESC, numhidden ASC, con.contextlevel ASC, con.id ASC", $params);
|
||||
|
||||
// Print the report heading.
|
||||
echo $OUTPUT->heading($title);
|
||||
|
||||
// Initialise the table.
|
||||
$table = new html_table();
|
||||
$table->head = array(
|
||||
get_string('context', 'role'),
|
||||
get_string('totalquestions', 'report_questioninstances'),
|
||||
get_string('visiblequestions', 'report_questioninstances'),
|
||||
get_string('hiddenquestions', 'report_questioninstances'));
|
||||
$table->data = array();
|
||||
$table->class = '';
|
||||
$table->id = '';
|
||||
|
||||
// Add the data for each row.
|
||||
$totalquestions = 0;
|
||||
$totalvisible = 0;
|
||||
$totalhidden = 0;
|
||||
foreach ($counts as $count) {
|
||||
// Work out a link for editing questions in this context.
|
||||
$contextname = print_context_name($count);
|
||||
$url = question_edit_url($count);
|
||||
if ($url) {
|
||||
$contextname = '<a href="' . $url . '" title="' .
|
||||
get_string('editquestionshere', 'report_questioninstances') .
|
||||
'">' . $contextname . '</a>';
|
||||
}
|
||||
|
||||
// Put the scores in the table.
|
||||
$numvisible = $count->numquestions - $count->numhidden;
|
||||
$table->data[] = array(
|
||||
$contextname,
|
||||
$count->numquestions,
|
||||
$numvisible,
|
||||
$count->numhidden);
|
||||
|
||||
// Update the totals.
|
||||
$totalquestions += $count->numquestions;
|
||||
$totalvisible += $numvisible;
|
||||
$totalhidden += $count->numhidden;
|
||||
}
|
||||
|
||||
// Add a totals row.
|
||||
$table->data[] = array(
|
||||
'<b>' . get_string('total') . '</b>',
|
||||
$totalquestions,
|
||||
$totalvisible,
|
||||
$totalhidden);
|
||||
|
||||
// Print it.
|
||||
echo html_writer::table($table);
|
||||
}
|
||||
|
||||
// Footer.
|
||||
echo $OUTPUT->footer();
|
||||
+5
-5
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@@ -15,12 +16,11 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* lang strings
|
||||
* Strings for component 'report_questioninstances', language 'en', branch 'MOODLE_20_STABLE'
|
||||
*
|
||||
* @package report
|
||||
* @subpackage questioninstances
|
||||
* @copyright 2008 Tim Hunt
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @package report_questioninstances
|
||||
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['editquestionshere'] = 'Edit questions in this context';
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$ADMIN->add('reports', new admin_externalpage('reportquestioninstances', get_string('pluginname', 'report_questioninstances'), "$CFG->wwwroot/$CFG->admin/report/questioninstances/index.php", 'report/questioninstances:view'));
|
||||
@@ -0,0 +1,27 @@
|
||||
<?PHP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.com //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$plugin->version = 2010090501;
|
||||
$plugin->requires = 2010090501;
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.com //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$capabilities = array(
|
||||
|
||||
'report/security:view' => array(
|
||||
'riskbitmask' => RISK_CONFIG,
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'archetypes' => array(
|
||||
'manager' => CAP_ALLOW
|
||||
),
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.org //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
require_once('../../../config.php');
|
||||
require_once($CFG->dirroot.'/'.$CFG->admin.'/report/security/lib.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
require_login();
|
||||
|
||||
$issue = optional_param('issue', '', PARAM_ALPHANUMEXT); // show detailed info about one issue only
|
||||
|
||||
$issues = report_security_get_issue_list();
|
||||
|
||||
// test if issue valid string
|
||||
if (array_search($issue, $issues, true) === false) {
|
||||
$issue = '';
|
||||
}
|
||||
|
||||
// we may need a bit more memory and this may take a long time to process
|
||||
raise_memory_limit(MEMORY_EXTRA);
|
||||
@set_time_limit(0);
|
||||
|
||||
// Print the header.
|
||||
admin_externalpage_setup('reportsecurity');
|
||||
echo $OUTPUT->header();
|
||||
|
||||
echo $OUTPUT->heading(get_string('pluginname', 'report_security'));
|
||||
|
||||
echo '<div id="timewarning">'.get_string('timewarning', 'report_security').'</div>';
|
||||
|
||||
$strok = '<span class="statusok">'.get_string('statusok', 'report_security').'</span>';
|
||||
$strinfo = '<span class="statusinfo">'.get_string('statusinfo', 'report_security').'</span>';
|
||||
$strwarning = '<span class="statuswarning">'.get_string('statuswarning', 'report_security').'</span>';
|
||||
$strserious = '<span class="statusserious">'.get_string('statusserious', 'report_security').'</span>';
|
||||
$strcritical = '<span class="statuscritical">'.get_string('statuscritical', 'report_security').'</span>';
|
||||
|
||||
$strissue = get_string('issue', 'report_security');
|
||||
$strstatus = get_string('status', 'report_security');
|
||||
$strdesc = get_string('description', 'report_security');
|
||||
$strconfig = get_string('configuration', 'report_security');
|
||||
|
||||
$statusarr = array(REPORT_SECURITY_OK => $strok,
|
||||
REPORT_SECURITY_INFO => $strinfo,
|
||||
REPORT_SECURITY_WARNING => $strwarning,
|
||||
REPORT_SECURITY_SERIOUS => $strserious,
|
||||
REPORT_SECURITY_CRITICAL => $strcritical);
|
||||
|
||||
$url = "$CFG->wwwroot/$CFG->admin/report/security/index.php";
|
||||
|
||||
if ($issue and ($result = $issue(true))) {
|
||||
report_security_hide_timearning();
|
||||
|
||||
$table = new html_table();
|
||||
$table->head = array($strissue, $strstatus, $strdesc, $strconfig);
|
||||
$table->size = array('30%', '10%', '50%', '10%' );
|
||||
$table->align = array('left', 'left', 'left', 'left');
|
||||
$table->attributes = array('class'=>'scurityreporttable generaltable');
|
||||
$table->data = array();
|
||||
|
||||
// print detail of one issue only
|
||||
$row = array();
|
||||
$row[0] = report_security_doc_link($issue, $result->name);
|
||||
$row[1] = $statusarr[$result->status];
|
||||
$row[2] = $result->info;
|
||||
$row[3] = is_null($result->link) ? ' ' : $result->link;
|
||||
|
||||
$PAGE->set_docs_path('admin/report/security/' . $issue);
|
||||
|
||||
$table->data[] = $row;
|
||||
|
||||
echo html_writer::table($table);
|
||||
|
||||
echo $OUTPUT->box($result->details, 'generalbox boxwidthnormal boxaligncenter'); // TODO: add proper css
|
||||
|
||||
echo $OUTPUT->continue_button($url);
|
||||
|
||||
} else {
|
||||
report_security_hide_timearning();
|
||||
|
||||
$table = new html_table();
|
||||
$table->head = array($strissue, $strstatus, $strdesc);
|
||||
$table->size = array('30%', '10%', '60%' );
|
||||
$table->align = array('left', 'left', 'left');
|
||||
$table->attributes = array('class'=>'scurityreporttable generaltable');
|
||||
$table->data = array();
|
||||
|
||||
foreach ($issues as $issue) {
|
||||
$result = $issue(false);
|
||||
if (!$result) {
|
||||
// ignore this test
|
||||
continue;
|
||||
}
|
||||
$row = array();
|
||||
$row[0] = "<a href='$url?issue=$result->issue'>$result->name</a>";
|
||||
$row[1] = $statusarr[$result->status];
|
||||
$row[2] = $result->info;
|
||||
|
||||
$table->data[] = $row;
|
||||
}
|
||||
echo html_writer::table($table);
|
||||
}
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
+5
-5
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@@ -15,12 +16,11 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Lang strings
|
||||
* Strings for component 'report_security', language 'en', branch 'MOODLE_20_STABLE'
|
||||
*
|
||||
* @package report
|
||||
* @subpackage security
|
||||
* @copyright 2008 petr Skoda
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @package report_security
|
||||
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['configuration'] = 'Configuration';
|
||||
@@ -0,0 +1,883 @@
|
||||
<?php
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.org //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require_once("$CFG->libdir/adminlib.php");
|
||||
|
||||
|
||||
define('REPORT_SECURITY_OK', 'ok');
|
||||
define('REPORT_SECURITY_INFO', 'info');
|
||||
define('REPORT_SECURITY_WARNING', 'warning');
|
||||
define('REPORT_SECURITY_SERIOUS', 'serious');
|
||||
define('REPORT_SECURITY_CRITICAL', 'critical');
|
||||
|
||||
function report_security_hide_timearning() {
|
||||
global $PAGE;
|
||||
$PAGE->requires->js_init_code("Y.one('#timewarning').addClass('timewarninghidden')");
|
||||
}
|
||||
|
||||
function report_security_get_issue_list() {
|
||||
return array(
|
||||
'report_security_check_globals',
|
||||
'report_security_check_unsecuredataroot',
|
||||
'report_security_check_displayerrors',
|
||||
'report_security_check_noauth',
|
||||
'report_security_check_embed',
|
||||
'report_security_check_mediafilterswf',
|
||||
'report_security_check_openprofiles',
|
||||
'report_security_check_google',
|
||||
'report_security_check_passwordpolicy',
|
||||
'report_security_check_passwordsaltmain',
|
||||
'report_security_check_emailchangeconfirmation',
|
||||
'report_security_check_cookiesecure',
|
||||
'report_security_check_configrw',
|
||||
'report_security_check_riskxss',
|
||||
'report_security_check_riskadmin',
|
||||
'report_security_check_riskbackup',
|
||||
'report_security_check_defaultuserrole',
|
||||
'report_security_check_guestrole',
|
||||
'report_security_check_frontpagerole',
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
function report_security_doc_link($issue, $name) {
|
||||
global $CFG, $OUTPUT;
|
||||
|
||||
if (empty($CFG->docroot)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return $OUTPUT->doc_link('report/security/'.$issue, $name);
|
||||
}
|
||||
|
||||
///=============================================
|
||||
/// Issue checks
|
||||
///=============================================
|
||||
|
||||
|
||||
/**
|
||||
* Verifies register globals PHP setting.
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_globals($detailed=false) {
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_globals';
|
||||
$result->name = get_string('check_globals_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = null;
|
||||
|
||||
if (ini_get_bool('register_globals')) {
|
||||
$result->status = REPORT_SECURITY_CRITICAL;
|
||||
$result->info = get_string('check_globals_error', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_globals_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_globals_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies unsupported noauth setting
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_noauth($detailed=false) {
|
||||
global $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_noauth';
|
||||
$result->name = get_string('check_noauth_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = null;
|
||||
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=manageauths\">".get_string('authsettings', 'admin').'</a>';
|
||||
|
||||
if (is_enabled_auth('none')) {
|
||||
$result->status = REPORT_SECURITY_CRITICAL;
|
||||
$result->info = get_string('check_noauth_error', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_noauth_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_noauth_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if password policy set
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_passwordpolicy($detailed=false) {
|
||||
global $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_passwordpolicy';
|
||||
$result->name = get_string('check_passwordpolicy_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
|
||||
|
||||
if (empty($CFG->passwordpolicy)) {
|
||||
$result->status = REPORT_SECURITY_WARNING;
|
||||
$result->info = get_string('check_passwordpolicy_error', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_passwordpolicy_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_passwordpolicy_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies sloppy embedding - this should have been removed long ago!!
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_embed($detailed=false) {
|
||||
global $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_embed';
|
||||
$result->name = get_string('check_embed_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
|
||||
|
||||
if (!empty($CFG->allowobjectembed)) {
|
||||
$result->status = REPORT_SECURITY_CRITICAL;
|
||||
$result->info = get_string('check_embed_error', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_embed_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_embed_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies sloppy swf embedding - this should have been removed long ago!!
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_mediafilterswf($detailed=false) {
|
||||
global $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_mediafilterswf';
|
||||
$result->name = get_string('check_mediafilterswf_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=filtersettingfiltermediaplugin\">".get_string('filtersettings', 'admin').'</a>';
|
||||
|
||||
$activefilters = filter_get_globally_enabled();
|
||||
|
||||
if (array_search('filter/mediaplugin', $activefilters) !== false and !empty($CFG->filter_mediaplugin_enable_swf)) {
|
||||
$result->status = REPORT_SECURITY_CRITICAL;
|
||||
$result->info = get_string('check_mediafilterswf_error', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_mediafilterswf_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_mediafilterswf_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies fatal misconfiguration of dataroot
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_unsecuredataroot($detailed=false) {
|
||||
global $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_unsecuredataroot';
|
||||
$result->name = get_string('check_unsecuredataroot_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = null;
|
||||
|
||||
$insecuredataroot = is_dataroot_insecure(true);
|
||||
|
||||
if ($insecuredataroot == INSECURE_DATAROOT_WARNING) {
|
||||
$result->status = REPORT_SECURITY_SERIOUS;
|
||||
$result->info = get_string('check_unsecuredataroot_warning', 'report_security', $CFG->dataroot);
|
||||
|
||||
} else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
|
||||
$result->status = REPORT_SECURITY_CRITICAL;
|
||||
$result->info = get_string('check_unsecuredataroot_error', 'report_security', $CFG->dataroot);
|
||||
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_unsecuredataroot_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_unsecuredataroot_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies displaying of errors - problem for lib files and 3rd party code
|
||||
* because we can not disable debugging in these scripts (they do not include config.php)
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_displayerrors($detailed=false) {
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_displayerrors';
|
||||
$result->name = get_string('check_displayerrors_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = null;
|
||||
|
||||
if (defined('WARN_DISPLAY_ERRORS_ENABLED')) {
|
||||
$result->status = REPORT_SECURITY_WARNING;
|
||||
$result->info = get_string('check_displayerrors_error', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_displayerrors_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_displayerrors_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies open profiles - originally open by default, not anymore because spammer abused it a lot
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_openprofiles($detailed=false) {
|
||||
global $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_openprofiles';
|
||||
$result->name = get_string('check_openprofiles_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
|
||||
|
||||
if (empty($CFG->forcelogin) and empty($CFG->forceloginforprofiles)) {
|
||||
$result->status = REPORT_SECURITY_WARNING;
|
||||
$result->info = get_string('check_openprofiles_error', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_openprofiles_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_openprofiles_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies google access not combined with disabled guest access
|
||||
* because attackers might gain guest access by modifying browser signature.
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_google($detailed=false) {
|
||||
global $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_google';
|
||||
$result->name = get_string('check_google_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
|
||||
|
||||
if (empty($CFG->opentogoogle)) {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_google_ok', 'report_security');
|
||||
} else if (!empty($CFG->guestloginbutton)) {
|
||||
$result->status = REPORT_SECURITY_INFO;
|
||||
$result->info = get_string('check_google_info', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_SERIOUS;
|
||||
$result->info = get_string('check_google_error', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_google_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies email confirmation - spammers were changing mails very often
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_emailchangeconfirmation($detailed=false) {
|
||||
global $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_emailchangeconfirmation';
|
||||
$result->name = get_string('check_emailchangeconfirmation_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
|
||||
|
||||
if (empty($CFG->emailchangeconfirmation)) {
|
||||
if (empty($CFG->allowemailaddresses)) {
|
||||
$result->status = REPORT_SECURITY_WARNING;
|
||||
$result->info = get_string('check_emailchangeconfirmation_error', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_INFO;
|
||||
$result->info = get_string('check_emailchangeconfirmation_info', 'report_security');
|
||||
}
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_emailchangeconfirmation_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_emailchangeconfirmation_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if https enabled only secure cookies allowed,
|
||||
* this prevents redirections and sending of cookies to unsecure port.
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_cookiesecure($detailed=false) {
|
||||
global $CFG;
|
||||
|
||||
if (strpos($CFG->wwwroot, 'https://') !== 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_cookiesecure';
|
||||
$result->name = get_string('check_cookiesecure_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=httpsecurity\">".get_string('httpsecurity', 'admin').'</a>';
|
||||
|
||||
if (empty($CFG->cookiesecure)) {
|
||||
$result->status = REPORT_SECURITY_SERIOUS;
|
||||
$result->info = get_string('check_cookiesecure_error', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_cookiesecure_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_cookiesecure_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies config.php is not writable anymore after installation,
|
||||
* config files were changed on several outdated server.
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_configrw($detailed=false) {
|
||||
global $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_configrw';
|
||||
$result->name = get_string('check_configrw_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = null;
|
||||
|
||||
if (is_writable($CFG->dirroot.'/config.php')) {
|
||||
$result->status = REPORT_SECURITY_WARNING;
|
||||
$result->info = get_string('check_configrw_warning', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_configrw_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_configrw_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function report_security_check_passwordsaltmain($detailed=false) {
|
||||
global $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_passwordsaltmain';
|
||||
$result->name = get_string('check_passwordsaltmain_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = null;
|
||||
|
||||
if (empty($CFG->passwordsaltmain)) {
|
||||
$result->status = REPORT_SECURITY_WARNING;
|
||||
$result->info = get_string('check_passwordsaltmain_warning', 'report_security');
|
||||
} else if ($CFG->passwordsaltmain === 'some long random string here with lots of characters'
|
||||
|| trim($CFG->passwordsaltmain) === '' || preg_match('/^([a-z0-9]{0,10})$/i', $CFG->passwordsaltmain)) {
|
||||
$result->status = REPORT_SECURITY_WARNING;
|
||||
$result->info = get_string('check_passwordsaltmain_weak', 'report_security');
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_passwordsaltmain_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_passwordsaltmain_details', 'report_security', get_docs_url('report/security/report_security_check_passwordsaltmain'));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all users with XSS risk, it would be great to combine this with risk trusts in user table,
|
||||
* unfortunately nobody implemented user trust UI yet :-(
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_riskxss($detailed=false) {
|
||||
global $DB;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_riskxss';
|
||||
$result->name = get_string('check_riskxss_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = REPORT_SECURITY_WARNING;
|
||||
$result->link = null;
|
||||
|
||||
$params = array('capallow'=>CAP_ALLOW);
|
||||
|
||||
$sqlfrom = "FROM (SELECT rcx.*
|
||||
FROM {role_capabilities} rcx
|
||||
JOIN {capabilities} cap ON (cap.name = rcx.capability AND ".$DB->sql_bitand('cap.riskbitmask', RISK_XSS)." <> 0)
|
||||
WHERE rcx.permission = :capallow) rc,
|
||||
{context} c,
|
||||
{context} sc,
|
||||
{role_assignments} ra,
|
||||
{user} u
|
||||
WHERE c.id = rc.contextid
|
||||
AND (sc.path = c.path OR sc.path LIKE ".$DB->sql_concat('c.path', "'/%'")." OR c.path LIKE ".$DB->sql_concat('sc.path', "'/%'").")
|
||||
AND u.id = ra.userid AND u.deleted = 0
|
||||
AND ra.contextid = sc.id AND ra.roleid = rc.roleid";
|
||||
|
||||
$count = $DB->count_records_sql("SELECT COUNT(DISTINCT u.id) $sqlfrom", $params);
|
||||
|
||||
$result->info = get_string('check_riskxss_warning', 'report_security', $count);
|
||||
|
||||
if ($detailed) {
|
||||
$users = $DB->get_records_sql("SELECT DISTINCT u.id, u.firstname, u.lastname, u.picture, u.imagealt $sqlfrom", $params);
|
||||
foreach ($users as $uid=>$user) {
|
||||
$users[$uid] = fullname($user);
|
||||
}
|
||||
$users = implode(', ', $users);
|
||||
$result->details = get_string('check_riskxss_details', 'report_security', $users);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies sanity of default user role.
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_defaultuserrole($detailed=false) {
|
||||
global $DB, $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_defaultuserrole';
|
||||
$result->name = get_string('check_defaultuserrole_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=userpolicies\">".get_string('userpolicies', 'admin').'</a>';;
|
||||
|
||||
if (!$default_role = $DB->get_record('role', array('id'=>$CFG->defaultuserroleid))) {
|
||||
$result->status = REPORT_SECURITY_WARNING;
|
||||
$result->info = get_string('check_defaultuserrole_notset', 'report_security');
|
||||
$result->details = $result->info;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// risky caps - usually very dangerous
|
||||
$params = array('capallow'=>CAP_ALLOW, 'roleid'=>$default_role->id);
|
||||
$sql = "SELECT COUNT(DISTINCT rc.contextid)
|
||||
FROM {role_capabilities} rc
|
||||
JOIN {capabilities} cap ON cap.name = rc.capability
|
||||
WHERE ".$DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
|
||||
AND rc.permission = :capallow
|
||||
AND rc.roleid = :roleid";
|
||||
|
||||
$riskycount = $DB->count_records_sql($sql, $params);
|
||||
|
||||
// it may have either none or 'user' archetype - nothing else, or else it would break during upgrades badly
|
||||
if ($default_role->archetype === '' or $default_role->archetype === 'user') {
|
||||
$legacyok = true;
|
||||
} else {
|
||||
$legacyok = false;
|
||||
}
|
||||
|
||||
if ($riskycount or !$legacyok) {
|
||||
$result->status = REPORT_SECURITY_CRITICAL;
|
||||
$result->info = get_string('check_defaultuserrole_error', 'report_security', format_string($default_role->name));
|
||||
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_defaultuserrole_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_defaultuserrole_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies sanity of guest role
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_guestrole($detailed=false) {
|
||||
global $DB, $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_guestrole';
|
||||
$result->name = get_string('check_guestrole_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=userpolicies\">".get_string('userpolicies', 'admin').'</a>';;
|
||||
|
||||
if (!$guest_role = $DB->get_record('role', array('id'=>$CFG->guestroleid))) {
|
||||
$result->status = REPORT_SECURITY_WARNING;
|
||||
$result->info = get_string('check_guestrole_notset', 'report_security');
|
||||
$result->details = $result->info;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// risky caps - usually very dangerous
|
||||
$params = array('capallow'=>CAP_ALLOW, 'roleid'=>$guest_role->id);
|
||||
$sql = "SELECT COUNT(DISTINCT rc.contextid)
|
||||
FROM {role_capabilities} rc
|
||||
JOIN {capabilities} cap ON cap.name = rc.capability
|
||||
WHERE ".$DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
|
||||
AND rc.permission = :capallow
|
||||
AND rc.roleid = :roleid";
|
||||
|
||||
$riskycount = $DB->count_records_sql($sql, $params);
|
||||
|
||||
// it may have either no or 'guest' archetype - nothing else, or else it would break during upgrades badly
|
||||
if ($guest_role->archetype === '' or $guest_role->archetype === 'guest') {
|
||||
$legacyok = true;
|
||||
} else {
|
||||
$legacyok = false;
|
||||
}
|
||||
|
||||
if ($riskycount or !$legacyok) {
|
||||
$result->status = REPORT_SECURITY_CRITICAL;
|
||||
$result->info = get_string('check_guestrole_error', 'report_security', format_string($guest_role->name));
|
||||
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_guestrole_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_guestrole_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies sanity of frontpage role
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_frontpagerole($detailed=false) {
|
||||
global $DB, $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_frontpagerole';
|
||||
$result->name = get_string('check_frontpagerole_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=frontpagesettings\">".get_string('frontpagesettings','admin').'</a>';;
|
||||
|
||||
if (!$frontpage_role = $DB->get_record('role', array('id'=>$CFG->defaultfrontpageroleid))) {
|
||||
$result->status = REPORT_SECURITY_INFO;
|
||||
$result->info = get_string('check_frontpagerole_notset', 'report_security');
|
||||
$result->details = get_string('check_frontpagerole_details', 'report_security');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// risky caps - usually very dangerous
|
||||
$params = array('capallow'=>CAP_ALLOW, 'roleid'=>$frontpage_role->id);
|
||||
$sql = "SELECT COUNT(DISTINCT rc.contextid)
|
||||
FROM {role_capabilities} rc
|
||||
JOIN {capabilities} cap ON cap.name = rc.capability
|
||||
WHERE ".$DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
|
||||
AND rc.permission = :capallow
|
||||
AND rc.roleid = :roleid";
|
||||
|
||||
$riskycount = $DB->count_records_sql($sql, $params);
|
||||
|
||||
// there is no legacy role type for frontpage yet - anyway we can not allow teachers or admins there!
|
||||
if ($frontpage_role->archetype === 'teacher' or $frontpage_role->archetype === 'editingteacher'
|
||||
or $frontpage_role->archetype === 'coursecreator' or $frontpage_role->archetype === 'manager') {
|
||||
$legacyok = false;
|
||||
} else {
|
||||
$legacyok = true;
|
||||
}
|
||||
|
||||
if ($riskycount or !$legacyok) {
|
||||
$result->status = REPORT_SECURITY_CRITICAL;
|
||||
$result->info = get_string('check_frontpagerole_error', 'report_security', format_string($frontpage_role->name));
|
||||
|
||||
} else {
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_frontpagerole_ok', 'report_security');
|
||||
}
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_frontpagerole_details', 'report_security');
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all admins.
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_riskadmin($detailed=false) {
|
||||
global $DB, $CFG;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_riskadmin';
|
||||
$result->name = get_string('check_riskadmin_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = null;
|
||||
|
||||
$sql = "SELECT u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email
|
||||
FROM {user} u
|
||||
WHERE u.id IN ($CFG->siteadmins)";
|
||||
|
||||
$admins = $DB->get_records_sql($sql);
|
||||
$admincount = count($admins);
|
||||
|
||||
if ($detailed) {
|
||||
foreach ($admins as $uid=>$user) {
|
||||
$url = "$CFG->wwwroot/user/view.php?id=$user->id";
|
||||
$admins[$uid] = '<li><a href="'.$url.'">'.fullname($user).' ('.$user->email.')</a></li>';
|
||||
}
|
||||
$admins = '<ul>'.implode($admins).'</ul>';
|
||||
}
|
||||
|
||||
$result->status = REPORT_SECURITY_OK;
|
||||
$result->info = get_string('check_riskadmin_ok', 'report_security', $admincount);
|
||||
|
||||
if ($detailed) {
|
||||
$result->details = get_string('check_riskadmin_detailsok', 'report_security', $admins);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all roles that have the ability to backup user data, as well as users
|
||||
* @param bool $detailed
|
||||
* @return object result
|
||||
*/
|
||||
function report_security_check_riskbackup($detailed=false) {
|
||||
global $CFG, $DB;
|
||||
|
||||
$result = new stdClass();
|
||||
$result->issue = 'report_security_check_riskbackup';
|
||||
$result->name = get_string('check_riskbackup_name', 'report_security');
|
||||
$result->info = null;
|
||||
$result->details = null;
|
||||
$result->status = null;
|
||||
$result->link = null;
|
||||
|
||||
$syscontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
|
||||
$params = array('capability'=>'moodle/backup:userinfo', 'permission'=>CAP_ALLOW, 'contextid'=>$syscontext->id);
|
||||
$sql = "SELECT DISTINCT r.id, r.name, r.shortname, r.sortorder, r.archetype
|
||||
FROM {role} r
|
||||
JOIN {role_capabilities} rc ON rc.roleid = r.id
|
||||
WHERE rc.capability = :capability
|
||||
AND rc.contextid = :contextid
|
||||
AND rc.permission = :permission";
|
||||
$systemroles = $DB->get_records_sql($sql, $params);
|
||||
|
||||
$params = array('capability'=>'moodle/backup:userinfo', 'permission'=>CAP_ALLOW, 'contextid'=>$syscontext->id);
|
||||
$sql = "SELECT DISTINCT r.id, r.name, r.shortname, r.sortorder, r.archetype, rc.contextid
|
||||
FROM {role} r
|
||||
JOIN {role_capabilities} rc ON rc.roleid = r.id
|
||||
WHERE rc.capability = :capability
|
||||
AND rc.contextid <> :contextid
|
||||
AND rc.permission = :permission";
|
||||
$overriddenroles = $DB->get_records_sql($sql, $params);
|
||||
|
||||
// list of users that are able to backup personal info
|
||||
// note: "sc" is context where is role assigned,
|
||||
// "c" is context where is role overridden or system context if in role definition
|
||||
$params = array('capability'=>'moodle/backup:userinfo', 'permission'=>CAP_ALLOW, 'context1'=>CONTEXT_COURSE, 'context2'=>CONTEXT_COURSE);
|
||||
|
||||
$sqluserinfo = "
|
||||
FROM (SELECT rcx.*
|
||||
FROM {role_capabilities} rcx
|
||||
WHERE rcx.permission = :permission AND rcx.capability = :capability) rc,
|
||||
{context} c,
|
||||
{context} sc,
|
||||
{role_assignments} ra,
|
||||
{user} u
|
||||
WHERE c.id = rc.contextid
|
||||
AND (sc.path = c.path OR sc.path LIKE ".$DB->sql_concat('c.path', "'/%'")." OR c.path LIKE ".$DB->sql_concat('sc.path', "'/%'").")
|
||||
AND u.id = ra.userid AND u.deleted = 0
|
||||
AND ra.contextid = sc.id AND ra.roleid = rc.roleid
|
||||
AND sc.contextlevel <= :context1 AND c.contextlevel <= :context2";
|
||||
|
||||
$usercount = $DB->count_records_sql("SELECT COUNT('x') FROM (SELECT DISTINCT u.id $sqluserinfo) userinfo", $params);
|
||||
$systemrolecount = empty($systemroles) ? 0 : count($systemroles);
|
||||
$overriddenrolecount = empty($overriddenroles) ? 0 : count($overriddenroles);
|
||||
|
||||
$result->status = REPORT_SECURITY_WARNING; // there is always at least one admin
|
||||
$a = (object)array('rolecount'=>$systemrolecount,'overridecount'=>$overriddenrolecount,'usercount'=>$usercount);
|
||||
$result->info = get_string('check_riskbackup_warning', 'report_security', $a);
|
||||
|
||||
if ($detailed) {
|
||||
|
||||
$result->details = ''; // Will be added to later
|
||||
|
||||
// Make a list of roles
|
||||
if ($systemroles) {
|
||||
$links = array();
|
||||
foreach ($systemroles as $role) {
|
||||
$role->url = "$CFG->wwwroot/$CFG->admin/roles/manage.php?action=edit&roleid=$role->id";
|
||||
$links[] = '<li>'.get_string('check_riskbackup_editrole', 'report_security', $role).'</li>';
|
||||
}
|
||||
$links = '<ul>'.implode($links).'</ul>';
|
||||
$result->details .= get_string('check_riskbackup_details_systemroles', 'report_security', $links);
|
||||
}
|
||||
|
||||
// Make a list of overrides to roles
|
||||
$rolelinks2 = array();
|
||||
if ($overriddenroles) {
|
||||
$links = array();
|
||||
foreach ($overriddenroles as $role) {
|
||||
$context = get_context_instance_by_id($role->contextid);
|
||||
if ($context->contextlevel == CONTEXT_COURSE) {
|
||||
$role->name = role_get_name($role, $context);
|
||||
}
|
||||
$role->contextname = print_context_name($context);
|
||||
$role->url = "$CFG->wwwroot/$CFG->admin/roles/override.php?contextid=$role->contextid&roleid=$role->id";
|
||||
$links[] = '<li>'.get_string('check_riskbackup_editoverride', 'report_security', $role).'</li>';
|
||||
}
|
||||
$links = '<ul>'.implode($links).'</ul>';
|
||||
$result->details .= get_string('check_riskbackup_details_overriddenroles', 'report_security', $links);
|
||||
}
|
||||
|
||||
// Get a list of affected users as well
|
||||
$users = array();
|
||||
|
||||
$rs = $DB->get_recordset_sql("SELECT DISTINCT u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email, ra.contextid, ra.roleid
|
||||
$sqluserinfo ORDER BY u.lastname, u.firstname", $params);
|
||||
|
||||
foreach ($rs as $user) {
|
||||
$context = get_context_instance_by_id($user->contextid);
|
||||
$url = "$CFG->wwwroot/$CFG->admin/roles/assign.php?contextid=$user->contextid&roleid=$user->roleid";
|
||||
$a = (object)array('fullname'=>fullname($user), 'url'=>$url, 'email'=>$user->email,
|
||||
'contextname'=>print_context_name($context));
|
||||
$users[] = '<li>'.get_string('check_riskbackup_unassign', 'report_security', $a).'</li>';
|
||||
}
|
||||
if (!empty($users)) {
|
||||
$users = '<ul>'.implode($users).'</ul>';
|
||||
$result->details .= get_string('check_riskbackup_details_users', 'report_security', $users);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$ADMIN->add('reports', new admin_externalpage('reportsecurity', get_string('pluginname', 'report_security'), "$CFG->wwwroot/$CFG->admin/report/security/index.php",'report/security:view'));
|
||||
@@ -0,0 +1,27 @@
|
||||
<?PHP
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.com //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$plugin->version = 2010090501;
|
||||
$plugin->requires = 2010090501;
|
||||
@@ -0,0 +1,286 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Spam Cleaner
|
||||
*
|
||||
* Helps an admin to clean up spam in Moodle
|
||||
*
|
||||
* @authors Dongsheng Cai, Martin Dougiamas, Amr Hourani
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
|
||||
// List of known spammy keywords, please add more here
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require_once('../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
|
||||
// Configuration
|
||||
|
||||
$autokeywords = array(
|
||||
"<img",
|
||||
"fuck",
|
||||
"casino",
|
||||
"porn",
|
||||
"xxx",
|
||||
"cialis",
|
||||
"viagra",
|
||||
"poker",
|
||||
"warcraft"
|
||||
);
|
||||
|
||||
$keyword = optional_param('keyword', '', PARAM_RAW);
|
||||
$autodetect = optional_param('autodetect', '', PARAM_RAW);
|
||||
$del = optional_param('del', '', PARAM_RAW);
|
||||
$delall = optional_param('delall', '', PARAM_RAW);
|
||||
$ignore = optional_param('ignore', '', PARAM_RAW);
|
||||
$reset = optional_param('reset', '', PARAM_RAW);
|
||||
$id = optional_param('id', '', PARAM_INT);
|
||||
|
||||
require_login();
|
||||
admin_externalpage_setup('reportspamcleaner');
|
||||
|
||||
// Delete one user
|
||||
if (!empty($del) && confirm_sesskey() && ($id != $USER->id)) {
|
||||
if (isset($SESSION->users_result[$id])) {
|
||||
$user = $SESSION->users_result[$id];
|
||||
if (delete_user($user)) {
|
||||
unset($SESSION->users_result[$id]);
|
||||
echo json_encode(true);
|
||||
} else {
|
||||
echo json_encode(false);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(false);
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
// Delete lots of users
|
||||
if (!empty($delall) && confirm_sesskey()) {
|
||||
if (!empty($SESSION->users_result)) {
|
||||
foreach ($SESSION->users_result as $userid => $user) {
|
||||
if ($userid != $USER->id) {
|
||||
if (delete_user($user)) {
|
||||
unset($SESSION->users_result[$userid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
echo json_encode(true);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!empty($ignore)) {
|
||||
unset($SESSION->users_result[$id]);
|
||||
echo json_encode(true);
|
||||
exit;
|
||||
}
|
||||
|
||||
$PAGE->requires->js_init_call('M.report_spamcleaner.init', array(me()), true);
|
||||
$strings = Array('spaminvalidresult','spamdeleteallconfirm','spamcannotdelete','spamdeleteconfirm');
|
||||
$PAGE->requires->strings_for_js($strings, 'report_spamcleaner');
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
// Print headers and things
|
||||
echo $OUTPUT->box(get_string('spamcleanerintro', 'report_spamcleaner'));
|
||||
|
||||
echo $OUTPUT->box_start(); // The forms section at the top
|
||||
|
||||
?>
|
||||
|
||||
<div class="mdl-align">
|
||||
|
||||
<form method="post" action="index.php">
|
||||
<div>
|
||||
<input type="text" name="keyword" id="keyword_el" value="<?php p($keyword) ?>" />
|
||||
<input type="hidden" name="sesskey" value="<?php echo sesskey();?>" />
|
||||
<input type="submit" value="<?php echo get_string('spamsearch', 'report_spamcleaner')?>" />
|
||||
</div>
|
||||
</form>
|
||||
<p><?php echo get_string('spameg', 'report_spamcleaner');?></p>
|
||||
|
||||
<hr />
|
||||
|
||||
<form method="post" action="index.php">
|
||||
<div>
|
||||
<input type="submit" name="autodetect" value="<?php echo get_string('spamauto', 'report_spamcleaner');?>" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
echo '<div id="result" class="mdl-align">';
|
||||
|
||||
// Print list of resulting profiles
|
||||
|
||||
if (!empty($keyword)) { // Use the keyword(s) supplied by the user
|
||||
$keywords = explode(',', $keyword);
|
||||
foreach ($keywords as $key => $keyword) {
|
||||
$keywords[$key] = trim($keyword);
|
||||
}
|
||||
search_spammers($keywords);
|
||||
|
||||
} else if (!empty($autodetect)) { // Use the inbuilt keyword list to detect users
|
||||
search_spammers($autokeywords);
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/// Functions
|
||||
|
||||
|
||||
function search_spammers($keywords) {
|
||||
|
||||
global $CFG, $USER, $DB, $OUTPUT;
|
||||
|
||||
if (!is_array($keywords)) {
|
||||
$keywords = array($keywords); // Make it into an array
|
||||
}
|
||||
|
||||
$params = array('userid'=>$USER->id);
|
||||
|
||||
$keywordfull = array();
|
||||
$i = 0;
|
||||
foreach ($keywords as $keyword) {
|
||||
$keywordfull[] = $DB->sql_like('description', ':descpat'.$i, false);
|
||||
$params['descpat'.$i] = "%$keyword%";
|
||||
$keywordfull2[] = $DB->sql_like('p.summary', ':sumpat'.$i, false);
|
||||
$params['sumpat'.$i] = "%$keyword%";
|
||||
$i++;
|
||||
}
|
||||
$conditions = '( '.implode(' OR ', $keywordfull).' )';
|
||||
$conditions2 = '( '.implode(' OR ', $keywordfull2).' )';
|
||||
|
||||
$sql = "SELECT * FROM {user} WHERE deleted = 0 AND id <> :userid AND $conditions"; // Exclude oneself
|
||||
$sql2 = "SELECT u.*, p.summary FROM {user} AS u, {post} AS p WHERE $conditions2 AND u.deleted = 0 AND u.id=p.userid AND u.id <> :userid";
|
||||
$spamusers_desc = $DB->get_recordset_sql($sql, $params);
|
||||
$spamusers_blog = $DB->get_recordset_sql($sql2, $params);
|
||||
|
||||
$keywordlist = implode(', ', $keywords);
|
||||
echo $OUTPUT->box(get_string('spamresult', 'report_spamcleaner').s($keywordlist)).' ...';
|
||||
|
||||
print_user_list(array($spamusers_desc, $spamusers_blog), $keywords);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function print_user_list($users_rs, $keywords) {
|
||||
global $CFG, $SESSION;
|
||||
|
||||
// reset session everytime this function is called
|
||||
$SESSION->users_result = array();
|
||||
$count = 0;
|
||||
|
||||
foreach ($users_rs as $rs){
|
||||
foreach ($rs as $user) {
|
||||
if (!$count) {
|
||||
echo '<table border="1" width="100%" id="data-grid"><tr><th> </th><th>'.get_string('user','admin').'</th><th>'.get_string('spamdesc', 'report_spamcleaner').'</th><th>'.get_string('spamoperation', 'report_spamcleaner').'</th></tr>';
|
||||
}
|
||||
$count++;
|
||||
filter_user($user, $keywords, $count);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$count) {
|
||||
echo get_string('spamcannotfinduser', 'report_spamcleaner');
|
||||
|
||||
} else {
|
||||
echo '</table>';
|
||||
echo '<div class="mld-align">
|
||||
<button id="removeall_btn">'.get_string('spamdeleteall', 'report_spamcleaner').'</button>
|
||||
</div>';
|
||||
}
|
||||
}
|
||||
function filter_user($user, $keywords, $count) {
|
||||
global $CFG;
|
||||
$image_search = false;
|
||||
if (in_array('<img', $keywords)) {
|
||||
$image_search = true;
|
||||
}
|
||||
if (isset($user->summary)) {
|
||||
$user->description = '<h3>'.get_string('spamfromblog', 'report_spamcleaner').'</h3>'.$user->summary;
|
||||
unset($user->summary);
|
||||
}
|
||||
if (preg_match('#<img.*src=[\"\']('.$CFG->wwwroot.')#', $user->description, $matches)
|
||||
&& $image_search) {
|
||||
$result = false;
|
||||
foreach ($keywords as $keyword) {
|
||||
if (preg_match('#'.$keyword.'#', $user->description)
|
||||
&& ($keyword != '<img')) {
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
if ($result) {
|
||||
echo print_user_entry($user, $keywords, $count);
|
||||
} else {
|
||||
unset($user);
|
||||
}
|
||||
} else {
|
||||
echo print_user_entry($user, $keywords, $count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function print_user_entry($user, $keywords, $count) {
|
||||
|
||||
global $SESSION, $CFG;
|
||||
|
||||
$smalluserobject = new stdClass(); // All we need to delete them later
|
||||
$smalluserobject->id = $user->id;
|
||||
$smalluserobject->email = $user->email;
|
||||
$smalluserobject->auth = $user->auth;
|
||||
$smalluserobject->firstname = $user->firstname;
|
||||
$smalluserobject->lastname = $user->lastname;
|
||||
$smalluserobject->username = $user->username;
|
||||
|
||||
if (empty($SESSION->users_result[$user->id])) {
|
||||
$SESSION->users_result[$user->id] = $smalluserobject;
|
||||
$html = '<tr valign="top" id="row-'.$user->id.'" class="result-row">';
|
||||
$html .= '<td width="10">'.$count.'</td>';
|
||||
$html .= '<td width="30%" align="left"><a href="'.$CFG->wwwroot."/user/view.php?course=1&id=".$user->id.'" title="'.s($user->username).'">'.fullname($user).'</a>';
|
||||
|
||||
$html .= "<ul>";
|
||||
$profile_set = array('city'=>true, 'country'=>true, 'email'=>true);
|
||||
foreach ($profile_set as $key=>$value) {
|
||||
if (isset($user->$key)){
|
||||
$html .= '<li>'.$user->$key.'</li>';
|
||||
}
|
||||
}
|
||||
$html .= "</ul>";
|
||||
$html .= '</td>';
|
||||
|
||||
foreach ($keywords as $keyword) {
|
||||
$user->description = highlight($keyword, $user->description);
|
||||
}
|
||||
|
||||
if (!isset($user->descriptionformat)) {
|
||||
$user->descriptionformat = FORMAT_MOODLE;
|
||||
}
|
||||
|
||||
$html .= '<td align="left">'.format_text($user->description, $user->descriptionformat, array('overflowdiv'=>true)).'</td>';
|
||||
$html .= '<td width="100px" align="center">';
|
||||
$html .= '<button onclick="M.report_spamcleaner.del_user(this,'.$user->id.')">'.get_string('deleteuser', 'admin').'</button><br />';
|
||||
$html .= '<button onclick="M.report_spamcleaner.ignore_user(this,'.$user->id.')">'.get_string('ignore', 'admin').'</button>';
|
||||
$html .= '</td>';
|
||||
$html .= '</tr>';
|
||||
return $html;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
@@ -0,0 +1,40 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Strings for component 'report_spamcleaner', language 'en', branch 'MOODLE_20_STABLE'
|
||||
*
|
||||
* @package report_spamcleaner
|
||||
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['pluginname'] = 'Spam cleaner';
|
||||
$string['spamauto'] = 'Autodetect common spam patterns';
|
||||
$string['spamcannotdelete'] = 'Cannot delete this user';
|
||||
$string['spamcannotfinduser'] = 'No users matching your search';
|
||||
$string['spamcleanerintro'] = 'This script allows you to search all user profiles for certain strings and then delete those accounts which are obviously created by spammers. You can search for multiple keywords using commas (eg casino, porn)<br /><br />Moodle docs has more information about <a href="http://docs.moodle.org/en/Reducing_spam_in_Moodle">Reducing spam in Moodle</a>.';
|
||||
$string['spamdeleteall'] = 'Delete all these user accounts';
|
||||
$string['spamdeleteallconfirm'] = 'Are you sure you want to delete all these user accounts? You can not undo this.';
|
||||
$string['spamdeleteconfirm'] = 'Are you sure you want to delete this entry? You can not undo this.';
|
||||
$string['spamdesc'] = 'Description';
|
||||
$string['spameg'] = 'eg: casino, porn, xxx';
|
||||
$string['spamfromblog'] = 'From blog post:';
|
||||
$string['spaminvalidresult'] = 'Unknown but invalid result';
|
||||
$string['spamoperation'] = 'Operation';
|
||||
$string['spamresult'] = 'Results of searching user profiles containing:';
|
||||
$string['spamsearch'] = 'Search for these keywords';
|
||||
@@ -0,0 +1,115 @@
|
||||
M.report_spamcleaner = {
|
||||
Y: null,
|
||||
row: null,
|
||||
me: null,
|
||||
|
||||
del_all: function() {
|
||||
var context = M.report_spamcleaner;
|
||||
|
||||
var yes = confirm(M.str.report_spamcleaner.spamdeleteallconfirm);
|
||||
if (yes) {
|
||||
var cfg = {
|
||||
method: "POST",
|
||||
on: {
|
||||
success : function(id, o, args) {
|
||||
try {
|
||||
var resp = context.Y.JSON.parse(o.responseText);
|
||||
} catch(e) {
|
||||
alert(M.str.report_spamcleaner.spaminvalidresult);
|
||||
return;
|
||||
}
|
||||
if (resp == true) {
|
||||
window.location.href=window.location.href;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
context.Y.io(context.me+'?delall=yes&sesskey='+M.cfg.sesskey, cfg);
|
||||
}
|
||||
},
|
||||
|
||||
del_user: function(obj, id) {
|
||||
var context = M.report_spamcleaner;
|
||||
|
||||
if (context.Y == null) {
|
||||
// not initialised yet
|
||||
return;
|
||||
}
|
||||
|
||||
var yes = confirm(M.str.report_spamcleaner.spamdeleteconfirm);
|
||||
if (yes) {
|
||||
context.row = obj;
|
||||
var cfg = {
|
||||
method: "POST",
|
||||
on: {
|
||||
success : function(id, o, args) {
|
||||
try {
|
||||
var resp = context.Y.JSON.parse(o.responseText);
|
||||
} catch(e) {
|
||||
alert(M.str.report_spamcleaner.spaminvalidresult);
|
||||
return;
|
||||
}
|
||||
if (context.row) {
|
||||
if (resp == true) {
|
||||
while(context.row.tagName != 'TR') {
|
||||
context.row = context.row.parentNode;
|
||||
}
|
||||
context.row.parentNode.removeChild(context.row);
|
||||
context.row = null;
|
||||
} else {
|
||||
alert(M.str.report_spamcleaner.spamcannotdelete);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
context.Y.io(context.me+'?del=yes&sesskey='+M.cfg.sesskey+'&id='+id, cfg);
|
||||
}
|
||||
},
|
||||
|
||||
ignore_user: function(obj, id) {
|
||||
var context = M.report_spamcleaner;
|
||||
|
||||
if (context.Y == null) {
|
||||
// not initilised yet
|
||||
return;
|
||||
}
|
||||
|
||||
context.row = obj;
|
||||
var cfg = {
|
||||
method: "POST",
|
||||
on: {
|
||||
success : function(id, o, args) {
|
||||
try {
|
||||
var resp = context.Y.JSON.parse(o.responseText);
|
||||
} catch(e) {
|
||||
alert(M.str.report_spamcleaner.spaminvalidresult);
|
||||
return;
|
||||
}
|
||||
if (context.row) {
|
||||
if (resp == true){
|
||||
while(context.row.tagName != 'TR') {
|
||||
context.row = context.row.parentNode;
|
||||
}
|
||||
context.row.parentNode.removeChild(context.row);
|
||||
context.row = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
context.Y.io(context.me+'?ignore=yes&sesskey='+M.cfg.sesskey+'&id='+id, cfg);
|
||||
},
|
||||
|
||||
init: function(Y, me) {
|
||||
var context = M.report_spamcleaner;
|
||||
|
||||
Y.use('json', 'io', function (Y) {
|
||||
context.Y = Y;
|
||||
context.me = me;
|
||||
if (Y.one("#removeall_btn")) {
|
||||
Y.on("click", context.del_all, "#removeall_btn");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
// spam cleaner
|
||||
$ADMIN->add('reports', new admin_externalpage('reportspamcleaner', get_string('pluginname', 'report_spamcleaner'), "$CFG->wwwroot/$CFG->admin/report/spamcleaner/index.php", 'moodle/site:config'));
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
// just a link to course report
|
||||
$ADMIN->add('reports', new admin_externalpage('reportstats', get_string('stats', 'admin'), "$CFG->wwwroot/course/report/stats/index.php", 'coursereport/stats:view'));
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
@@ -20,8 +21,8 @@
|
||||
* Syntax: coveragefile.php/path/to/file/file.html
|
||||
* coveragefile.php?file=path/to/file/file.html
|
||||
*
|
||||
* @package tool
|
||||
* @subpackage unittest
|
||||
* @package moodlecore
|
||||
* @subpackage simpletestcoverage
|
||||
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
@@ -29,12 +30,12 @@
|
||||
// disable moodle specific debug messages and any errors in output
|
||||
define('NO_DEBUG_DISPLAY', true);
|
||||
|
||||
require(dirname(__FILE__) . '/../../../config.php');
|
||||
require_once(dirname(__FILE__) . '/../../../config.php');
|
||||
require_once($CFG->libdir . '/filelib.php');
|
||||
|
||||
// basic security, require login + require site config cap
|
||||
require_login();
|
||||
require_capability('tool/unittest:execute', get_context_instance(CONTEXT_SYSTEM));
|
||||
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
|
||||
|
||||
// get file requested
|
||||
$relativepath = get_file_argument();
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// NOTICE OF COPYRIGHT //
|
||||
// //
|
||||
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
||||
// http://moodle.com //
|
||||
// //
|
||||
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
|
||||
// //
|
||||
// This program 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 2 of the License, or //
|
||||
// (at your option) any later version. //
|
||||
// //
|
||||
// This program 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: //
|
||||
// //
|
||||
// http://www.gnu.org/copyleft/gpl.html //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$capabilities = array(
|
||||
|
||||
'report/unittest:view' => array(
|
||||
'riskbitmask' => RISK_DATALOSS,
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'archetypes' => array(
|
||||
'manager' => CAP_ALLOW
|
||||
),
|
||||
|
||||
'clonepermissionsfrom' => 'moodle/site:config',
|
||||
)
|
||||
);
|
||||
@@ -1,43 +1,23 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Run database functional tests.
|
||||
*
|
||||
* @package tool
|
||||
* @subpackage unittest
|
||||
* @copyright 2008 Petr Skoda {@link http://skodak.org}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @package SimpleTestEx
|
||||
*/
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
require(dirname(__FILE__) . '/../../../config.php');
|
||||
require_once(dirname(__FILE__).'/../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once('simpletestlib.php');
|
||||
require_once('simpletestcoveragelib.php');
|
||||
require_once($CFG->libdir.'/simpletestcoveragelib.php');
|
||||
require_once('ex_simple_test.php');
|
||||
require_once('ex_reporter.php');
|
||||
|
||||
$showpasses = optional_param('showpasses', false, PARAM_BOOL);
|
||||
$codecoverage = optional_param('codecoverage', false, PARAM_BOOL);
|
||||
$selected = optional_param_array('selected', array(), PARAM_INT);
|
||||
$selected = optional_param('selected', array(), PARAM_INT);
|
||||
|
||||
// Print the header and check access.
|
||||
admin_externalpage_setup('tooldbtest');
|
||||
admin_externalpage_setup('reportdbtest');
|
||||
echo $OUTPUT->header();
|
||||
|
||||
global $UNITTEST;
|
||||
@@ -128,11 +108,11 @@ echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
|
||||
echo '<form method="post" action="dbtest.php">';
|
||||
echo '<div>';
|
||||
echo $OUTPUT->heading("Run functional database tests"); // TODO: localise
|
||||
echo '<p>'.html_writer::checkbox('showpasses', 1, $showpasses, get_string('showpasses', 'tool_unittest')).'</p>';
|
||||
echo '<p>'.html_writer::checkbox('showpasses', 1, $showpasses, get_string('showpasses', 'simpletest')).'</p>';
|
||||
if (moodle_coverage_recorder::can_run_codecoverage()) {
|
||||
echo '<p>'.html_writer::checkbox('codecoverage', 1, $codecoverage, get_string('codecoverageanalysis', 'tool_unittest')).'</p>';
|
||||
echo '<p>'.html_writer::checkbox('codecoverage', 1, $codecoverage, get_string('codecoverageanalysis', 'simpletest')).'</p>';
|
||||
} else {
|
||||
echo '<p>'; print_string('codecoveragedisabled', 'tool_unittest'); echo '<input type="hidden" name="codecoverage" value="0" /></p>';
|
||||
echo '<p>'; print_string('codecoveragedisabled', 'simpletest'); echo '<input type="hidden" name="codecoverage" value="0" /></p>';
|
||||
}
|
||||
echo '<p><strong>'."Databases:".'</strong></p>';
|
||||
echo '<ul>';
|
||||
@@ -154,7 +134,7 @@ $CFG->func_test_db_1 = array("native", "pgsql", "localhost", "moodleuser", "pass
|
||||
$CFG->func_test_db_2 = array("native", "mssql", "localhost", "moodleuser", "password", "moodle", "test", null);
|
||||
</pre>
|
||||
<p>where order of parameters is: dblibrary, dbtype, dbhost, dbuser, dbpass, dbname, prefix, dboptions</p>';
|
||||
echo '<p><input type="submit" value="' . get_string('runtests', 'tool_unittest') . '" /></p>';
|
||||
echo '<p><input type="submit" value="' . get_string('runtests', 'simpletest') . '" /></p>';
|
||||
echo '</div>';
|
||||
echo '</form>';
|
||||
echo $OUTPUT->box_end();
|
||||
@@ -1,27 +1,11 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* A SimpleTest report format for Moodle.
|
||||
*
|
||||
* @package tool
|
||||
* @subpackage unittest
|
||||
* @copyright © 2006 The Open University
|
||||
* @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @copyright © 2006 The Open University
|
||||
* @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package SimpleTestEx
|
||||
*/
|
||||
|
||||
if (!defined('MOODLE_INTERNAL')) {
|
||||
@@ -180,7 +164,7 @@ class ExHtmlReporter extends HtmlReporter {
|
||||
foreach ($stacktrace as $frame) {
|
||||
if (empty($frame['file']) || (strpos($frame['file'], 'simpletestlib') === false &&
|
||||
strpos($frame['file'], 'simpletestcoveragelib') === false
|
||||
&& strpos($frame['file'], 'tool/unittest') === false)) {
|
||||
&& strpos($frame['file'], 'report/unittest') === false)) {
|
||||
$filteredstacktrace[] = $frame;
|
||||
$interestinglines += 1;
|
||||
$dotsadded = false;
|
||||
@@ -287,11 +271,6 @@ class ExHtmlReporter extends HtmlReporter {
|
||||
* Look up a lang string in the appropriate file.
|
||||
*/
|
||||
function get_string($identifier, $a = NULL) {
|
||||
return get_string($identifier, 'tool_unittest', $a);
|
||||
}
|
||||
|
||||
function _htmlEntities($message) {
|
||||
// Override subclass message that breaks UTF8.
|
||||
return s($message);
|
||||
return get_string($identifier, 'simpletest', $a);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,12 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* A SimpleTest GroupTest that automatically finds all the
|
||||
* test files in a directory tree according to certain rules.
|
||||
*
|
||||
* @package tool
|
||||
* @subpackage unittest
|
||||
* @copyright © 2006 The Open University
|
||||
* @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @copyright © 2006 The Open University
|
||||
* @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package SimpleTestEx
|
||||
*/
|
||||
|
||||
if (!defined('MOODLE_INTERNAL')) {
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* Run the unit tests.
|
||||
*
|
||||
* @copyright © 2006 The Open University
|
||||
* @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package SimpleTestEx
|
||||
*/
|
||||
|
||||
define('NO_OUTPUT_BUFFERING', true);
|
||||
|
||||
require_once(dirname(__FILE__).'/../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/simpletestcoveragelib.php');
|
||||
require_once('ex_simple_test.php');
|
||||
require_once('ex_reporter.php');
|
||||
|
||||
// Always run the unit tests in developer debug mode.
|
||||
$CFG->debug = DEBUG_DEVELOPER;
|
||||
error_reporting($CFG->debug);
|
||||
raise_memory_limit(MEMORY_EXTRA);
|
||||
|
||||
// page parameters
|
||||
$path = optional_param('path', null, PARAM_PATH);
|
||||
$showpasses = optional_param('showpasses', false, PARAM_BOOL);
|
||||
$codecoverage = optional_param('codecoverage', false, PARAM_BOOL);
|
||||
$showsearch = optional_param('showsearch', false, PARAM_BOOL);
|
||||
|
||||
admin_externalpage_setup('reportsimpletest', '', array('showpasses'=>$showpasses, 'showsearch'=>$showsearch));
|
||||
|
||||
$unittest = true;
|
||||
|
||||
global $UNITTEST;
|
||||
$UNITTEST = new stdClass();
|
||||
|
||||
// This limit is the time allowed per individual test function. Please do not
|
||||
// increase this value. If you get a PHP time limit when running unit tests,
|
||||
// find the unit test which is running slowly, and either make it faster,
|
||||
// split it into multiple tests, or call set_time_limit within that test.
|
||||
define('TIME_ALLOWED_PER_UNIT_TEST', 60);
|
||||
|
||||
// Print the header.
|
||||
$strtitle = get_string('unittests', 'simpletest');
|
||||
|
||||
if (!is_null($path)) {
|
||||
//trim so user doesn't get an error if they include a space on the end of the path (ie by pasting path)
|
||||
$path = trim($path);
|
||||
|
||||
// Turn off xmlstrictheaders during the unit test run.
|
||||
$origxmlstrictheaders = !empty($CFG->xmlstrictheaders);
|
||||
$CFG->xmlstrictheaders = false;
|
||||
echo $OUTPUT->header();
|
||||
$CFG->xmlstrictheaders = $origxmlstrictheaders;
|
||||
unset($origxmlstrictheaders);
|
||||
|
||||
// Create the group of tests.
|
||||
$test = new autogroup_test_coverage($showsearch, true, $codecoverage, 'Moodle Unit Tests Code Coverage Report', 'unittest');
|
||||
|
||||
// OU specific. We use the _nonproject folder for stuff we want to
|
||||
// keep in CVS, but which is not really relevant. It does no harm
|
||||
// to leave this here.
|
||||
$test->addIgnoreFolder($CFG->dirroot . '/_nonproject');
|
||||
|
||||
// Make the reporter, which is what displays the results.
|
||||
$reporter = new ExHtmlReporter($showpasses);
|
||||
|
||||
if ($showsearch) {
|
||||
echo $OUTPUT->heading('Searching for test cases');
|
||||
}
|
||||
flush();
|
||||
|
||||
// Work out what to test.
|
||||
if (substr($path, 0, 1) == '/') {
|
||||
$path = substr($path, 1);
|
||||
}
|
||||
$path = $CFG->dirroot . '/' . $path;
|
||||
if (substr($path, -1) == '/') {
|
||||
$path = substr($path, 0, -1);
|
||||
}
|
||||
$displaypath = substr($path, strlen($CFG->dirroot) + 1);
|
||||
$ok = true;
|
||||
if (is_file($path)) {
|
||||
$test->addTestFile($path);
|
||||
} else if (is_dir($path)){
|
||||
$test->findTestFiles($path);
|
||||
} else {
|
||||
echo $OUTPUT->box(get_string('pathdoesnotexist', 'simpletest', $path), 'errorbox');
|
||||
$ok = false;
|
||||
}
|
||||
|
||||
// If we have something to test, do it.
|
||||
if ($ok) {
|
||||
if ($path == $CFG->dirroot) {
|
||||
$title = get_string('moodleunittests', 'simpletest', get_string('all', 'simpletest'));
|
||||
} else {
|
||||
$title = get_string('moodleunittests', 'simpletest', $displaypath);
|
||||
}
|
||||
echo $OUTPUT->heading($title);
|
||||
$test->run($reporter);
|
||||
}
|
||||
|
||||
$formheader = get_string('retest', 'simpletest');
|
||||
} else {
|
||||
$displaypath = '';
|
||||
echo $OUTPUT->header();
|
||||
$formheader = get_string('rununittests', 'simpletest');
|
||||
}
|
||||
// Print the form for adjusting options.
|
||||
echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
|
||||
echo $OUTPUT->heading($formheader);
|
||||
echo '<form method="get" action="index.php">';
|
||||
echo '<fieldset class="invisiblefieldset">';
|
||||
echo '<p>'.html_writer::checkbox('showpasses', 1, $showpasses, get_string('showpasses', 'simpletest')).'</p>';
|
||||
echo '<p>'.html_writer::checkbox('showsearch', 1, $showsearch, get_string('showsearch', 'simpletest')).'</p>';
|
||||
if (moodle_coverage_recorder::can_run_codecoverage()) {
|
||||
echo '<p>'.html_writer::checkbox('codecoverage', 1, $codecoverage, get_string('codecoverageanalysis', 'simpletest')).'</p>';
|
||||
} else {
|
||||
echo '<p>'; print_string('codecoveragedisabled', 'simpletest'); echo '<input type="hidden" name="codecoverage" value="0" /></p>';
|
||||
}
|
||||
echo '<p>';
|
||||
echo '<label for="path">', get_string('onlytest', 'simpletest'), '</label> ';
|
||||
echo '<input type="text" id="path" name="path" value="', $displaypath, '" size="40" />';
|
||||
echo '</p>';
|
||||
echo '<input type="submit" value="' . get_string('runtests', 'simpletest') . '" />';
|
||||
echo '</fieldset>';
|
||||
echo '</form>';
|
||||
echo $OUTPUT->box_end();
|
||||
|
||||
// Print link to latest code coverage for this report type
|
||||
if (is_null($path) || !$codecoverage) {
|
||||
moodle_coverage_reporter::print_link_to_latest('unittest');
|
||||
}
|
||||
|
||||
// Footer.
|
||||
echo $OUTPUT->footer();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user