Compare commits
1155 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2159765e74 | |||
| f03f3a665a | |||
| e15ed28787 | |||
| b5fcbcf59c | |||
| de0caf4bda | |||
| 4985cbde0b | |||
| 3c95dfea94 | |||
| 2cfd5fd531 | |||
| 9c067299f6 | |||
| 989b0e64f1 | |||
| 67b98646eb | |||
| a9e79cb1d7 | |||
| 767904d06c | |||
| 0a5bf56672 | |||
| abf58c0272 | |||
| e51f717e51 | |||
| f10af7b137 | |||
| 89c1fe8297 | |||
| 61ac3a70dd | |||
| eb1b491181 | |||
| 9d73b7e3fc | |||
| 972f7bb2f0 | |||
| 4889610b11 | |||
| c07cb2e8bc | |||
| c0e37117b2 | |||
| aa13521bf1 | |||
| 04da7fef54 | |||
| 62082bebd0 | |||
| 9499230085 | |||
| 3556e43683 | |||
| b8f2fd6a59 | |||
| c5c5f5376c | |||
| b945888dca | |||
| e0eb5d21f5 | |||
| 2e14051ba0 | |||
| adb6ccd946 | |||
| 9346a8ff99 | |||
| fa952896a3 | |||
| c73705641f | |||
| bfe5f847b4 | |||
| 10ac51efae | |||
| 623a81e19a | |||
| feeb76097b | |||
| 79b4a87567 | |||
| 8166ff5358 | |||
| 56eece4e54 | |||
| 6f806335e0 | |||
| 80fbfbb3f6 | |||
| 3be9556391 | |||
| 8f0a36a201 | |||
| 1c077f6ad0 | |||
| 156726fd07 | |||
| 0d21fc03a3 | |||
| c373242b42 | |||
| fedfff27f5 | |||
| 79143931ce | |||
| 0074ab9cef | |||
| 2a200a31d0 | |||
| 48629ec809 | |||
| 8dd6ca3a27 | |||
| 7fbdd28395 | |||
| 8a50f7d16b | |||
| 617d203373 | |||
| a71482a737 | |||
| 14e93d3cae | |||
| 69785be47a | |||
| 7738dd48c5 | |||
| e8e23ffcc3 | |||
| 9a71308057 | |||
| 2e4dfb210e | |||
| 8d73532067 | |||
| 696018df63 | |||
| c7ad7da9c0 | |||
| 1701805b9e | |||
| 916dec711b | |||
| 0af2efcf54 | |||
| 5bac2c2848 | |||
| a4bb739b92 | |||
| 9c536d5a9c | |||
| 400688352e | |||
| 45c3dd8fce | |||
| e67af80ed5 | |||
| cd669edcc1 | |||
| 4f7ee1cdcc | |||
| 9f09bc9342 | |||
| 95444f7b1d | |||
| c22c551225 | |||
| ae47f3bde9 | |||
| 6ea3353c7c | |||
| cb5c33b235 | |||
| 551d425a88 | |||
| 0d5f1abbef | |||
| 35d3f6b7d9 | |||
| 5fcba158ce | |||
| b1f45df9be | |||
| 03c4782e11 | |||
| e41ba841e0 | |||
| 3effcb29a1 | |||
| fffe748c4c | |||
| 2ead96df61 | |||
| 5200e67665 | |||
| 10cae68206 | |||
| 7234be25bb | |||
| 580898921f | |||
| 3bd8cfe4a3 | |||
| 30911d519a | |||
| 25fcb7a520 | |||
| 6da5a0db23 | |||
| dd385043a6 | |||
| 1ee253d0ef | |||
| 719e210878 | |||
| 82a461040d | |||
| db6f2bb775 | |||
| f53d2cf806 | |||
| 3cee044c01 | |||
| d13cf40879 | |||
| 309be30e7a | |||
| b2fe689814 | |||
| 6f31d67743 | |||
| 081c26d41f | |||
| 0ba3cbecca | |||
| bd2fb930a2 | |||
| 50d3981988 | |||
| d7b3edf944 | |||
| 8ccb3b2440 | |||
| e30fdc6c94 | |||
| e11bdd6ac7 | |||
| 156f59304e | |||
| 851c918d23 | |||
| d8b837f9f2 | |||
| 2764745f48 | |||
| 228b3a13c6 | |||
| c4e8deecbb | |||
| fa297173a7 | |||
| f2c7967ce5 | |||
| 4ea98f458e | |||
| 0b3f171430 | |||
| 9937440935 | |||
| e40c5d4def | |||
| 6627e36129 | |||
| 1e6e88f1fb | |||
| 9b729e076c | |||
| 6e7b8954e9 | |||
| 3ecb39e535 | |||
| e0240136f5 | |||
| ceb41f927c | |||
| 3c01f1883c | |||
| 48e8f83bc2 | |||
| 8074fe4f8c | |||
| b50ff44a27 | |||
| 5b24f78751 | |||
| 542288130f | |||
| d1c3e2b83c | |||
| 45b80481ef | |||
| 1d375abe68 | |||
| 69472eef28 | |||
| c160d5fe09 | |||
| 432d2bade1 | |||
| aa665d6353 | |||
| 86c651cc3d | |||
| 1060c2164d | |||
| 27e280b27c | |||
| 28435cbcb6 | |||
| ade7c41b90 | |||
| 5383ba0d43 | |||
| 5f9b44089e | |||
| f32ee22655 | |||
| e7d8321f40 | |||
| c4b46d9a7e | |||
| 1dd40dc0d7 | |||
| e4bfac7587 | |||
| 9612e92185 | |||
| dc60ee9a74 | |||
| 3c9c3aa722 | |||
| 68f82f804c | |||
| 90260a3a2a | |||
| 05105cbe47 | |||
| 3b5ff77414 | |||
| e4043b37d8 | |||
| c8c1f2f3ac | |||
| 43cf71ebc0 | |||
| 903c830041 | |||
| 581e0d7ac4 | |||
| b994941167 | |||
| 6483c5b005 | |||
| 66a2d3b1fc | |||
| beef81db81 | |||
| 64895b6a85 | |||
| 36560de1bf | |||
| d1a83777f9 | |||
| 342f26f5a7 | |||
| 96d5e696d6 | |||
| 9ff8c54b52 | |||
| 5828d143d4 | |||
| b486ed5604 | |||
| c669f4025d | |||
| 2802a8eb01 | |||
| abe7973a9a | |||
| 704926310d | |||
| d756a3ef79 | |||
| fc431a5a19 | |||
| 89af1a706a | |||
| 4d07f1c87e | |||
| dec816756a | |||
| 676e4d4569 | |||
| eb24292dee | |||
| 66f303360d | |||
| 9ed386b6cf | |||
| a51fb7e9ba | |||
| c194163564 | |||
| 6524c910da | |||
| 4c92d180ac | |||
| 8a945601b3 | |||
| 5bb0cd916d | |||
| 31a8cf8e83 | |||
| 7e3fdfdb0e | |||
| 786eed65f9 | |||
| 6d305e4f73 | |||
| 55ea2fb983 | |||
| 79b35f3866 | |||
| fd13e4f162 | |||
| f5187943c0 | |||
| 579c4bc033 | |||
| 7727d7a558 | |||
| 03acab4231 | |||
| 814783b478 | |||
| bb6c8de31f | |||
| 265859b120 | |||
| d370403233 | |||
| e04abdba8b | |||
| fd9e47f7c9 | |||
| 645574ae9c | |||
| e04544af60 | |||
| b540ebdc82 | |||
| 28f148f63c | |||
| 2767262c21 | |||
| b8b118b322 | |||
| 04e43cfc7e | |||
| 71bf0e07aa | |||
| 67f381e4d3 | |||
| e9c5d87a17 | |||
| f868465f02 | |||
| b546e97106 | |||
| 2e2a9ec02c | |||
| 88b119010d | |||
| e7b98680d7 | |||
| aa96913f3c | |||
| df859bc818 | |||
| b950f12601 | |||
| 2f4ec8a0a7 | |||
| 3682b74272 | |||
| 5a966b8089 | |||
| 898be4fbdb | |||
| f60ff51cac | |||
| 83e55afa36 | |||
| 4113a8d05d | |||
| d547bb0bd0 | |||
| cd0de43baf | |||
| 3fca7144ca | |||
| 22de2a9020 | |||
| bc4fb0c278 | |||
| dff2a97ab1 | |||
| f2234e611d | |||
| 19a9e4f2fa | |||
| abe16888de | |||
| 2788e588fe | |||
| 7ed8fad35b | |||
| 067b054260 | |||
| 52c28ff98a | |||
| d9c0d727d7 | |||
| 31c8f5ebaa | |||
| 35a8b3cfac | |||
| 88906bf330 | |||
| 823ebe16cc | |||
| 1a5a1c0e6c | |||
| 6042285796 | |||
| ea718748b8 | |||
| fec5c0cf5f | |||
| 28d02ef39e | |||
| 307b92632b | |||
| dfabc486c9 | |||
| c2b308cfc0 | |||
| 191e741060 | |||
| fdb5bf270e | |||
| 826cedfd54 | |||
| e46fe67177 | |||
| d27ab8aa93 | |||
| df2415e85f | |||
| 5df04607be | |||
| da9429c8e6 | |||
| 9658298c2e | |||
| 45f782d7c7 | |||
| 9709ffccc9 | |||
| e5dbb5ea88 | |||
| 0326d0e6f7 | |||
| e56c4c0027 | |||
| 5d4d1af5d7 | |||
| f891b69aec | |||
| 0f899b0cc3 | |||
| 0471947593 | |||
| 0791d2fbb5 | |||
| 654e003982 | |||
| f847d9f546 | |||
| 68a3d81779 | |||
| bd294d2986 | |||
| e24a45df3f | |||
| 6f49985bb8 | |||
| 5a1655832f | |||
| 26c2f68336 | |||
| 1fcf706f09 | |||
| 8871d7f463 | |||
| 912481e00d | |||
| bbaec83b08 | |||
| acb1e9fc07 | |||
| 57a049c4b5 | |||
| 533f83552c | |||
| 2867af6a5b | |||
| cc18654ce9 | |||
| 5e7932a38f | |||
| 19902c841f | |||
| edeb99025b | |||
| d831f2bd37 | |||
| e04eb3c786 | |||
| 1316b059c9 | |||
| 776e168943 | |||
| 97e5e34231 | |||
| 2538f34611 | |||
| a6b72a94d7 | |||
| 5a84b468c7 | |||
| f21a6c674c | |||
| c7904acb92 | |||
| 4a093d5096 | |||
| 2b808f03b8 | |||
| 5636aa5494 | |||
| a756e41f9f | |||
| 73fc1a1820 | |||
| 0c34967646 | |||
| e299d01687 | |||
| 2113a65fdd | |||
| f0fbafe9d9 | |||
| 5ea5f1052c | |||
| 589358b7f3 | |||
| f40fb532d8 | |||
| 7fc3fa77d7 | |||
| 70d00ab90b | |||
| 22973ebf85 | |||
| 0479b1aa14 | |||
| 20538060c3 | |||
| 80fe7b9ef7 | |||
| 7d8f12b630 | |||
| d3c7da5741 | |||
| a1e836ace4 | |||
| 10ec29097f | |||
| ee8d4be64f | |||
| 772230543b | |||
| f6de7336d1 | |||
| aa6ab4e614 | |||
| 6e1f85a7a8 | |||
| f9d9e0e512 | |||
| 9740b1b449 | |||
| 312fc573c7 | |||
| e3cc7cfd7c | |||
| b890fdaed4 | |||
| acfc17d452 | |||
| 37934e4996 | |||
| 7b1476eb6d | |||
| c1d77cb923 | |||
| 6e5eaf55b9 | |||
| 4e334e2d89 | |||
| 3ab60a5351 | |||
| 6b31e49438 | |||
| ec6270acb8 | |||
| 73c0691713 | |||
| 08888c21c6 | |||
| 2c0838a960 | |||
| 03d0e079c7 | |||
| aab2a31c11 | |||
| 3216e3bcdf | |||
| 40ffadedca | |||
| 30f703a490 | |||
| c52af6208e | |||
| e85de04d7b | |||
| cb512feef5 | |||
| e603181eeb | |||
| b3c8c097aa | |||
| f8338c21b5 | |||
| dc56fc912e | |||
| 93c0ab4628 | |||
| 734e6125ed | |||
| 689eeabb2f | |||
| b31b9c0d8d | |||
| baec5bf1b5 | |||
| 675c797a5c | |||
| cec35fd605 | |||
| b0178a9339 | |||
| 73078aefd5 | |||
| c5129f59e6 | |||
| b3e0a94764 | |||
| a34725b3eb | |||
| 102ab4b93d | |||
| 0b8efe1434 | |||
| 1c3090aabc | |||
| 135de95512 | |||
| 86bfbf6d5a | |||
| 4bfcbb6065 | |||
| 3ebec13e90 | |||
| 4130b29319 | |||
| 7c581c26d6 | |||
| 753d8d6b8f | |||
| cac526294c | |||
| 9d86cefba4 | |||
| 9161104df4 | |||
| a1f37c56c7 | |||
| 4ff615ba18 | |||
| 0b01e09a84 | |||
| 2546b11627 | |||
| 3856061526 | |||
| 97268bfcd1 | |||
| 61b8ee4cc8 | |||
| dc30763a29 | |||
| 13cd3572ef | |||
| 61ed6f0fef | |||
| e366e28485 | |||
| 6323f16bce | |||
| 0728db718f | |||
| 7ac3cc9a32 | |||
| cf8a84bf7e | |||
| 33edb1d079 | |||
| 6aec578ba1 | |||
| f8c0dc7619 | |||
| 22aa2fdc7c | |||
| 070fd51ff0 | |||
| 574b31e05a | |||
| 6a00dfa325 | |||
| 4d5f3910e9 | |||
| a2e4bb85a6 | |||
| 056a946997 | |||
| 7b97dc4cbb | |||
| 6d45d2bb7c | |||
| 362b789ca0 | |||
| e2e7da4724 | |||
| 82e0a8a59f | |||
| f73d700f79 | |||
| c64f343eaa | |||
| 458cc5c807 | |||
| f964ff9281 | |||
| 67c0bc01eb | |||
| 51d6e3d5b9 | |||
| 8dea1ae18c | |||
| 55b51fafa7 | |||
| e0240b2abd | |||
| fbffc13306 | |||
| 2a2124087f | |||
| 1c86f1b0ac | |||
| e18c7dde34 | |||
| c672c0ed6c | |||
| fb205e7b0b | |||
| a92a26b3b6 | |||
| 7ece8b4084 | |||
| dca4f867b6 | |||
| eaea1cefde | |||
| d7267110ca | |||
| 2f64c88416 | |||
| 5af402822b | |||
| 82b904822e | |||
| 4b2839e2a5 | |||
| 0ce91e17f7 | |||
| 42f60c49fb | |||
| 56cef87b61 | |||
| c52849d56c | |||
| afb7e5382c | |||
| a50c3fb9ad | |||
| 5515ae9a0a | |||
| e0d027939e | |||
| 3354933a9f | |||
| c88022ade7 | |||
| 5a6d196559 | |||
| 8d0787e3b1 | |||
| 3cbb43304a | |||
| 52b6e169b8 | |||
| 460da32af8 | |||
| 7ca1f7a0fc | |||
| 1726d852ae | |||
| 2dc83e6145 | |||
| bb2067c851 | |||
| d5b43ea6a2 | |||
| 4c7971bb08 | |||
| 047158d694 | |||
| f2af2ec841 | |||
| f01be9f366 | |||
| a5886c1a26 | |||
| 6ed6493820 | |||
| 6a31fe27bb | |||
| 8cc2a7e47a | |||
| 473474f370 | |||
| ecde99b07d | |||
| 26f86416a0 | |||
| 9eb6cba683 | |||
| b65da94dd7 | |||
| f8102d906e | |||
| 1db15f42c6 | |||
| 5494b1a058 | |||
| 6790b9a824 | |||
| bfe073b05d | |||
| 5c211a86f1 | |||
| 52a7473e9a | |||
| 28364d4103 | |||
| a2b4f68e91 | |||
| f91d11fc6f | |||
| 4a040da19a | |||
| 0c24a4523d | |||
| ae5c3732d1 | |||
| 3ee21ffa01 | |||
| d2aa927a0a | |||
| 50537ba778 | |||
| eada690a18 | |||
| 33f4c4c10b | |||
| 45b0c62de6 | |||
| d25db1b795 | |||
| 95c1a1e51d | |||
| adfd6053f1 | |||
| 22962abbf0 | |||
| 94e044dd6f | |||
| e9103c0a0e | |||
| 098a5acddd | |||
| 76d9c74e68 | |||
| 51bddf22fd | |||
| b290c986f6 | |||
| 85557feb30 | |||
| bb8b3cffe6 | |||
| 4b3fd72079 | |||
| c972b89def | |||
| 7d3d94eee5 | |||
| 791733eaab | |||
| 69658560bf | |||
| 08b51e7f13 | |||
| ab478fe0bc | |||
| 94f7464280 | |||
| 277ae48e25 | |||
| fe27f84099 | |||
| 876a3baa42 | |||
| 1465d3d426 | |||
| bc5368842f | |||
| 4dc25063e8 | |||
| 436e9574a5 | |||
| fd50629bd0 | |||
| 59fc418b73 | |||
| 9ac773b15c | |||
| d6546599dd | |||
| 552ae7276f | |||
| e8d902964d | |||
| a0dd83702f | |||
| 4b53c0f87d | |||
| 87c2747ee5 | |||
| eaffb7ef7c | |||
| a92bc4ed2d | |||
| 6b57802eca | |||
| 8788cc6fe6 | |||
| 91792878a0 | |||
| 2d3799bfc8 | |||
| fc85b7977f | |||
| 397ad6af5b | |||
| 3aeca96386 | |||
| 256c570e0a | |||
| cc90879d52 | |||
| 822f1fe81c | |||
| a063109a4a | |||
| 4ba3104b23 | |||
| 32f25d39b7 | |||
| 8ae0e59cbb | |||
| 49f3723381 | |||
| f5838b1e56 | |||
| 0b0b1022f9 | |||
| 0d217d2820 | |||
| 669db62519 | |||
| 65cb682f22 | |||
| 5648e66cb2 | |||
| 613d0f81c4 | |||
| 72f0f08f9d | |||
| e00a6b577f | |||
| 4d5025a776 | |||
| 82e1b609d2 | |||
| 81126259ae | |||
| 1e98ff2a8d | |||
| 827f863046 | |||
| b3b4937eb6 | |||
| 5893fbd8e1 | |||
| e6dcae98fa | |||
| 3f4820fadf | |||
| 78700ccdca | |||
| be10e474f3 | |||
| b1ddca5c74 | |||
| e666ae15f6 | |||
| e7ff269394 | |||
| 8c3666955a | |||
| a166672c09 | |||
| cc84c1aba0 | |||
| 62c7a8c799 | |||
| 0b174abec7 | |||
| ba58c9f08e | |||
| dd75d8696e | |||
| aaa9b674c9 | |||
| 2d1541b597 | |||
| b226b10a60 | |||
| 6e115e57be | |||
| 8d81298c4a | |||
| cc8549eaae | |||
| a68a6dcc62 | |||
| ed103b539a | |||
| 3c6ed6e2ca | |||
| eb64eefaab | |||
| 284aefc537 | |||
| bb215b150f | |||
| 2f1fc9d9f2 | |||
| 042be7ddd6 | |||
| 6b502ee98f | |||
| 35aacbe41e | |||
| 63370ab86b | |||
| aacdd2a2aa | |||
| ee71dd5d5b | |||
| 9637977c56 | |||
| 38abaa812b | |||
| 50a391f3ff | |||
| 2f0595b2ba | |||
| 0d2d8435eb | |||
| 84d866f59a | |||
| 3b8a200da9 | |||
| 3a281e4282 | |||
| 8ad8632027 | |||
| adfe07e897 | |||
| c83e62ae8b | |||
| 92179c5667 | |||
| b26a82e9a9 | |||
| 1ed574d378 | |||
| 1ae3f411b5 | |||
| 6592bac242 | |||
| d750ce8fa2 | |||
| 94b7fd6607 | |||
| 576ba278bc | |||
| 8a76863c7e | |||
| 000bfd6e5b | |||
| ec432881c3 | |||
| 17400c041b | |||
| 59911a0388 | |||
| 3c13c816f3 | |||
| c57931ce32 | |||
| e33c29d4b2 | |||
| 0aa5484366 | |||
| 0f9654453d | |||
| 86b6811e97 | |||
| 13d2dda5de | |||
| 0f208a88f0 | |||
| bb038bc7c8 | |||
| c98fa2cd88 | |||
| 6de4bdb976 | |||
| 9f62d5bd19 | |||
| 6f48c01a43 | |||
| 50850f2545 | |||
| d8c5e6c18f | |||
| 94d9f6d84f | |||
| 5f3e7b35d4 | |||
| f6d70ceca1 | |||
| 190dddfc0b | |||
| 9d06855887 | |||
| b755cfd75c | |||
| 3c2df10618 | |||
| 187e8dc3a4 | |||
| d3f811b3c4 | |||
| 241cf74e0a | |||
| d78bca84e8 | |||
| 9c73f43e69 | |||
| 93c9712e34 | |||
| bf28249d82 | |||
| 4328416b29 | |||
| 959a292ddf | |||
| a6dcdb14c9 | |||
| e79859512f | |||
| 22fc88f88b | |||
| ac6e14ff79 | |||
| c8a507097c | |||
| dfa8aab5d8 | |||
| 7bbe53f402 | |||
| 8e88626ff3 | |||
| 68099376a3 | |||
| b5d665d551 | |||
| 526a055559 | |||
| a3d160fdec | |||
| f442462c07 | |||
| b02e348184 | |||
| c1321f6c40 | |||
| 58ce50f528 | |||
| 8ab1c8dfeb | |||
| 2b406390d8 | |||
| 489b503378 | |||
| ee5537a5a9 | |||
| 7481a23090 | |||
| 79536558fa | |||
| 85a0fcf2a2 | |||
| 7d8264c188 | |||
| 1cb675b598 | |||
| c6c9b4faca | |||
| 2a538623e4 | |||
| 83b238f9b8 | |||
| 6548bc4898 | |||
| a23612213a | |||
| a75573c738 | |||
| 8ec33be76c | |||
| 037f56034f | |||
| 57a8ff3a73 | |||
| e12b3b10ca | |||
| e2e0711a49 | |||
| 54862201c5 | |||
| 69cce5950b | |||
| 624567f853 | |||
| fe6a9871bf | |||
| 8656394dac | |||
| be2f1abc87 | |||
| 295c7cad90 | |||
| 6eb25b3e8c | |||
| 93eceb28d2 | |||
| 5a33217812 | |||
| 2f62d8b459 | |||
| 9802accd59 | |||
| af993edd90 | |||
| 86ced6c244 | |||
| 05f6536c54 | |||
| d8b7674ec5 | |||
| 507c75ff7c | |||
| 77c64292d5 | |||
| 9dc01d93fe | |||
| db784f7936 | |||
| acfbbeb1d3 | |||
| 5400aac79f | |||
| f67faa62d6 | |||
| e83a493a43 | |||
| 2b42953f9a | |||
| ef005cf1fe | |||
| ef2286f2d8 | |||
| 5c8cb3a6a4 | |||
| 251e356eb1 | |||
| 6cde557687 | |||
| c512f546b0 | |||
| aeb1c7c456 | |||
| a606b17d90 | |||
| 33698217a3 | |||
| 7685016d20 | |||
| c37304a964 | |||
| 95968dff75 | |||
| ff3ce1ed42 | |||
| 5f9e154544 | |||
| a963e6c8e4 | |||
| 25da571df9 | |||
| 3222c0c272 | |||
| 33942f16e2 | |||
| 6b13469879 | |||
| 7e8ab13d8f | |||
| f9377c0a7e | |||
| 7f491dc474 | |||
| c3e7bda77c | |||
| ea0bc86d6e | |||
| ffb5a93032 | |||
| e2cf6b91da | |||
| d100f76f6e | |||
| 060f414899 | |||
| 8b68630612 | |||
| 323a266cf5 | |||
| 85203af7a3 | |||
| 0f2f33611f | |||
| c201ac514b | |||
| 3080aa14e1 | |||
| 0502b5122c | |||
| ae9f99119a | |||
| b11a0766ed | |||
| 0b3a3435a1 | |||
| 65eda6e60e | |||
| 351c28559b | |||
| edd41a94eb | |||
| 937a8769de | |||
| a490bb4f0d | |||
| 2252803d20 | |||
| 3a580fd193 | |||
| 1c1646cb4b | |||
| 1caa37ac3e | |||
| 14c870de0d | |||
| 3afd68857d | |||
| 2f0a40ab47 | |||
| 615852be16 | |||
| fa6eac40ee | |||
| 21aabcbc9f | |||
| f3d3aa6881 | |||
| c165e7462e | |||
| fd5244dc46 | |||
| d8709908a0 | |||
| 2d10a5ef93 | |||
| 968788be74 | |||
| f56cacd0d8 | |||
| 54cae7edcf | |||
| 07f8fab029 | |||
| ee89fdf92c | |||
| 8e99ea4081 | |||
| 2a3f443ac1 | |||
| b56ccc3192 | |||
| 323a68467c | |||
| 68c5857cb9 | |||
| 7acc360f7c | |||
| 80a6e5fb67 | |||
| b18ecac385 | |||
| 9111f5dacf | |||
| d09916f929 | |||
| 41fd49847c | |||
| 60bcf0156d | |||
| 9be7cc58e4 | |||
| 6913746fb1 | |||
| bd88ac6161 | |||
| 797a1f7e0b | |||
| 1c8e955e4b | |||
| 60ced88eb2 | |||
| 2b11b765dd | |||
| 62cf1ae8c1 | |||
| 501592d7be | |||
| a658b7fe9c | |||
| f9ed2393be | |||
| 7f8cd6639a | |||
| 689dfa7a7c | |||
| f0e02543da | |||
| 159865b202 | |||
| 7fae1f7b6c | |||
| c9f0c6e754 | |||
| b4502ae40f | |||
| aa77a3d3de | |||
| c414f9e5ad | |||
| 2eaf6c0e95 | |||
| 26207ab4c2 | |||
| 23179e6a47 | |||
| 7fc859e6e4 | |||
| 29b951b6dd | |||
| 080eed3f12 | |||
| 70cf5492bc | |||
| 9af88f530b | |||
| 954a3a0b9c | |||
| cf0031eef4 | |||
| bae97d133b | |||
| 4f4fa095e9 | |||
| 576fe29a1c | |||
| 50a8526252 | |||
| 5be081f0d9 | |||
| 112b018900 | |||
| 2c87248acc | |||
| e6551f36d0 | |||
| 88575207d3 | |||
| 4058e8bacc | |||
| dc37ac0b2f | |||
| f3355b7b06 | |||
| 110b003f86 | |||
| 1c870741af | |||
| 51134a7b79 | |||
| 7921d02f15 | |||
| f9c1a62f86 | |||
| 4fb4ff22a6 | |||
| 5d922e47f7 | |||
| bc7bc8e1d6 | |||
| 7b7863fa69 | |||
| 4a8ded6144 | |||
| 7eea186ea0 | |||
| 1067cd48e9 | |||
| 5903377c7a | |||
| ef232b4294 | |||
| 16d3155e4e | |||
| 248be37230 | |||
| 20cd50e2e7 | |||
| aaae02a573 | |||
| 2fa8ad59f9 | |||
| b926e3dde5 | |||
| 8f12ddef8e | |||
| 02d92a5513 | |||
| da4676a27e | |||
| 56d2fd74d9 | |||
| 52b6dd1533 | |||
| 3656fb017a | |||
| c1832e69da | |||
| c396e2239c | |||
| 99c13aae72 | |||
| 374b0f29cd | |||
| 0857948493 | |||
| d3363def5a | |||
| 2bc4631d41 | |||
| 86a01e810f | |||
| d84dacba45 | |||
| 89f67f45aa | |||
| 1d7651e19f | |||
| 540875d055 | |||
| 0043e716bc | |||
| 4c83ff8612 | |||
| 4c47d171d1 | |||
| 13c223cb2f | |||
| 7f2e6a23a9 | |||
| 32b1759f9d | |||
| e753201ea8 | |||
| 5cc23984d6 | |||
| a853baa1ef | |||
| 72a0975fd2 | |||
| 9333948786 | |||
| 79518165b9 | |||
| 39dc0663e2 | |||
| b1b3aede9c | |||
| 383570242d | |||
| be0420e2ee | |||
| 44805fee30 | |||
| bde30ae513 | |||
| 2e9cb9d29a | |||
| b645325d98 | |||
| fcb5bc8193 | |||
| 270b6e3444 | |||
| d41415da8a | |||
| 98d9032ce1 | |||
| 741426a8f6 | |||
| 67a8105001 | |||
| b2908c36a7 | |||
| 059ec02aaa | |||
| c353917324 | |||
| 426c2ba5b2 | |||
| a546aa2eec | |||
| a1990f18ef | |||
| 8d2ef9efe8 | |||
| f499321716 | |||
| 8f2f9d3d08 | |||
| 89ee56ed69 | |||
| 7ea8ea7f0a | |||
| d45250b531 | |||
| cecd63c9f2 | |||
| 1a16c4486c | |||
| 0d2aa4a617 | |||
| 19a4956b35 | |||
| f93c5dcf23 | |||
| 22a987837c | |||
| c6bfc43c7c | |||
| f23d1d4057 | |||
| 8c25e10349 | |||
| 475a460b6e | |||
| 9f1bf377ac | |||
| ec3bd695f3 | |||
| 26d7e0294c | |||
| 37be511e7c | |||
| da9dcf8ef7 | |||
| ee65d12cfe | |||
| b989fe2b0f | |||
| a429bdab98 | |||
| 7b6f15a8c4 | |||
| e8b6d6f62c | |||
| ae7b2e3829 | |||
| 52e24fe922 | |||
| 0c51eaa6f0 | |||
| 5c4bcc266e | |||
| 57dfa1557b | |||
| 12748c8425 | |||
| 901c4aae9f | |||
| 761e1f5cb5 | |||
| 874be4b0f0 | |||
| 4ec232ec6a | |||
| 3cacf33b58 | |||
| 35c7aaa325 | |||
| 331fb695a9 | |||
| 2d89f2de76 | |||
| 2910d40ad0 | |||
| e998027091 | |||
| 065a86dbf7 | |||
| 8a893ed82f | |||
| 3b85388c00 | |||
| a5eebeaea3 | |||
| 087d36b6e5 | |||
| 8e66f84d9f | |||
| ebce25e7b9 | |||
| 0afa12be00 | |||
| 1272fbf749 | |||
| 498e0d12d8 | |||
| 08cbafdeac | |||
| 7b9d66434b | |||
| 5649654bd5 | |||
| 71a93cd00e | |||
| a208bffde9 | |||
| cc89382bdc | |||
| 04bf1303c2 | |||
| 542cd89f8d | |||
| 490414af8d | |||
| 4df7f4237e | |||
| dad879ae99 | |||
| f0a8545516 | |||
| 67aea44be9 | |||
| ae3c9c36d4 | |||
| daed839963 | |||
| 9280eac530 | |||
| f597bba458 | |||
| 54d2128109 | |||
| eeae9616be | |||
| 10b1faa27f | |||
| 5cbd2c991b | |||
| 5866dee70a | |||
| c1ed31c01f | |||
| f92fbb037d | |||
| 934f6bd973 | |||
| 9be463a33b | |||
| 836bd9aad4 | |||
| 63e73da77b | |||
| f3b83353e7 | |||
| f1855ba03b | |||
| 5979de1b0e | |||
| d8f015100a | |||
| b3bca79c74 | |||
| 465bd9f5be | |||
| d3a94cbbe4 | |||
| de67f68127 | |||
| 0329e38af7 | |||
| b5c9d33a7f | |||
| d430e7feb5 | |||
| dd50f0d6da | |||
| 296da1a31b | |||
| ef0d6a6a8f | |||
| 24050cd891 | |||
| c303dca672 | |||
| 9e7f70ddab | |||
| b40bf0bf58 | |||
| a60ed2afc6 | |||
| cb03609eed | |||
| 926da7c331 | |||
| 01edd51f1a | |||
| 0a3eb4efac | |||
| 74ed9155a1 | |||
| e6e54c85e9 | |||
| 79875473a4 | |||
| fca0b1c6dd | |||
| f29dd7aac0 | |||
| ac9c42de1f | |||
| eddf18d9f2 | |||
| fa44bc2fb8 | |||
| 2232f4fbd9 | |||
| 6995ba729a | |||
| 49d62e0d49 | |||
| bc6d265d16 | |||
| aeaff0b308 | |||
| b0a9e1c532 | |||
| 802af00aea | |||
| f77f4743e2 | |||
| e9a53fb1ba | |||
| 4847ef9b3a | |||
| 5e304e4900 | |||
| a98b19c219 | |||
| 4d5b31c269 | |||
| 2e9f0b00e4 | |||
| 1bda18dfb0 | |||
| 58cbd74d66 | |||
| 5e1fd88ecb | |||
| 5b64744053 | |||
| 85f1f34c85 | |||
| 5c4db861ab | |||
| 1964efc04b | |||
| bcc1885779 | |||
| 5037cf7014 | |||
| 2bb6c9fbe4 | |||
| 172e3b12a2 | |||
| ec5978ac13 | |||
| 4c4faf547f | |||
| 418a1ffb39 | |||
| e87035545b | |||
| 11a786d55e | |||
| cac15c9ff3 | |||
| 69017ad364 | |||
| 34c01a4a02 | |||
| 20a594645a | |||
| 0baeccfd24 | |||
| 557caae4eb | |||
| 2d2955bc70 | |||
| 710e078327 | |||
| 7a80df2bbc | |||
| 577d9d6de6 | |||
| b92ef5be76 | |||
| 26aa7a8db9 | |||
| 1866371731 | |||
| 1905721bee | |||
| 8dc2432c92 | |||
| 436294e18c | |||
| cc99016319 | |||
| 39889df28a | |||
| ed7ba2f8bd | |||
| 19202892a7 | |||
| 6ebb04cff6 | |||
| b97a5d97bd | |||
| b7c8bfd263 | |||
| f0f28e3a4e | |||
| 78eac44451 | |||
| 57bdd314e4 | |||
| 9f29866371 | |||
| f00e699477 | |||
| b29f0b5d59 | |||
| c372f7bac5 | |||
| 7aa5da8b2e | |||
| 2fe9a6d323 | |||
| fc89ab2433 | |||
| fac8b5db4f | |||
| 97928e7e50 | |||
| 0dca43644d | |||
| a4e5cc84e0 | |||
| f8b220ec70 | |||
| 5123fa76c8 | |||
| 0105dfc1f3 | |||
| 75f484f534 | |||
| c9c457c268 | |||
| 8fca983968 | |||
| 1a445dc3fc | |||
| 00959494a6 | |||
| d5942d6a6f | |||
| 5b407159d5 | |||
| e3c3610af1 | |||
| 10610a60bc | |||
| f0abdc5c72 | |||
| 13069faafe | |||
| 3f51bef08c | |||
| f42636806d | |||
| 4043d93219 | |||
| 700ba226f7 | |||
| 1db7d40fc9 | |||
| 156a376c41 | |||
| 0ada42290c | |||
| 4e96b320ec | |||
| 6e91016520 | |||
| 20c30ac5e4 | |||
| a240818cf3 | |||
| ead49b0e44 | |||
| c457a17af4 | |||
| ba0f099ade | |||
| b75bb79414 | |||
| 2bc741e66a | |||
| 112de10a61 | |||
| d9b3406111 | |||
| 21de218e57 | |||
| 98cc1b062d | |||
| 06306ddd94 | |||
| 73de6ccc13 | |||
| ec3d11dd00 | |||
| d7d10cd3d4 | |||
| af20b75c55 | |||
| 1f02086d55 | |||
| 44c64196fb | |||
| e1009af391 | |||
| 4a36974d3b | |||
| 523a5947a3 | |||
| bddc038848 | |||
| f81e0a1d06 | |||
| af4c52b849 | |||
| 85db26a355 | |||
| 9e9b288017 | |||
| d3ee291624 | |||
| abb176bfc0 | |||
| f4d2786bb0 | |||
| dfa5b89d74 | |||
| dd4e8cbc7a |
+339
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
+19
-18
@@ -40,7 +40,7 @@
|
||||
}
|
||||
if (!empty($CFG->showcrondebugging)) {
|
||||
$CFG->debug = DEBUG_DEVELOPER;
|
||||
$CFG->displaydebug = true;
|
||||
$CFG->debugdisplay = true;
|
||||
}
|
||||
|
||||
/// extra safety
|
||||
@@ -245,7 +245,7 @@
|
||||
while ($assign = rs_fetch_next_record($rs)) {
|
||||
if ($context = get_context_instance(CONTEXT_COURSE, $assign->courseid)) {
|
||||
if (role_unassign(0, $assign->userid, 0, $context->id)) {
|
||||
mtrace("Deleted assignment for user $assign->userid from course $assign->courseid");
|
||||
mtrace("removing user $assign->userid from course $assign->courseid as they have not accessed the course for over $CFG->longtimenosee days");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -425,6 +425,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
/// Run the auth cron, if any
|
||||
/// before enrolments because it might add users that will be needed in enrol plugins
|
||||
$auths = get_enabled_auth_plugins();
|
||||
|
||||
mtrace("Running auth crons if required...");
|
||||
foreach ($auths as $auth) {
|
||||
$authplugin = get_auth_plugin($auth);
|
||||
if (method_exists($authplugin, 'cron')) {
|
||||
mtrace("Running cron for auth/$auth...");
|
||||
$authplugin->cron();
|
||||
if (!empty($authplugin->log)) {
|
||||
mtrace($authplugin->log);
|
||||
}
|
||||
}
|
||||
unset($authplugin);
|
||||
}
|
||||
|
||||
/// Run the enrolment cron, if any
|
||||
if (!($plugins = explode(',', $CFG->enrol_plugins_enabled))) {
|
||||
$plugins = array($CFG->enrol);
|
||||
@@ -441,22 +458,6 @@
|
||||
unset($enrol);
|
||||
}
|
||||
|
||||
/// Run the auth cron, if any
|
||||
$auths = get_enabled_auth_plugins();
|
||||
|
||||
mtrace("Running auth crons if required...");
|
||||
foreach ($auths as $auth) {
|
||||
$authplugin = get_auth_plugin($auth);
|
||||
if (method_exists($authplugin, 'cron')) {
|
||||
mtrace("Running cron for auth/$auth...");
|
||||
$authplugin->cron();
|
||||
if (!empty($authplugin->log)) {
|
||||
mtrace($authplugin->log);
|
||||
}
|
||||
}
|
||||
unset($authplugin);
|
||||
}
|
||||
|
||||
if (!empty($CFG->enablestats) and empty($CFG->disablestatsprocessing)) {
|
||||
require_once($CFG->dirroot.'/lib/statslib.php');
|
||||
// check we're not before our runtime
|
||||
|
||||
+27
-10
@@ -200,7 +200,7 @@
|
||||
<ON_OK message="questioncwqpfsok" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
<CUSTOM_CHECK file="lib/customcheckslib.php" function="php_check_register_globals" level="optional">
|
||||
<CUSTOM_CHECK file="lib/customcheckslib.php" function="php_check_register_globals" level="required">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="globalswarning" />
|
||||
</FEEDBACK>
|
||||
@@ -214,20 +214,20 @@
|
||||
</FEEDBACK>
|
||||
</UNICODE>
|
||||
<DATABASE level="required">
|
||||
<VENDOR name="mysql" version="4.1.16">
|
||||
<VENDOR name="mysql" version="5.0.25">
|
||||
<FEEDBACK>
|
||||
<ON_ERROR message="mysql416required" />
|
||||
</FEEDBACK>
|
||||
<BYPASS function="bypass_mysql416_reqs" message="mysql416bypassed" />
|
||||
</VENDOR>
|
||||
<VENDOR name="postgres" version="8.0" />
|
||||
<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="9.0" />
|
||||
<VENDOR name="oracle" version="10.0" />
|
||||
<VENDOR name="sqlite" version="2.0" />
|
||||
</DATABASE>
|
||||
<PHP version="5.2.4" level="required">
|
||||
<PHP version="5.2.8" level="required">
|
||||
</PHP>
|
||||
<PHP_EXTENSIONS>
|
||||
<PHP_EXTENSION name="iconv" level="optional">
|
||||
@@ -270,13 +270,30 @@
|
||||
<ON_ERROR message="ziprequired" />
|
||||
</FEEDBACK>
|
||||
</PHP_EXTENSION>
|
||||
</PHP_EXTENSIONS>
|
||||
<CUSTOM_CHECKS>
|
||||
<CUSTOM_CHECK file="lib/customcheckslib.php" function="php_check_register_globals" level="optional">
|
||||
<PHP_EXTENSION name="gd" level="optional">
|
||||
<FEEDBACK>
|
||||
<ON_CHECK message="globalswarning" />
|
||||
<ON_CHECK message="gdrecommended" />
|
||||
</FEEDBACK>
|
||||
</CUSTOM_CHECK>
|
||||
</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>
|
||||
<CUSTOM_CHECKS>
|
||||
</CUSTOM_CHECKS>
|
||||
</MOODLE>
|
||||
</COMPATIBILITY_MATRIX>
|
||||
|
||||
Executable
+275
@@ -0,0 +1,275 @@
|
||||
<?php
|
||||
|
||||
require_once('../config.php');
|
||||
/**
|
||||
* SCRIPT CONFIGURATION
|
||||
*/
|
||||
$starttimer = time()+microtime();
|
||||
|
||||
$settings = array();
|
||||
$settings['verbose'] = false;
|
||||
$settings['username'] = null;
|
||||
$settings['password'] = null;
|
||||
$settings['eolchar'] = '<br />'; // Character used to break lines
|
||||
|
||||
// Argument arrays: 0=>short name, 1=>long name
|
||||
$arguments = array(
|
||||
array('short'=>'u', 'long'=>'username', 'help' => 'Your moodle username', 'type'=>'STRING', 'default' => ''),
|
||||
array('short'=>'pw', 'long'=>'password', 'help' => 'Your moodle password', 'type'=>'STRING', 'default' => ''),
|
||||
array('short'=>'v', 'long' => 'verbose', 'help' => 'Display extra information about the process')
|
||||
);
|
||||
|
||||
// Building the USAGE output of the command line version
|
||||
if (isset($argv) && isset($argc)) {
|
||||
$help = "Moodle User Pix Fix. Restores user profile images that were not properly moved during 1.8.2 upgrade to newer versions.\n\n"
|
||||
. "Usage: {$argv[0]}; [OPTION] ...\n"
|
||||
. "Options:\n"
|
||||
. " -h, -?, -help, --help This output\n";
|
||||
|
||||
foreach ($arguments as $arg_array) {
|
||||
$equal = '';
|
||||
if (!empty($arg_array['type'])) {
|
||||
$equal = "={$arg_array['type']}";
|
||||
}
|
||||
|
||||
$padding1 = 5 - strlen($arg_array['short']);
|
||||
$padding2 = 30 - (strlen($arg_array['long']) + strlen($equal));
|
||||
$paddingstr1 = '';
|
||||
for ($i = 0; $i < $padding1; $i++) {
|
||||
$paddingstr1 .= ' ';
|
||||
}
|
||||
$paddingstr2 = '';
|
||||
for ($i = 0; $i < $padding2; $i++) {
|
||||
$paddingstr2 .= ' ';
|
||||
}
|
||||
|
||||
$help .= " -{$arg_array['short']},$paddingstr1--{$arg_array['long']}$equal$paddingstr2{$arg_array['help']}\n";
|
||||
}
|
||||
|
||||
$help .= "\nEmail nicolasconnault@gmail.com for any suggestions or bug reports.\n";
|
||||
|
||||
if ($argc == 1 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) {
|
||||
echo $help;
|
||||
die();
|
||||
|
||||
} else {
|
||||
|
||||
$settings['eolchar'] = "\n";
|
||||
$argv = arguments($argv);
|
||||
$argscount = 0;
|
||||
|
||||
foreach ($arguments as $arg_array) {
|
||||
$value = null;
|
||||
if (in_array($arg_array['short'], array_keys($argv))) {
|
||||
$value = $argv[$arg_array['short']];
|
||||
unset($argv[$arg_array['short']]);
|
||||
} elseif (in_array($arg_array['long'], array_keys($argv))) {
|
||||
$value = $argv[$arg_array['long']];
|
||||
unset($argv[$arg_array['long']]);
|
||||
}
|
||||
if (!is_null($value)) {
|
||||
$settings[$arg_array['long']] = $value;
|
||||
$argscount++;
|
||||
}
|
||||
}
|
||||
|
||||
// If some params are left in argv, it means they are not supported
|
||||
if ($argscount == 0 || count($argv) > 0) {
|
||||
echo $help;
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SCRIPT SETUP
|
||||
*/
|
||||
require_once($CFG->libdir . '/formslib.php');
|
||||
require_once($CFG->dirroot .'/course/lib.php');
|
||||
verbose("Loading libraries...");
|
||||
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
|
||||
/**
|
||||
* WEB INTERFACE FORM
|
||||
*/
|
||||
|
||||
class pixfix_form extends moodleform {
|
||||
function definition() {
|
||||
global $arguments;
|
||||
$mform =& $this->_form;
|
||||
|
||||
foreach ($arguments as $arg_array) {
|
||||
$type = 'advcheckbox';
|
||||
|
||||
$label = ucfirst(str_replace('-', ' ', $arg_array['long']));
|
||||
if (!empty($arg_array['type'])) {
|
||||
$type = 'text';
|
||||
}
|
||||
|
||||
if ($arg_array['long'] == 'password' || $arg_array['long'] == 'username') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$mform->addElement($type, $arg_array['long'], $label);
|
||||
|
||||
if (isset($arg_array['default'])) {
|
||||
$mform->setDefault($arg_array['long'], $arg_array['default']);
|
||||
}
|
||||
}
|
||||
$this->add_action_buttons(false, 'Restore Images');
|
||||
}
|
||||
|
||||
function definition_after_data() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$run_script = true;
|
||||
$web_interface = false;
|
||||
|
||||
// If eolchar is still <br />, load the web interface
|
||||
if ($settings['eolchar'] == '<br />') {
|
||||
print_header("User Pix-Fix");
|
||||
print_heading("User Pix-Fix");
|
||||
$mform = new pixfix_form();
|
||||
|
||||
if ($data = $mform->get_data(false)) {
|
||||
foreach ($arguments as $arg_array) {
|
||||
if (!empty($data->{$arg_array['long']})) {
|
||||
$settings[$arg_array['long']] = $data->{$arg_array['long']};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$run_script = false;
|
||||
}
|
||||
|
||||
if (!has_capability('moodle/site:doanything', $systemcontext)) {
|
||||
// If not logged in, give link to login page for current site
|
||||
notify("You must be logged in as administrator before using this script.");
|
||||
require_login();
|
||||
} else {
|
||||
$mform->display();
|
||||
}
|
||||
|
||||
$web_interface = true;
|
||||
}
|
||||
|
||||
if ($run_script) {
|
||||
|
||||
// User authentication
|
||||
if (!$web_interface) {
|
||||
if (empty($settings['username'])) {
|
||||
echo "You must enter a valid username for a moodle administrator account on this site.{$settings['eolchar']}";
|
||||
die();
|
||||
} elseif (empty($settings['password'])) {
|
||||
echo "You must enter a valid password for a moodle administrator account on this site.{$settings['eolchar']}";
|
||||
die();
|
||||
} else {
|
||||
if (!$user = authenticate_user_login($settings['username'], $settings['password'])) {
|
||||
echo "Invalid username or password!{$settings['eolchar']}";
|
||||
die();
|
||||
}
|
||||
$USER = complete_user_login($user);
|
||||
if (!has_capability('moodle/site:doanything', $systemcontext)) {
|
||||
echo "You do not have administration privileges on this Moodle site. These are required for running the restore script.{$settings['eolchar']}";
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Script code here
|
||||
|
||||
// Look for old moodledata/users directory
|
||||
$oldusersdir = $CFG->dataroot . '/users';
|
||||
|
||||
if (!file_exists($oldusersdir)) {
|
||||
notify('The old directory for user profile images ('.$oldusersdir.') does not exist. Pictures cannot be restored!');
|
||||
} else {
|
||||
// Find user profile images that are not yet in the new directory
|
||||
$folders = get_directory_list($oldusersdir, '', false, true, false);
|
||||
|
||||
$restored_count = 0;
|
||||
|
||||
foreach ($folders as $userid) {
|
||||
$olddir = $oldusersdir . '/' . $userid;
|
||||
$files = get_directory_list($olddir);
|
||||
|
||||
if (empty($files)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create new user directory
|
||||
if (!$newdir = make_user_directory($userid)) {
|
||||
// some weird directory - do not stop the upgrade, just ignore it
|
||||
continue;
|
||||
}
|
||||
|
||||
// Move contents of old directory to new one
|
||||
if (file_exists($olddir) && file_exists($newdir)) {
|
||||
$restored = false;
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (!file_exists($newdir . '/' . $file)) {
|
||||
copy($olddir . '/' . $file, $newdir . '/' . $file);
|
||||
verbose("Moved $olddir/$file into $newdir/$file");
|
||||
$restored = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($restored) {
|
||||
$restored_count++;
|
||||
}
|
||||
} else {
|
||||
notify("Could not move the contents of $olddir into $newdir!");
|
||||
$result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($settings['eolchar'] == '<br />') {
|
||||
print_box_start('generalbox centerpara');
|
||||
}
|
||||
if ($restored_count > 0) {
|
||||
echo "Successfully restored profile images for $restored_count users!" . $settings['eolchar'];
|
||||
} else {
|
||||
echo "Did not find any user profile images in need of restoring." . $settings['eolchar'];
|
||||
}
|
||||
if ($settings['eolchar'] == '<br />') {
|
||||
print_box_end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($settings['eolchar'] == '<br />') {
|
||||
print_footer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the standard $argv into an associative array taking var=val arguments into account
|
||||
* @param array $argv
|
||||
* @return array $_ARG
|
||||
*/
|
||||
function arguments($argv) {
|
||||
$_ARG = array();
|
||||
foreach ($argv as $arg) {
|
||||
if (ereg('--?([^=]+)=(.*)',$arg,$reg)) {
|
||||
$_ARG[$reg[1]] = $reg[2];
|
||||
} elseif(ereg('-([a-zA-Z0-9]+)',$arg,$reg)) {
|
||||
$_ARG[$reg[1]] = 'true';
|
||||
}
|
||||
}
|
||||
return $_ARG;
|
||||
}
|
||||
|
||||
/**
|
||||
* If verbose is switched on, prints a string terminated by the global eolchar string.
|
||||
* @param string $string The string to STDOUT
|
||||
*/
|
||||
function verbose($string) {
|
||||
global $settings;
|
||||
if ($settings['verbose'] && !$settings['quiet']) {
|
||||
echo $string . $settings['eolchar'];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
+9
-5
@@ -363,7 +363,11 @@ class problem_000008 extends problem_base {
|
||||
}
|
||||
$oldmemlimit = get_real_size($oldmemlimit);
|
||||
//now lets change the memory limit to something unique below 128M==134217728
|
||||
@ini_set('memory_limit', 134217720);
|
||||
if (empty($CFG->extramemorylimit)) {
|
||||
raise_memory_limit('128M');
|
||||
} else {
|
||||
raise_memory_limit($CFG->extramemorylimit);
|
||||
}
|
||||
$testmemlimit = get_real_size(@ini_get('memory_limit'));
|
||||
//verify the change had any effect at all
|
||||
if ($oldmemlimit == $testmemlimit) {
|
||||
@@ -374,7 +378,7 @@ class problem_000008 extends problem_base {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ini_set('memory_limit', $oldmemlimit);
|
||||
reduce_memory_limit($oldmemlimit);
|
||||
return false;
|
||||
}
|
||||
function severity() {
|
||||
@@ -660,10 +664,10 @@ class problem_000015 extends problem_base {
|
||||
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 qc
|
||||
DELETE FROM ' . $CFG->prefix . 'question_categories
|
||||
WHERE
|
||||
NOT EXISTS (SELECT * FROM ' . $CFG->prefix . 'question q WHERE q.category = qc.id)
|
||||
AND NOT EXISTS (SELECT * FROM ' . $CFG->prefix . 'context con WHERE qc.contextid = con.id)
|
||||
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>';
|
||||
}
|
||||
|
||||
+25
-13
@@ -61,6 +61,10 @@
|
||||
error("The PHP server variable 'file_uploads' is not turned On - $documentationlink");
|
||||
}
|
||||
|
||||
if (is_float_problem()) {
|
||||
print_error('phpfloatproblem', 'admin', '', $documentationlink);
|
||||
}
|
||||
|
||||
if (empty($CFG->prefix) && $CFG->dbfamily != 'mysql') { //Enforce prefixes for everybody but mysql
|
||||
error('$CFG->prefix can\'t be empty for your target DB (' . $CFG->dbtype . ')');
|
||||
}
|
||||
@@ -286,17 +290,22 @@
|
||||
|
||||
require_once($CFG->libdir.'/environmentlib.php');
|
||||
print_heading(get_string('environment', 'admin'));
|
||||
remove_dir($CFG->dataroot . '/environment'); /// Always delete downloaded env. info to force use of the released one. MDL-9796
|
||||
if (!check_moodle_environment($release, $environment_results, true)) {
|
||||
print_box_start('generalbox', 'notice'); // MDL-8330
|
||||
print_string('langpackwillbeupdated', 'admin');
|
||||
print_box_end();
|
||||
if (empty($CFG->skiplangupgrade)) {
|
||||
print_box_start('generalbox', 'notice'); // MDL-8330
|
||||
print_string('langpackwillbeupdated', 'admin');
|
||||
print_box_end();
|
||||
}
|
||||
notice_yesno(get_string('environmenterrorupgrade', 'admin'),
|
||||
'index.php?confirmupgrade=1&confirmrelease=1', 'index.php');
|
||||
'index.php?confirmupgrade=1&confirmrelease=1', 'index.php');
|
||||
} else {
|
||||
notify(get_string('environmentok', 'admin'), 'notifysuccess');
|
||||
print_box_start('generalbox', 'notice'); // MDL-8330
|
||||
print_string('langpackwillbeupdated', 'admin');
|
||||
print_box_end();
|
||||
if (empty($CFG->skiplangupgrade)) {
|
||||
print_box_start('generalbox', 'notice'); // MDL-8330
|
||||
print_string('langpackwillbeupdated', 'admin');
|
||||
print_box_end();
|
||||
}
|
||||
echo '<form action="index.php"><div>';
|
||||
echo '<input type="hidden" name="confirmupgrade" value="1" />';
|
||||
echo '<input type="hidden" name="confirmrelease" value="1" />';
|
||||
@@ -319,7 +328,7 @@
|
||||
print_plugin_tables();
|
||||
echo "<br />";
|
||||
echo '<div class="continuebutton">';
|
||||
print_single_button('index.php', array('confirmupgrade' => 1, 'confirmrelease' => 1), get_string('reload'), 'get');
|
||||
echo '<a href="index.php?confirmupgrade=1&confirmrelease=1" title="'.get_string('reload').'" ><img src="'.$CFG->pixpath.'/i/reload.gif" alt="" /> '.get_string('reload').'</a>';
|
||||
echo '</div><br />';
|
||||
echo '<form action="index.php"><div>';
|
||||
echo '<input type="hidden" name="confirmupgrade" value="1" />';
|
||||
@@ -344,7 +353,9 @@
|
||||
upgrade_log_start();
|
||||
|
||||
/// Upgrade current language pack if we can
|
||||
upgrade_language_pack();
|
||||
if (empty($CFG->skiplangupgrade)) {
|
||||
upgrade_language_pack();
|
||||
}
|
||||
|
||||
print_heading($strdatabasechecking);
|
||||
$db->debug=true;
|
||||
@@ -467,6 +478,9 @@
|
||||
/// Check all message output plugins and upgrade if necessary
|
||||
upgrade_plugins('message','message/output',"$CFG->wwwroot/$CFG->admin/index.php");
|
||||
|
||||
/// Check all course report plugins and upgrade if necessary
|
||||
upgrade_plugins('coursereport', 'course/report', "$CFG->wwwroot/$CFG->admin/index.php");
|
||||
|
||||
/// Check all admin report plugins and upgrade if necessary
|
||||
upgrade_plugins('report', $CFG->admin.'/report', "$CFG->wwwroot/$CFG->admin/index.php");
|
||||
|
||||
@@ -540,10 +554,8 @@
|
||||
set_config('adminblocks_initialised', 1);
|
||||
}
|
||||
|
||||
/// Define the unique site ID code if it isn't already
|
||||
if (empty($CFG->siteidentifier)) { // Unique site identification code
|
||||
set_config('siteidentifier', random_string(32).$_SERVER['HTTP_HOST']);
|
||||
}
|
||||
/// Define the unique site ID code if it isn't already set. This getter does that as a side-effect.
|
||||
get_site_identifier();
|
||||
|
||||
/// Check if the guest user exists. If not, create one.
|
||||
if (! record_exists("user", "username", "guest")) {
|
||||
|
||||
+4
-4
@@ -822,7 +822,7 @@
|
||||
echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
|
||||
echo '<input type="hidden" name="currentfile" value="'.$currentfile.'" />';
|
||||
echo '<input type="hidden" name="mode" value="helpfiles" />';
|
||||
echo "<div align=\"center\">\n";
|
||||
echo "<div class='mdl-align'>\n";
|
||||
echo "<textarea rows=\"$fileeditorrows\" cols=\"$fileeditorcols\" name=\"filedata\">";
|
||||
if (file_exists("$saveto/$currentfile")) {
|
||||
echo htmlspecialchars(file_get_contents("$saveto/$currentfile"));
|
||||
@@ -830,7 +830,7 @@
|
||||
echo ($filetemplate);
|
||||
}
|
||||
echo "</textarea>\n</div>\n";
|
||||
echo '<div align="center"><input type="submit" value="'.get_string('savechanges').'" /></div>';
|
||||
echo '<div class="mdl-align"><input type="submit" value="'.get_string('savechanges').'" /></div>';
|
||||
echo '</form>';
|
||||
$preview_url = lang_help_preview_url($currentfile, !$uselocal);
|
||||
if ($preview_url) {
|
||||
@@ -842,7 +842,7 @@
|
||||
if (is_readable("$altdir/$currentfile")) {
|
||||
// show the content of the same help file in alternative location
|
||||
echo '<fieldset><legend>'.$straltdirtitle.'</legend>';
|
||||
echo "<div align=\"center\">\n";
|
||||
echo "<div class='mdl-align'>\n";
|
||||
echo "<textarea rows=\"$fileeditorrows\" cols=\"$fileeditorcols\" name=\"\">";
|
||||
if (file_exists("$altdir/$currentfile")) {
|
||||
echo htmlspecialchars(file_get_contents("$altdir/$currentfile"));
|
||||
@@ -869,7 +869,7 @@
|
||||
echo '<fieldset><legend>'.$strlangmasterenglish;
|
||||
helpbutton('langpackages', $strlangmasterenglish);
|
||||
echo '</legend>';
|
||||
echo "<div align=\"center\">\n<textarea rows=\"$fileeditorrows\" cols=\"$fileeditorcols\" name=\"\">";
|
||||
echo "<div class='mdl-align'>\n<textarea rows=\"$fileeditorrows\" cols=\"$fileeditorcols\" name=\"\">";
|
||||
echo htmlspecialchars(file_get_contents($ensrc));
|
||||
echo "</textarea>\n</div>\n";
|
||||
$preview_url = lang_help_preview_url($currentfile, true, 'en_utf8'); // do not display en_utf8_local
|
||||
|
||||
+2
-2
@@ -112,7 +112,7 @@
|
||||
for ($a=0; $a < count($pathparts)-1 ; $a++) {
|
||||
$checkpath .= "/".$pathparts[$a];
|
||||
if(!file_exists($checkpath)){
|
||||
if(!mkdir($checkpath)){
|
||||
if(!mkdir($checkpath, $CFG->directorypermissions)){
|
||||
echo ("Cannot create directory: $checkpath");
|
||||
}
|
||||
}
|
||||
@@ -186,7 +186,7 @@ $langdir/$currentfile")."</font></p>";
|
||||
if ($preview_url) {
|
||||
link_to_popup_window($preview_url, 'popup', get_string('preview'));
|
||||
}
|
||||
echo '<div align="center"><input type="submit" value="'.get_string('savechanges').': lang/'.$currentlang.'/'.$currentfile.'" /></div>';
|
||||
echo '<div class="mdl-align"><input type="submit" value="'.get_string('savechanges').': lang/'.$currentlang.'/'.$currentfile.'" /></div>';
|
||||
echo '</form>';
|
||||
}
|
||||
|
||||
|
||||
+11
-4
@@ -11,6 +11,13 @@
|
||||
|
||||
admin_externalpage_setup('langimport');
|
||||
|
||||
if (!empty($CFG->skiplangupgrade)) {
|
||||
admin_externalpage_print_header();
|
||||
print_box(get_string('langimportdisabled', 'admin'));
|
||||
print_footer();
|
||||
die;
|
||||
}
|
||||
|
||||
$mode = optional_param('mode', 0, PARAM_INT); //phase
|
||||
$pack = optional_param('pack', array(), PARAM_FILE); //pack to install
|
||||
$displaylang = $pack;
|
||||
@@ -43,8 +50,8 @@
|
||||
|
||||
if (confirm_sesskey() and !empty($pack)) {
|
||||
set_time_limit(0);
|
||||
@mkdir ($CFG->dataroot.'/temp/'); //make it in case it's a fresh install, it might not be there
|
||||
@mkdir ($CFG->dataroot.'/lang/');
|
||||
@mkdir ($CFG->dataroot.'/temp/', $CFG->directorypermissions); //make it in case it's a fresh install, it might not be there
|
||||
@mkdir ($CFG->dataroot.'/lang/', $CFG->directorypermissions);
|
||||
|
||||
if (is_array($pack)) {
|
||||
$packs = $pack;
|
||||
@@ -160,8 +167,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
@mkdir ($CFG->dataroot.'/temp/');
|
||||
@mkdir ($CFG->dataroot.'/lang/');
|
||||
@mkdir ($CFG->dataroot.'/temp/', $CFG->directorypermissions);
|
||||
@mkdir ($CFG->dataroot.'/lang/', $CFG->directorypermissions);
|
||||
foreach ($packs as $pack){ //for each of the remaining in the list, we
|
||||
if ($pack == 'en_utf8') { // no update for en_utf8
|
||||
continue;
|
||||
|
||||
+13
-4
@@ -33,29 +33,36 @@
|
||||
|
||||
admin_externalpage_print_header();
|
||||
|
||||
print_heading(get_string('sitemaintenancemode', 'admin'));
|
||||
|
||||
print_box_start();
|
||||
|
||||
/// Print the appropriate form
|
||||
|
||||
if (file_exists($filename)) { // We are in maintenance mode
|
||||
echo '<div style="margin-left:auto;margin-right:auto">';
|
||||
echo '<div class="buttons">';
|
||||
echo '<p>'.get_string('sitemaintenanceon', 'admin').'</p>';
|
||||
echo '<form action="maintenance.php" method="post">';
|
||||
echo '<div>';
|
||||
echo '<input type="hidden" name="action" value="disable" />';
|
||||
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
|
||||
echo '<p><input type="submit" value="'.get_string('disable').'" /></p>';
|
||||
echo '</div>';
|
||||
echo '</form>';
|
||||
echo '</div>';
|
||||
} else { // We are not in maintenance mode
|
||||
$usehtmleditor = can_use_html_editor();
|
||||
|
||||
echo '<div style="text-align:center;margin-left:auto;margin-right:auto">';
|
||||
echo '<div class="buttons">';
|
||||
echo '<form action="maintenance.php" method="post">';
|
||||
echo '<div>';
|
||||
echo '<input type="hidden" name="action" value="enable" />';
|
||||
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
|
||||
echo '<p><input type="submit" value="'.get_string('enable').'" /></p>';
|
||||
echo '<p>'.get_string('optionalmaintenancemessage', 'admin').':</p>';
|
||||
echo '<table><tr><td>';
|
||||
echo '<div class="editor" style="width:600px;">'; // contains the editor
|
||||
print_textarea($usehtmleditor, 20, 50, 600, 400, "text");
|
||||
echo '</td></tr></table>';
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
echo '</form>';
|
||||
echo '</div>';
|
||||
@@ -65,5 +72,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
print_box_end();
|
||||
|
||||
admin_externalpage_print_footer();
|
||||
?>
|
||||
|
||||
@@ -123,6 +123,13 @@
|
||||
if (!delete_records("course_modules", "module", $module->id)) {
|
||||
notify("Error occurred while deleting all $strmodulename records in course_modules table");
|
||||
}
|
||||
if ($coursemods) {
|
||||
foreach ($coursemods as $coursemod) {
|
||||
if (!delete_context(CONTEXT_MODULE, $coursemod->id)) {
|
||||
notify("Could not delete the context for $strmodulename with id = $coursemod->id");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then delete all the logs
|
||||
if (!delete_records("log", "module", $module->name)) {
|
||||
|
||||
+39
-6
@@ -20,8 +20,11 @@ page_map_class(PAGE_ADMIN, 'page_admin');
|
||||
|
||||
class page_admin extends page_base {
|
||||
|
||||
var $section;
|
||||
var $section = '';
|
||||
var $visiblepathtosection;
|
||||
var $extraurlparams = array();
|
||||
var $extrabutton = '';
|
||||
var $url = '';
|
||||
|
||||
// hack alert!
|
||||
// this function works around the inability to store the section name
|
||||
@@ -62,6 +65,9 @@ class page_admin extends page_base {
|
||||
|
||||
function url_get_path() {
|
||||
global $CFG;
|
||||
if (!empty($this->url)) {
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
$adminroot =& admin_get_root(false, false); //settings not required - only pages
|
||||
|
||||
@@ -73,8 +79,29 @@ class page_admin extends page_base {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to pass extra HTML that is added after the turn blocks editing on/off button.
|
||||
*
|
||||
* @param string $extrabutton HTML code.
|
||||
*/
|
||||
function set_extra_button($extrabutton) {
|
||||
$this->extrabutton = $extrabutton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to pass extra URL parameters that, for example, the blocks editing controls need to reload the current page accurately.
|
||||
*
|
||||
* @param array $extraurlparams paramname => value array.
|
||||
*/
|
||||
function set_extra_url_params($extraurlparams, $actualurl = '') {
|
||||
$this->extraurlparams = $extraurlparams;
|
||||
if (!empty($actualurl)) {
|
||||
$this->url = $actualurl;
|
||||
}
|
||||
}
|
||||
|
||||
function url_get_parameters() { // only handles parameters relevant to the admin pagetype
|
||||
return array('section' => (isset($this->section) ? $this->section : ''));
|
||||
return array_merge($this->extraurlparams, array('section' => $this->section));
|
||||
}
|
||||
|
||||
function blocks_get_positions() {
|
||||
@@ -107,13 +134,19 @@ class page_admin extends page_base {
|
||||
|
||||
// The search page currently doesn't handle block editing
|
||||
if ($this->section != 'search' and $this->user_allowed_editing()) {
|
||||
$buttons = '<div><form '.$CFG->frametarget.' method="get" action="' . $this->url_get_path() . '">'.
|
||||
'<div><input type="hidden" name="adminedit" value="'.($this->user_is_editing()?'off':'on').'" />'.
|
||||
'<input type="hidden" name="section" value="'.$this->section.'" />'.
|
||||
'<input type="submit" value="'.get_string($this->user_is_editing()?'blockseditoff':'blocksediton').'" /></div></form></div>';
|
||||
$options = $this->url_get_parameters();
|
||||
if ($this->user_is_editing()) {
|
||||
$caption = get_string('blockseditoff');
|
||||
$options['adminedit'] = 'off';
|
||||
} else {
|
||||
$caption = get_string('blocksediton');
|
||||
$options['adminedit'] = 'on';
|
||||
}
|
||||
$buttons = print_single_button($this->url_get_path(), $options, $caption, 'get', '', true);
|
||||
} else {
|
||||
$buttons = ' ';
|
||||
}
|
||||
$buttons .= $this->extrabutton;
|
||||
|
||||
$navlinks = array();
|
||||
foreach ($this->visiblepathtosection as $element) {
|
||||
|
||||
+1
-7
@@ -23,13 +23,7 @@
|
||||
$admin->country = $CFG->country;
|
||||
}
|
||||
|
||||
if (empty($CFG->siteidentifier)) { // Unique site identification code
|
||||
set_config('siteidentifier', random_string(32).$_SERVER['HTTP_HOST']);
|
||||
}
|
||||
|
||||
|
||||
/// Print headings
|
||||
|
||||
$stradministration = get_string("administration");
|
||||
$strregistration = get_string("registration");
|
||||
$strregistrationinfo = get_string("registrationinfo");
|
||||
@@ -54,7 +48,7 @@
|
||||
echo "<!-- Together they form a key. If any of these change between updates then the entry -->\n";
|
||||
echo "<!-- is flagged as a new entry and will be manually checked by the list maintainer -->\n";
|
||||
echo "<input type=\"hidden\" name=\"url\" value=\"$CFG->wwwroot\" />\n";
|
||||
echo "<input type=\"hidden\" name=\"secret\" value=\"$CFG->siteidentifier\" />\n";
|
||||
echo "<input type=\"hidden\" name=\"secret\" value=\"" . get_site_identifier() . "\" />\n";
|
||||
echo "<input type=\"hidden\" name=\"host\" value=\"".$_SERVER["HTTP_HOST"]."\" />\n";
|
||||
echo "<input type=\"hidden\" name=\"lang\" value=\"".current_language()."\" />\n";
|
||||
|
||||
|
||||
+15
-1
@@ -19,7 +19,7 @@ print_heading('Search and replace text throughout the whole database');
|
||||
if (!data_submitted() or !$search or !$replace or !confirm_sesskey()) { /// Print a form
|
||||
|
||||
print_simple_box_start('center');
|
||||
echo '<div align="center">';
|
||||
echo '<div class="mdl-align">';
|
||||
echo '<form action="replace.php" method="post">';
|
||||
echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
|
||||
echo 'Search whole database for: <input type="text" name="search" /><br />';
|
||||
@@ -40,6 +40,20 @@ if (!db_replace($search, $replace)) {
|
||||
|
||||
print_simple_box_end();
|
||||
|
||||
/// Try to replace some well-known serialised contents (html blocks)
|
||||
notify('Replacing in html blocks...');
|
||||
$sql = "SELECT bi.*
|
||||
FROM {$CFG->prefix}block_instance bi
|
||||
JOIN {$CFG->prefix}block b ON b.id = bi.blockid
|
||||
WHERE b.name = 'html'";
|
||||
if ($instances = get_records_sql($sql)) {
|
||||
foreach ($instances as $instance) {
|
||||
$blockobject = block_instance('html', $instance);
|
||||
$blockobject->config->text = str_replace($search, $replace, $blockobject->config->text);
|
||||
$blockobject->instance_config_commit($blockobject->pinned);
|
||||
}
|
||||
}
|
||||
|
||||
/// Rebuild course cache which might be incorrect now
|
||||
notify('Rebuilding course cache...');
|
||||
rebuild_course_cache();
|
||||
|
||||
@@ -5,13 +5,10 @@
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->dirroot.'/backup/lib.php');
|
||||
|
||||
admin_externalpage_setup('reportbackups');
|
||||
|
||||
admin_externalpage_print_header();
|
||||
|
||||
$courseid = optional_param('courseid', 0, PARAM_INT);
|
||||
|
||||
require_capability('moodle/site:backup', get_context_instance(CONTEXT_SYSTEM));
|
||||
admin_externalpage_setup('reportbackups');
|
||||
admin_externalpage_print_header();
|
||||
|
||||
/// Scheduled backups are disabled by the server admin
|
||||
if (!empty($CFG->disablescheduledbackups)) {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php // $Id$
|
||||
$ADMIN->add('reports', new admin_externalpage('reportbackups', get_string('backups', 'admin'), "$CFG->wwwroot/$CFG->admin/report/backups/index.php",'moodle/site:backup'));
|
||||
?>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php // $Id$
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 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 //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$report_courseoverview_capabilities = array(
|
||||
|
||||
'report/courseoverview:view' => array(
|
||||
'riskbitmask' => RISK_PERSONAL,
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'legacy' => array(
|
||||
'teacher' => CAP_ALLOW,
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
'admin' => CAP_ALLOW
|
||||
),
|
||||
|
||||
'clonepermissionsfrom' => 'moodle/site:viewreports',
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
@@ -4,18 +4,19 @@
|
||||
require_once($CFG->dirroot.'/lib/statslib.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('reportcourseoverview');
|
||||
|
||||
admin_externalpage_print_header();
|
||||
|
||||
$report = optional_param('report', STATS_REPORT_ACTIVE_COURSES, PARAM_INT);
|
||||
$time = optional_param('time', 0, PARAM_INT);
|
||||
$numcourses = optional_param('numcourses', 20, PARAM_INT);
|
||||
|
||||
require_capability('moodle/site:viewreports', get_context_instance(CONTEXT_SYSTEM)); // needed?
|
||||
admin_externalpage_setup('reportcourseoverview');
|
||||
admin_externalpage_print_header();
|
||||
|
||||
if (empty($CFG->enablestats)) {
|
||||
redirect("$CFG->wwwroot/$CFG->admin/settings.php?section=stats", get_string('mustenablestats', 'admin'), 3);
|
||||
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 {
|
||||
error("Stats is not enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
$course = get_site();
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
require_login();
|
||||
|
||||
require_capability('moodle/site:viewreports', get_context_instance(CONTEXT_SYSTEM));
|
||||
require_capability('report/courseoverview:view', get_context_instance(CONTEXT_SYSTEM));
|
||||
|
||||
stats_check_uptodate();
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
$courses = get_records_sql($sql, 0, $numcourses);
|
||||
|
||||
if (empty($courses)) {
|
||||
print_error('statsnodata', "", $CFG->wwwroot.'/'.$CFG->admin.'/report/course/index.php');
|
||||
print_error('statsnodata', "", $CFG->wwwroot.'/'.$CFG->admin.'/report/courseoverview/index.php');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php // $Id$
|
||||
$ADMIN->add('reports', new admin_externalpage('reportcourseoverview', get_string('courseoverview', 'admin'), "$CFG->wwwroot/$CFG->admin/report/courseoverview/index.php",'report/courseoverview:view'));
|
||||
?>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?PHP // $Id$
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 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 = 2007101503;
|
||||
$plugin->requires = 2007101532;
|
||||
|
||||
?>
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php // $Id$
|
||||
|
||||
require_once('../../../config.php');
|
||||
require_once($CFG->dirroot.'/course/lib.php');
|
||||
require_once($CFG->dirroot.'/course/report/log/lib.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('reportlog');
|
||||
|
||||
admin_externalpage_print_header();
|
||||
|
||||
|
||||
$course = get_site();
|
||||
|
||||
print_heading(get_string('chooselogs') .':');
|
||||
|
||||
print_mnet_log_selector_form($CFG->mnet_localhost_id, $course);
|
||||
|
||||
echo '<br />';
|
||||
print_heading(get_string('chooselivelogs') .':');
|
||||
|
||||
$heading = link_to_popup_window('/course/report/log/live.php?id='. $course->id,
|
||||
'livelog', get_string('livelogs'),
|
||||
500, 800, '', 'none', true);
|
||||
|
||||
print_heading($heading, 'center', 3);
|
||||
|
||||
|
||||
admin_externalpage_print_footer();
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php // $Id$
|
||||
// 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'));
|
||||
?>
|
||||
@@ -5,8 +5,8 @@
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('reportquestion');
|
||||
|
||||
admin_externalpage_print_header();
|
||||
|
||||
print_heading(get_string('adminreport', 'question'));
|
||||
|
||||
$probstr = '';
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php // $Id$
|
||||
$ADMIN->add('reports', new admin_externalpage('reportquestion', get_string('question', 'admin'), "$CFG->wwwroot/$CFG->admin/report/question/index.php", 'moodle/site:config'));
|
||||
?>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php // $Id$
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 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 //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$report_security_capabilities = array(
|
||||
|
||||
'report/security:view' => array(
|
||||
'riskbitmask' => RISK_CONFIG,
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'legacy' => array(
|
||||
'admin' => CAP_ALLOW
|
||||
),
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php //$Id$
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 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('../../../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_FILE); // 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('128M');
|
||||
@set_time_limit(0);
|
||||
|
||||
// Print the header.
|
||||
admin_externalpage_setup('reportsecurity');
|
||||
admin_externalpage_print_header();
|
||||
|
||||
print_heading(get_string('reportsecurity', 'report_security'));
|
||||
|
||||
echo '<div id="timewarning">'.get_string('timewarning', 'report_security').'</div>';
|
||||
while(@ob_end_flush());
|
||||
@flush();
|
||||
|
||||
$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 object();
|
||||
$table->head = array($strissue, $strstatus, $strdesc, $strconfig);
|
||||
$table->size = array('30%', '10%', '50%', '10%' );
|
||||
$table->align = array('left', 'left', 'left', 'left');
|
||||
$table->width = '90%';
|
||||
$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;
|
||||
|
||||
$CFG->pagepath = "report/security/$issue"; // help link in footer
|
||||
|
||||
$table->data[] = $row;
|
||||
|
||||
print_table($table);
|
||||
|
||||
print_box($result->details, 'generalbox boxwidthnormal boxaligncenter'); // TODO: add proper css
|
||||
|
||||
print_continue($url);
|
||||
|
||||
} else {
|
||||
report_security_hide_timearning();
|
||||
|
||||
$table = new object();
|
||||
$table->head = array($strissue, $strstatus, $strdesc);
|
||||
$table->size = array('30%', '10%', '60%' );
|
||||
$table->align = array('left', 'left', 'left');
|
||||
$table->width = '90%';
|
||||
$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;
|
||||
}
|
||||
print_table($table);
|
||||
}
|
||||
|
||||
print_footer();
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
<?php //$Id$
|
||||
|
||||
$ADMIN->add('reports', new admin_externalpage('reportsecurity', get_string('reportsecurity', 'report_security'), "$CFG->wwwroot/$CFG->admin/report/security/index.php",'report/security:view'));
|
||||
@@ -0,0 +1,29 @@
|
||||
<?PHP // $Id$
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 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 = 2007101500;
|
||||
$plugin->requires = 2007101533;
|
||||
|
||||
?>
|
||||
Executable
+373
@@ -0,0 +1,373 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Spam Cleaner
|
||||
*
|
||||
* Helps an admin to clean up spam in Moodle
|
||||
*
|
||||
* @version $Id$
|
||||
* @authors Dongsheng Cai, Martin Dougiamas, Amr Hourani
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
|
||||
// Configuration
|
||||
|
||||
// List of known spammy keywords, please add more here
|
||||
|
||||
$autokeywords = array(
|
||||
"<img",
|
||||
"fuck",
|
||||
"casino",
|
||||
"porn",
|
||||
"xxx",
|
||||
"cialis",
|
||||
"viagra",
|
||||
"poker",
|
||||
"warcraft"
|
||||
);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
require_once('../../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
require_js(array('yui_dom-event', 'yui_connection', 'yui_json'));
|
||||
|
||||
$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');
|
||||
|
||||
// Implement some AJAX calls
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
admin_externalpage_print_header();
|
||||
|
||||
// Print headers and things
|
||||
|
||||
print_spamcleaner_javascript();
|
||||
|
||||
print_box(get_string('spamcleanerintro', 'report_spamcleaner'));
|
||||
|
||||
print_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
|
||||
print_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;
|
||||
|
||||
if (!is_array($keywords)) {
|
||||
$keywords = array($keywords); // Make it into an array
|
||||
}
|
||||
|
||||
$like = sql_ilike();
|
||||
|
||||
$keywordfull = array();
|
||||
foreach ($keywords as $keyword) {
|
||||
$keyword = addslashes($keyword); // Just to be safe
|
||||
$keywordfull[] = " description $like '%$keyword%' ";
|
||||
$keywordfull2[] = " p.summary $like '%$keyword%' ";
|
||||
}
|
||||
$conditions = '( '.implode(' OR ', $keywordfull).' )';
|
||||
$conditions2 = '( '.implode(' OR ', $keywordfull2).' )';
|
||||
|
||||
$sql = "SELECT * FROM {$CFG->prefix}user WHERE deleted = 0 AND id <> {$USER->id} AND $conditions"; // Exclude oneself
|
||||
$sql2= "SELECT u.*, p.summary FROM {$CFG->prefix}user AS u, {$CFG->prefix}post AS p WHERE $conditions2 AND u.deleted = 0 AND u.id=p.userid AND u.id <> {$USER->id}";
|
||||
$spamusers_desc = get_recordset_sql($sql);
|
||||
$spamusers_blog = get_recordset_sql($sql2);
|
||||
|
||||
$keywordlist = implode(', ', $keywords);
|
||||
print_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) {
|
||||
while ($user = rs_fetch_next_record($rs)) {
|
||||
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->pixpath.')#', $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 object; // 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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
$html .= '<td align="left">'.format_text($user->description, FORMAT_MOODLE).'</td>';
|
||||
$html .= '<td width="100px" align="center">';
|
||||
$html .= '<button onclick="del_user(this,'.$user->id.')">'.get_string('deleteuser', 'admin').'</button><br />';
|
||||
$html .= '<button onclick="ignore_user(this,'.$user->id.')">'.get_string('ignore', 'admin').'</button>';
|
||||
$html .= '</td>';
|
||||
$html .= '</tr>';
|
||||
return $html;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function print_spamcleaner_javascript() {
|
||||
|
||||
$sesskey = sesskey();
|
||||
|
||||
?>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var row = null;
|
||||
var delall_cb = {
|
||||
success: function(o){
|
||||
try {
|
||||
var resp = YAHOO.lang.JSON.parse(o.responseText);
|
||||
} catch(e) {
|
||||
alert('<?php echo get_string('spaminvalidresult', 'report_spamcleaner');?>');
|
||||
return;
|
||||
}
|
||||
if(resp == true){
|
||||
window.location.href=window.location.href;
|
||||
}
|
||||
}
|
||||
}
|
||||
function init() {
|
||||
YAHOO.util.Event.addListener("removeall_btn", "click", function(){
|
||||
var yes = confirm('<?php echo get_string('spamdeleteallconfirm', 'report_spamcleaner');?>');
|
||||
if(yes){
|
||||
var cObj = YAHOO.util.Connect.asyncRequest('POST', '<?php echo me();?>?delall=yes&sesskey=<?php echo $sesskey;?>', delall_cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
var del_cb = {
|
||||
success: function(o) {
|
||||
try {
|
||||
var resp = YAHOO.lang.JSON.parse(o.responseText);
|
||||
} catch(e) {
|
||||
alert('<?php echo get_string('spaminvalidresult', 'report_spamcleaner');?>');
|
||||
return;
|
||||
}
|
||||
if(row) {
|
||||
if(resp == true){
|
||||
while(row.tagName != 'TR') {
|
||||
row = row.parentNode;
|
||||
}
|
||||
row.parentNode.removeChild(row);
|
||||
row = null;
|
||||
} else {
|
||||
alert('<?php echo get_string('spamcannotdelete', 'report_spamcleaner');?>');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var ignore_cb = {
|
||||
success: function(o){
|
||||
try {
|
||||
var resp = YAHOO.lang.JSON.parse(o.responseText);
|
||||
} catch(e) {
|
||||
alert('<?php echo get_string('spaminvalidresult', 'report_spamcleaner');?>');
|
||||
return;
|
||||
}
|
||||
if(row) {
|
||||
if(resp == true){
|
||||
while(row.tagName != 'TR') {
|
||||
row = row.parentNode;
|
||||
}
|
||||
row.parentNode.removeChild(row);
|
||||
row = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function del_user(obj, id) {
|
||||
var yes = confirm('<?php echo get_string('spamdeleteconfirm', 'report_spamcleaner');?>');
|
||||
if(yes){
|
||||
row = obj;
|
||||
var cObj = YAHOO.util.Connect.asyncRequest('POST', '<?php echo me();?>?del=yes&sesskey=<?php echo $sesskey;?>&id='+id, del_cb);
|
||||
}
|
||||
}
|
||||
function ignore_user(obj, id) {
|
||||
row = obj;
|
||||
var cObj = YAHOO.util.Connect.asyncRequest('POST', '<?php echo me();?>?ignore=yes&sesskey=<?php echo $sesskey;?>&id='+id, ignore_cb);
|
||||
}
|
||||
YAHOO.util.Event.onDOMReady(init);
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
admin_externalpage_print_footer();
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
// spam cleaner
|
||||
$ADMIN->add('reports', new admin_externalpage('reportspamcleaner', get_string('spamcleaner','report_spamcleaner'), "$CFG->wwwroot/$CFG->admin/report/spamcleaner/index.php", 'moodle/site:config'));
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
<?php // $Id$
|
||||
|
||||
require_once('../../../config.php');
|
||||
require_once($CFG->dirroot.'/lib/statslib.php');
|
||||
require_once($CFG->dirroot.'/course/report/stats/lib.php');
|
||||
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('reportstats');
|
||||
|
||||
admin_externalpage_print_header();
|
||||
|
||||
|
||||
$courseid = optional_param('course', SITEID, PARAM_INT);
|
||||
$report = optional_param('report', 0, PARAM_INT);
|
||||
$time = optional_param('time', 0, PARAM_INT);
|
||||
$mode = optional_param('mode', STATS_MODE_GENERAL, PARAM_INT);
|
||||
$userid = optional_param('userid', 0, PARAM_INT);
|
||||
$roleid = 0;
|
||||
|
||||
if ($report > 50) {
|
||||
$roleid = substr($report,1);
|
||||
$report = 5;
|
||||
}
|
||||
|
||||
if ($report == STATS_REPORT_USER_LOGINS) {
|
||||
$courseid = SITEID; //override
|
||||
}
|
||||
|
||||
if ($mode == STATS_MODE_RANKED) {
|
||||
redirect($CFG->wwwroot.'/'.$CFG->admin.'/report/stats/index.php?time='.$time, '', 3);
|
||||
}
|
||||
|
||||
if (!$course = get_record("course","id",$courseid)) {
|
||||
error("That's an invalid course id");
|
||||
}
|
||||
|
||||
if (!empty($userid)) {
|
||||
if (!$user = get_record('user','id',$userid)) {
|
||||
error("That's an invalid user id");
|
||||
}
|
||||
}
|
||||
|
||||
require_login();
|
||||
|
||||
if (empty($CFG->enablestats)) {
|
||||
redirect("$CFG->wwwroot/$CFG->admin/settings.php?section=stats", get_string('mustenablestats', 'admin'), 3);
|
||||
}
|
||||
|
||||
require_capability('moodle/site:viewreports', get_context_instance(CONTEXT_SYSTEM));
|
||||
|
||||
add_to_log($course->id, "course", "report stats", "report/stats/index.php?course=$course->id", $course->id);
|
||||
|
||||
stats_check_uptodate($course->id);
|
||||
|
||||
|
||||
// $strreports = get_string("reports");
|
||||
// $strstats = get_string('stats');
|
||||
//
|
||||
// $menu = report_stats_mode_menu($course, $mode, $time); // add 4th $url parameter if uncommented!
|
||||
//
|
||||
//
|
||||
// $crumb = "<a href=\"{$CFG->wwwroot}/admin\">".get_string('administration')."</a> ->
|
||||
// <a href=\"{$CFG->wwwroot}/admin/report.php\">$strreports</a> ->
|
||||
// $strstats";
|
||||
|
||||
// print_header("$course->shortname: $strstats", "$course->fullname",
|
||||
// $crumb, '', '', true, ' ', $menu);
|
||||
|
||||
|
||||
require_once($CFG->dirroot.'/course/report/stats/report.php');
|
||||
|
||||
admin_externalpage_print_footer();
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php // $Id$
|
||||
// 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'));
|
||||
?>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php // $Id$
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 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 //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
$report_unittest_capabilities = array(
|
||||
|
||||
'report/unittest:view' => array(
|
||||
'riskbitmask' => RISK_DATALOSS,
|
||||
'captype' => 'read',
|
||||
'contextlevel' => CONTEXT_SYSTEM,
|
||||
'legacy' => array(
|
||||
'admin' => CAP_ALLOW
|
||||
),
|
||||
|
||||
'clonepermissionsfrom' => 'moodle/site:config',
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
@@ -16,14 +16,6 @@ require_once($CFG->libdir.'/simpletestlib.php');
|
||||
require_once('ex_simple_test.php');
|
||||
require_once('ex_reporter.php');
|
||||
|
||||
require_login();
|
||||
require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
|
||||
|
||||
/* The UNITTEST constant can be checked elsewhere if you need to know
|
||||
* when your code is being run as part of a unit test. */
|
||||
define('UNITTEST', true);
|
||||
$langfile = 'simpletest';
|
||||
|
||||
// CGI arguments
|
||||
$path = optional_param('path', null, PARAM_PATH);
|
||||
$showpasses = optional_param('showpasses', false, PARAM_BOOL);
|
||||
@@ -31,10 +23,17 @@ $showsearch = optional_param('showsearch', false, PARAM_BOOL);
|
||||
$thorough = optional_param('thorough', false, PARAM_BOOL);
|
||||
|
||||
// Print the header.
|
||||
admin_externalpage_setup('reportsimpletest');
|
||||
$strtitle = get_string('unittests', $langfile);
|
||||
admin_externalpage_setup('reportunittest', '', array('showpasses' => $showpasses,
|
||||
'showsearch' => $showsearch, 'thorough' => $thorough));
|
||||
admin_externalpage_print_header();
|
||||
|
||||
/* The UNITTEST constant can be checked elsewhere if you need to know
|
||||
* when your code is being run as part of a unit test. */
|
||||
define('UNITTEST', true);
|
||||
$langfile = 'simpletest';
|
||||
|
||||
$strtitle = get_string('unittests', $langfile);
|
||||
|
||||
if (!is_null($path)) {
|
||||
// Create the group of tests.
|
||||
$test =& new AutoGroupTest($showsearch, $thorough);
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php //$Id$
|
||||
$ADMIN->add('reports', new admin_externalpage('reportunittest', get_string('simpletest', 'admin'), "$CFG->wwwroot/$CFG->admin/report/unittest/index.php", 'report/unittest:view'));
|
||||
?>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?PHP // $Id$
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// 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 = 2007101501;
|
||||
$plugin->requires = 2007101532;
|
||||
|
||||
?>
|
||||
@@ -10,8 +10,7 @@
|
||||
require_once('../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('defineroles');
|
||||
|
||||
admin_externalpage_setup('defineroles', '', array(), $CFG->wwwroot . '/' . $CFG->admin . '/roles/allowassign.php');
|
||||
|
||||
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
require_capability('moodle/role:manage', $sitecontext);
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
require_once('../../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('defineroles');
|
||||
|
||||
admin_externalpage_setup('defineroles', '', array(), $CFG->wwwroot . '/' . $CFG->admin . '/roles/allowoverride.php');
|
||||
|
||||
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
require_capability('moodle/role:manage', $sitecontext);
|
||||
|
||||
+20
-9
@@ -144,11 +144,11 @@
|
||||
$currenttab = 'assign';
|
||||
include_once($CFG->dirroot.'/user/tabs.php');
|
||||
} else if ($context->contextlevel == CONTEXT_SYSTEM) {
|
||||
admin_externalpage_setup('assignroles');
|
||||
admin_externalpage_print_header();
|
||||
admin_externalpage_setup('assignroles', '', array('contextid' => $contextid, 'roleid' => $roleid));
|
||||
admin_externalpage_print_header('');
|
||||
} else if ($context->contextlevel==CONTEXT_COURSE and $context->instanceid == SITEID) {
|
||||
admin_externalpage_setup('frontpageroles');
|
||||
admin_externalpage_print_header();
|
||||
admin_externalpage_setup('frontpageroles', '', array('contextid' => $contextid, 'roleid' => $roleid));
|
||||
admin_externalpage_print_header('');
|
||||
$currenttab = 'assign';
|
||||
include_once('tabs.php');
|
||||
} else {
|
||||
@@ -290,7 +290,7 @@
|
||||
$selectsql = "";
|
||||
}
|
||||
|
||||
if ($context->contextlevel > CONTEXT_COURSE) { // mod or block (or group?)
|
||||
if ($context->contextlevel > CONTEXT_COURSE && !is_inside_frontpage($context)) { // mod or block (or group?)
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
@@ -395,6 +395,12 @@
|
||||
notify($msg);
|
||||
print_simple_box_end();
|
||||
}
|
||||
|
||||
//Back to Assign Roles button
|
||||
echo "<br/>";
|
||||
echo "<div class='continuebutton'>";
|
||||
print_single_button('assign.php', array('contextid' => $contextid), get_string('assignrolesin', 'role', print_context_name($context)));
|
||||
echo "</div>";
|
||||
|
||||
} else { // Print overview table
|
||||
|
||||
@@ -429,7 +435,8 @@
|
||||
$rolehodlernames[$roleid] = '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Print overview table
|
||||
$table->tablealign = 'center';
|
||||
$table->cellpadding = 5;
|
||||
@@ -452,10 +459,14 @@
|
||||
}
|
||||
$table->data[] = $row;
|
||||
}
|
||||
|
||||
print_table($table);
|
||||
|
||||
//Continue to Course Button
|
||||
echo "<br/>";
|
||||
echo "<div class='continuebutton'>";
|
||||
print_single_button($CFG->wwwroot.'/course/view.php', array('id' => $courseid), get_string('continuetocourse'));
|
||||
echo "</div>";
|
||||
}
|
||||
|
||||
|
||||
print_footer($course);
|
||||
|
||||
?>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<?php if ($action == 'view') { ?>
|
||||
<tr valign="top">
|
||||
<td align="right"><?php print_string('name') ?>:</td>
|
||||
<td><?php p($role->name); ?></td>
|
||||
<td><?php p(format_string($role->name)); ?></td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td align="right"><?php print_string('shortname') ?>:</td>
|
||||
@@ -32,11 +32,11 @@
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td align="right"><?php print_string('description') ?>:</td>
|
||||
<td><?php p($role->description); $usehtmleditor = false; ?></td>
|
||||
<td><?php p(format_text($role->description, FORMAT_HTML)); $usehtmleditor = false; ?></td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td align="right"><?php print_string('legacytype', 'role') ?>:</td>
|
||||
<td><?php
|
||||
<td><?php
|
||||
$usehtmleditor = false;
|
||||
if (empty($role->legacytype)) {
|
||||
print_string('none');
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
|
||||
admin_externalpage_setup('defineroles');
|
||||
|
||||
$roleid = optional_param('roleid', 0, PARAM_INT); // if set, we are editing a role
|
||||
$name = optional_param('name', '', PARAM_MULTILANG); // new role name
|
||||
$shortname = optional_param('shortname', '', PARAM_RAW); // new role shortname, special cleaning before storage
|
||||
@@ -14,6 +12,8 @@
|
||||
$confirm = optional_param('confirm', 0, PARAM_BOOL);
|
||||
$cancel = optional_param('cancel', 0, PARAM_BOOL);
|
||||
|
||||
admin_externalpage_setup('defineroles', '', array('roleid' => $roleid));
|
||||
|
||||
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
|
||||
require_capability('moodle/role:manage', $sitecontext);
|
||||
@@ -414,7 +414,7 @@
|
||||
|
||||
/// print UI now
|
||||
|
||||
admin_externalpage_print_header();
|
||||
admin_externalpage_print_header('');
|
||||
|
||||
$currenttab = 'manage';
|
||||
include_once('managetabs.php');
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
include_once($CFG->dirroot.'/user/tabs.php');
|
||||
} else if ($context->contextlevel==CONTEXT_COURSE and $context->instanceid == SITEID) {
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
admin_externalpage_setup('frontpageroles');
|
||||
admin_externalpage_setup('frontpageroles', '', array('contextid' => $contextid, 'roleid' => $roleid), $CFG->wwwroot . '/' . $CFG->admin . '/roles/override.php');
|
||||
admin_externalpage_print_header();
|
||||
$currenttab = 'override';
|
||||
include_once('tabs.php');
|
||||
|
||||
@@ -48,16 +48,13 @@ if ($currenttab != 'update') {
|
||||
|
||||
require_login($course);
|
||||
$navlinks[] = array('name' => get_string('roles'),
|
||||
'link' => "$CFG->wwwroot/admin/roles/assign.php?contextid=$context->id",
|
||||
'link' => "$CFG->wwwroot/$CFG->admin/roles/assign.php?contextid=$context->id",
|
||||
'type' => 'misc');
|
||||
$navigation = build_navigation($navlinks);
|
||||
print_header($streditcoursesettings, $course->fullname, $navigation);
|
||||
}
|
||||
break;
|
||||
|
||||
case CONTEXT_GROUP:
|
||||
break;
|
||||
|
||||
case CONTEXT_MODULE:
|
||||
// get module type?
|
||||
if (!$cm = get_record('course_modules','id',$context->instanceid)) {
|
||||
|
||||
@@ -44,6 +44,8 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$temp->add(new admin_setting_special_calendar_weekend());
|
||||
$temp->add(new admin_setting_configtext('calendar_lookahead',get_string('configlookahead','admin'),get_string('helpupcominglookahead', 'admin'),21,PARAM_INT));
|
||||
$temp->add(new admin_setting_configtext('calendar_maxevents',get_string('configmaxevents','admin'),get_string('helpupcomingmaxevents', 'admin'),10,PARAM_INT));
|
||||
$temp->add(new admin_setting_configcheckbox('enablecalendarexport', get_string('enablecalendarexport', 'admin'), get_string('configenablecalendarexport','admin'), 1));
|
||||
$temp->add(new admin_setting_configtext('calendar_exportsalt', get_string('calendarexportsalt','admin'), get_string('configcalendarexportsalt', 'admin'), random_string(60)));
|
||||
$ADMIN->add('appearance', $temp);
|
||||
|
||||
// "htmleditor" settingpage
|
||||
@@ -75,6 +77,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
$temp = new admin_settingpage('mymoodle', get_string('mymoodle', 'admin'));
|
||||
$temp->add(new admin_setting_configcheckbox('mymoodleredirect', get_string('mymoodleredirect', 'admin'), get_string('configmymoodleredirect', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configtext('mycoursesperpage', get_string('mycoursesperpage', 'admin'), get_string('configmycoursesperpage', 'admin'), 21, PARAM_INT));
|
||||
$ADMIN->add('appearance', $temp);
|
||||
|
||||
// new CFG variable for coursemanager (what roles to display)
|
||||
|
||||
@@ -4,19 +4,64 @@
|
||||
|
||||
if ($hassiteconfig
|
||||
or has_capability('moodle/site:backup', $systemcontext)
|
||||
or has_capability('moodle/category:update', $systemcontext)) { // speedup for non-admins, add all caps used on this page
|
||||
or has_capability('moodle/category:manage', $systemcontext)
|
||||
or has_capability('moodle/course:create', $systemcontext)
|
||||
or has_capability('moodle/site:approvecourse', $systemcontext)) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
|
||||
$ADMIN->add('courses', new admin_externalpage('coursemgmt', get_string('coursemgmt', 'admin'), $CFG->wwwroot . '/course/index.php?categoryedit=on','moodle/category:update'));
|
||||
$ADMIN->add('courses', new admin_externalpage('coursemgmt', get_string('coursemgmt', 'admin'), $CFG->wwwroot . '/course/index.php?categoryedit=on',
|
||||
array('moodle/category:manage', 'moodle/course:create')));
|
||||
|
||||
$ADMIN->add('courses', new admin_enrolment_page());
|
||||
|
||||
/// Course Default Settings Page
|
||||
/// NOTE: these settings must be applied after all other settings because they depend on them
|
||||
/// NOTE: these are a subset of the complete defaults available in 2.0
|
||||
///general course settings
|
||||
$temp = new admin_settingpage('coursesettings', get_string('coursesettings'));
|
||||
$courseformats = get_list_of_plugins('course/format');
|
||||
$formcourseformats = array();
|
||||
foreach ($courseformats as $courseformat) {
|
||||
$formcourseformats["$courseformat"] = get_string("format$courseformat","format_$courseformat");
|
||||
if ($formcourseformats["$courseformat"]=="[[format$courseformat]]") {
|
||||
$formcourseformats["$courseformat"] = get_string("format$courseformat");
|
||||
}
|
||||
}
|
||||
$temp->add(new admin_setting_configselect('moodlecourse/format', get_string('format'), get_string('coursehelpformat'), 'weeks',$formcourseformats));
|
||||
for ($i=1; $i<=52; $i++) {
|
||||
$sectionmenu[$i] = "$i";
|
||||
}
|
||||
$temp->add(new admin_setting_configselect('moodlecourse/numsections', get_string('numberweeks'), get_string('coursehelpnumberweeks'), 10, $sectionmenu));
|
||||
$choices = array();
|
||||
$choices['0'] = get_string('hiddensectionscollapsed');
|
||||
$choices['1'] = get_string('hiddensectionsinvisible');
|
||||
$temp->add(new admin_setting_configselect('moodlecourse/hiddensections', get_string('hiddensections'), get_string('coursehelphiddensections'), 0,$choices));
|
||||
$options = range(0, 10);
|
||||
$temp->add(new admin_setting_configselect('moodlecourse/newsitems', get_string('newsitemsnumber'), get_string('coursehelpnewsitemsnumber'), 5,$options));
|
||||
$temp->add(new admin_setting_configselect('moodlecourse/showgrades', get_string('showgrades'), get_string('coursehelpshowgrades'), 1,array(0 => get_string('no'), 1 => get_string('yes'))));
|
||||
$temp->add(new admin_setting_configselect('moodlecourse/showreports', get_string('showreports'), '', 0,array(0 => get_string('no'), 1 => get_string('yes'))));
|
||||
if (isset($CFG->maxbytes)) {
|
||||
$choices = get_max_upload_sizes($CFG->maxbytes);
|
||||
} else {
|
||||
$choices = get_max_upload_sizes();
|
||||
}
|
||||
$temp->add(new admin_setting_configselect('moodlecourse/maxbytes', get_string('maximumupload'), get_string('coursehelpmaximumupload'), key($choices), $choices));
|
||||
$temp->add(new admin_setting_configselect('moodlecourse/metacourse', get_string('metacourse'), get_string('coursehelpmetacourse'), 0,array(0 => get_string('no'), 1 => get_string('yes'))));
|
||||
|
||||
$ADMIN->add('courses', $temp);
|
||||
|
||||
// "courserequests" settingpage
|
||||
$temp = new admin_settingpage('courserequest', get_string('courserequest'));
|
||||
$temp->add(new admin_setting_configcheckbox('enablecourserequests', get_string('enablecourserequests', 'admin'), get_string('configenablecourserequests', 'admin'), 0));
|
||||
$temp->add(new admin_settings_coursecat_select('defaultrequestcategory', get_string('defaultrequestcategory', 'admin'), get_string('configdefaultrequestcategory', 'admin'), 1));
|
||||
$temp->add(new admin_setting_users_with_capability('courserequestnotify', get_string('courserequestnotify', 'admin'), get_string('configcourserequestnotify2', 'admin'), array(), 'moodle/site:approvecourse'));
|
||||
$ADMIN->add('courses', $temp);
|
||||
|
||||
// Pending course requests.
|
||||
if (!empty($CFG->enablecourserequests)) {
|
||||
$ADMIN->add('courses', new admin_externalpage('coursespending', get_string('pendingrequests'),
|
||||
$CFG->wwwroot . '/course/pending.php', array('moodle/site:approvecourse')));
|
||||
}
|
||||
|
||||
// "backups" settingpage
|
||||
if (!empty($CFG->backup_version)) {
|
||||
$bi = array();
|
||||
@@ -29,6 +74,7 @@ if ($hassiteconfig
|
||||
$bi[] = new admin_setting_configcheckbox('backup_sche_userfiles', get_string('userfiles'), get_string('backupuserfileshelp'), 0);
|
||||
$bi[] = new admin_setting_configcheckbox('backup_sche_coursefiles', get_string('coursefiles'), get_string('backupcoursefileshelp'), 0);
|
||||
$bi[] = new admin_setting_configcheckbox('backup_sche_sitefiles', get_string('sitefiles'), get_string('backupsitefileshelp'), 0);
|
||||
$bi[] = new admin_setting_configcheckbox('backup_sche_gradebook_history', get_string('gradebookhistories', 'grades'), get_string('backupgradebookhistoryhelp'), 0);
|
||||
$bi[] = new admin_setting_configcheckbox('backup_sche_messages', get_string('messages', 'message'), get_string('backupmessageshelp','message'), 0);
|
||||
$bi[] = new admin_setting_configcheckbox('backup_sche_blogs', get_string('blogs', 'blog'), get_string('backupblogshelp','blog'), 0);
|
||||
$bi[] = new admin_setting_configselect('backup_sche_keep', get_string('keep'),
|
||||
|
||||
@@ -26,6 +26,14 @@ if (get_site()) { //do not use during installation
|
||||
$temp->add(new admin_setting_special_frontpagedesc());
|
||||
$temp->add(new admin_setting_courselist_frontpage(false)); // non-loggedin version of the setting (that's what the parameter is for :) )
|
||||
$temp->add(new admin_setting_courselist_frontpage(true)); // loggedin version of the setting
|
||||
|
||||
$options = array();
|
||||
$options[] = get_string('unlimited');
|
||||
for ($i=1; $i<100; $i++) {
|
||||
$options[$i] = $i;
|
||||
}
|
||||
$temp->add(new admin_setting_configselect('maxcategorydepth', get_string('configsitemaxcategorydepth','admin'), get_string('configsitemaxcategorydepthhelp','admin'), 0, $options));
|
||||
|
||||
$temp->add(new admin_setting_sitesetcheckbox('numsections', get_string('sitesection'), get_string('sitesectionhelp','admin'), 1));
|
||||
$temp->add(new admin_setting_sitesetselect('newsitems', get_string('newsitemsnumber'), '', 3,
|
||||
array('0' => '0',
|
||||
|
||||
+33
-11
@@ -5,11 +5,23 @@
|
||||
if (has_capability('moodle/grade:manage', $systemcontext)
|
||||
or has_capability('moodle/grade:manageletters', $systemcontext)) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
require_once $CFG->libdir.'/grade/constants.php';
|
||||
$display_types = array(GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_PERCENTAGE => get_string('percentage', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_LETTER => get_string('letter', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_REAL_PERCENTAGE => get_string('realpercentage', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_REAL_LETTER => get_string('realletter', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_LETTER_REAL => get_string('letterreal', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE => get_string('letterpercentage', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER => get_string('percentageletter', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_PERCENTAGE_REAL => get_string('percentagereal', 'grades')
|
||||
);
|
||||
asort($display_types);
|
||||
|
||||
// General settings
|
||||
|
||||
$temp = new admin_settingpage('gradessettings', get_string('generalsettings', 'grades'), 'moodle/grade:manage');
|
||||
if ($ADMIN->fulltree) {
|
||||
require_once $CFG->libdir.'/grade/constants.php';
|
||||
|
||||
// new CFG variable for gradebook (what roles to display)
|
||||
$temp->add(new admin_setting_special_gradebookroles());
|
||||
@@ -32,10 +44,7 @@ if (has_capability('moodle/grade:manage', $systemcontext)
|
||||
$temp->add(new admin_setting_configcheckbox('gradepublishing', get_string('gradepublishing', 'grades'), get_string('configgradepublishing', 'grades'), 0));
|
||||
|
||||
$temp->add(new admin_setting_configselect('grade_export_displaytype', get_string('gradeexportdisplaytype', 'grades'),
|
||||
get_string('configgradeexportdisplaytype', 'grades'), GRADE_DISPLAY_TYPE_REAL,
|
||||
array(GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_PERCENTAGE => get_string('percentage', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_LETTER => get_string('letter', 'grades'))));
|
||||
get_string('configgradeexportdisplaytype', 'grades'), GRADE_DISPLAY_TYPE_REAL, $display_types));
|
||||
|
||||
$temp->add(new admin_setting_configselect('grade_export_decimalpoints', get_string('gradeexportdecimalpoints', 'grades'),
|
||||
get_string('configexportdecimalpoints', 'grades'), 2,
|
||||
@@ -45,8 +54,14 @@ if (has_capability('moodle/grade:manage', $systemcontext)
|
||||
'3' => '3',
|
||||
'4' => '4',
|
||||
'5' => '5')));
|
||||
$temp->add(new admin_setting_configselect('grade_navmethod', get_string('navmethod', 'grades'), null, 0,
|
||||
array(GRADE_NAVMETHOD_DROPDOWN => get_string('dropdown', 'grades'),
|
||||
GRADE_NAVMETHOD_TABS => get_string('tabs', 'grades'),
|
||||
GRADE_NAVMETHOD_COMBO => get_string('combo', 'grades'))));
|
||||
|
||||
$temp->add(new admin_setting_special_gradeexport());
|
||||
|
||||
$temp->add(new admin_setting_special_gradelimiting());
|
||||
}
|
||||
$ADMIN->add('grades', $temp);
|
||||
|
||||
@@ -67,9 +82,17 @@ if (has_capability('moodle/grade:manage', $systemcontext)
|
||||
GRADE_AGGREGATE_MAX =>get_string('aggregatemax', 'grades'),
|
||||
GRADE_AGGREGATE_MODE =>get_string('aggregatemode', 'grades'),
|
||||
GRADE_AGGREGATE_SUM =>get_string('aggregatesum', 'grades'));
|
||||
|
||||
$defaultvisible = array(GRADE_AGGREGATE_MEAN, GRADE_AGGREGATE_WEIGHTED_MEAN, GRADE_AGGREGATE_WEIGHTED_MEAN2,
|
||||
GRADE_AGGREGATE_EXTRACREDIT_MEAN, GRADE_AGGREGATE_MEDIAN, GRADE_AGGREGATE_MIN,
|
||||
GRADE_AGGREGATE_MAX, GRADE_AGGREGATE_MODE, GRADE_AGGREGATE_SUM);
|
||||
|
||||
$defaults = array('value'=>GRADE_AGGREGATE_WEIGHTED_MEAN2, 'forced'=>false, 'adv'=>false);
|
||||
$temp->add(new admin_setting_gradecat_combo('grade_aggregation', get_string('aggregation', 'grades'), get_string('aggregationhelp', 'grades'), $defaults, $options));
|
||||
|
||||
$temp->add(new admin_setting_configmultiselect('grade_aggregations_visible', get_string('aggregationsvisible', 'grades'),
|
||||
get_string('aggregationsvisiblehelp', 'grades'), $defaultvisible, $options));
|
||||
|
||||
$options = array(0 => get_string('no'), 1 => get_string('yes'));
|
||||
|
||||
$defaults = array('value'=>1, 'forced'=>false, 'adv'=>true);
|
||||
@@ -101,10 +124,7 @@ if (has_capability('moodle/grade:manage', $systemcontext)
|
||||
$temp = new admin_settingpage('gradeitemsettings', get_string('gradeitemsettings', 'grades'), 'moodle/grade:manage');
|
||||
if ($ADMIN->fulltree) {
|
||||
$temp->add(new admin_setting_configselect('grade_displaytype', get_string('gradedisplaytype', 'grades'),
|
||||
get_string('configgradedisplaytype', 'grades'), GRADE_DISPLAY_TYPE_REAL,
|
||||
array(GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_PERCENTAGE => get_string('percentage', 'grades'),
|
||||
GRADE_DISPLAY_TYPE_LETTER => get_string('letter', 'grades'))));
|
||||
get_string('configgradedisplaytype', 'grades'), GRADE_DISPLAY_TYPE_REAL, $display_types));
|
||||
|
||||
$temp->add(new admin_setting_configselect('grade_decimalpoints', get_string('decimalpoints', 'grades'),
|
||||
get_string('configdecimalpoints', 'grades'), 2,
|
||||
@@ -142,8 +162,10 @@ if (has_capability('moodle/grade:manage', $systemcontext)
|
||||
|
||||
$scales = new admin_externalpage('scales', get_string('scales'), $CFG->wwwroot.'/grade/edit/scale/index.php', 'moodle/grade:manage');
|
||||
$ADMIN->add('grades', $scales);
|
||||
$outcomes = new admin_externalpage('outcomes', get_string('outcomes', 'grades'), $CFG->wwwroot.'/grade/edit/outcome/index.php', 'moodle/grade:manage');
|
||||
$ADMIN->add('grades', $outcomes);
|
||||
if (!empty($CFG->enableoutcomes)) {
|
||||
$outcomes = new admin_externalpage('outcomes', get_string('outcomes', 'grades'), $CFG->wwwroot.'/grade/edit/outcome/index.php', 'moodle/grade:manage');
|
||||
$ADMIN->add('grades', $outcomes);
|
||||
}
|
||||
$letters = new admin_externalpage('letters', get_string('letters', 'grades'), $CFG->wwwroot.'/grade/edit/letter/edit.php', 'moodle/grade:manageletters');
|
||||
$ADMIN->add('grades', $letters);
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$item->set_updatedcallback('reset_text_filters_cache');
|
||||
$temp->add($item);
|
||||
$temp->add(new admin_setting_configcheckbox('enablegroupings', get_string('enablegroupings', 'admin'), get_string('configenablegroupings', 'admin'), 0));
|
||||
$rqsetting = new admin_setting_configcheckbox('selectmanual', get_string('selectmanualquestions', 'qtype_random'), get_string('configselectmanualquestions', 'qtype_random'), 0);
|
||||
$rqsetting->plugin = 'qtype_random';
|
||||
$temp->add($rqsetting);
|
||||
$temp->add(new admin_setting_configcheckbox('experimentalsplitrestore', get_string('experimentalsplitrestore', 'admin'), get_string('configexperimentalsplitrestore', 'admin'), 0));
|
||||
|
||||
$ADMIN->add('misc', $temp);
|
||||
|
||||
|
||||
@@ -138,9 +138,28 @@ if ($hassiteconfig) {
|
||||
$ADMIN->add('filtersettings', $settings);
|
||||
|
||||
} else if (file_exists("$CFG->dirroot/$filterfull/filterconfig.html")) {
|
||||
$ADMIN->add('filtersettings', new admin_externalpage('filtersetting'.str_replace('/', '', $filterfull), $strfiltername, "$CFG->wwwroot/$CFG->admin/filter.php?filter=$filterfull", !in_array($filterfull, $activefilters)));
|
||||
$ADMIN->add('filtersettings', new admin_externalpage('filtersetting'.str_replace('/', '', $filterfull), $strfiltername, "$CFG->wwwroot/$CFG->admin/filter.php?filter=$filterfull", 'moodle/site:config', !in_array($filterfull, $activefilters)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
/// Now add reports
|
||||
|
||||
foreach (get_list_of_plugins($CFG->admin.'/report') as $plugin) {
|
||||
$settings_path = "$CFG->dirroot/$CFG->admin/report/$plugin/settings.php";
|
||||
if (file_exists($settings_path)) {
|
||||
include($settings_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
$index_path = "$CFG->dirroot/$CFG->admin/report/$plugin/index.php";
|
||||
if (!file_exists($index_path)) {
|
||||
continue;
|
||||
}
|
||||
// old style 3rd party plugin without settings.php
|
||||
$www_path = "$CFG->wwwroot/$CFG->admin/report/$plugin/index.php";
|
||||
$reportname = get_string($plugin, 'report_' . $plugin);
|
||||
$ADMIN->add('reports', new admin_externalpage('report'.$plugin, $reportname, $www_path, 'moodle/site:viewreports'));
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
0 => get_string('disableblogs','blog'))));
|
||||
$temp->add(new admin_setting_configcheckbox('usetags', get_string('usetags','admin'),get_string('configusetags', 'admin'),'1'));
|
||||
$temp->add(new admin_setting_configcheckbox('keeptagnamecase', get_string('keeptagnamecase','admin'),get_string('configkeeptagnamecase', 'admin'),'1'));
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('profilesforenrolledusersonly', get_string('profilesforenrolledusersonly','admin'),get_string('configprofilesforenrolledusersonly', 'admin'),'1'));
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('cronclionly', get_string('cronclionly', 'admin'), get_string('configcronclionly', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configpasswordunmask('cronremotepassword', get_string('cronremotepassword', 'admin'), get_string('configcronremotepassword', 'admin'), ''));
|
||||
|
||||
@@ -51,6 +54,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
|
||||
$temp->add(new admin_setting_configtext('minpasswordnonalphanum', get_string('minpasswordnonalphanum', 'admin'), get_string('configminpasswordnonalphanum', 'admin'), 1, PARAM_INT));
|
||||
$temp->add(new admin_setting_configcheckbox('disableuserimages', get_string('disableuserimages', 'admin'), get_string('configdisableuserimages', 'admin'), 0));
|
||||
$temp->add(new admin_setting_configcheckbox('emailchangeconfirmation', get_string('emailchangeconfirmation', 'admin'), get_string('configemailchangeconfirmation', 'admin'), 1));
|
||||
$temp->add(new admin_setting_configcheckbox('enablenotes', get_string('enablenotes', 'notes'), get_string('configenablenotes', 'notes'), 1));
|
||||
$ADMIN->add('security', $temp);
|
||||
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ $temp->add(new admin_setting_configselect('sessiontimeout', get_string('sessiont
|
||||
300 => get_string('numminutes', '', 5))));
|
||||
$temp->add(new admin_setting_configtext('sessioncookie', get_string('sessioncookie', 'admin'), get_string('configsessioncookie', 'admin'), '', PARAM_ALPHANUM));
|
||||
$temp->add(new admin_setting_configtext('sessioncookiepath', get_string('sessioncookiepath', 'admin'), get_string('configsessioncookiepath', 'admin'), '/', PARAM_LOCALURL));
|
||||
$temp->add(new admin_setting_configtext('sessioncookiedomain', get_string('sessioncookiedomain', 'admin'), get_string('configsessioncookiedomain', 'admin'), '', PARAM_TEXT, 50));
|
||||
$ADMIN->add('server', $temp, 50);
|
||||
|
||||
|
||||
@@ -211,7 +212,10 @@ $temp->add(new admin_setting_configselect('loglifetime', get_string('loglifetime
|
||||
120 => get_string('numdays', '', 120),
|
||||
90 => get_string('numdays', '', 90),
|
||||
60 => get_string('numdays', '', 60),
|
||||
35 => get_string('numdays', '', 35))));
|
||||
35 => get_string('numdays', '', 35),
|
||||
10 => get_string('numdays', '', 10),
|
||||
5 => get_string('numdays', '', 5),
|
||||
2 => get_string('numdays', '', 2))));
|
||||
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('disablegradehistory', get_string('disablegradehistory', 'grades'),
|
||||
@@ -238,6 +242,16 @@ $ADMIN->add('server', new admin_externalpage('phpinfo', get_string('phpinfo'), "
|
||||
|
||||
// "performance" settingpage
|
||||
$temp = new admin_settingpage('performance', get_string('performance', 'admin'));
|
||||
|
||||
$temp->add(new admin_setting_configselect('extramemorylimit', get_string('extramemorylimit', 'admin'),
|
||||
get_string('configextramemorylimit', 'admin'), '128M',
|
||||
// if this option is set to 0, default 128M will be used
|
||||
array( '64M' => '64M',
|
||||
'128M' => '128M',
|
||||
'256M' => '256M',
|
||||
'512M' => '512M',
|
||||
'1024M' => '1024M'
|
||||
)));
|
||||
$temp->add(new admin_setting_special_selectsetup('cachetype', get_string('cachetype', 'admin'),
|
||||
get_string('configcachetype', 'admin'), '',
|
||||
array( '' => get_string('none'),
|
||||
@@ -261,8 +275,14 @@ $temp->add(new admin_setting_configselect('memcachedpconn', get_string('memcache
|
||||
'1' => get_string('yes'))));
|
||||
$ADMIN->add('server', $temp);
|
||||
|
||||
if (file_exists("$CFG->dirroot/$CFG->admin/mysql/frame.php")) {
|
||||
$ADMIN->add('server', new admin_externalpage('database', get_string('managedatabase'), "$CFG->wwwroot/$CFG->admin/mysql/frame.php"));
|
||||
if ($CFG->dbfamily === 'mysql') {
|
||||
if (file_exists("$CFG->dirroot/$CFG->admin/mysql/frame.php")) {
|
||||
$ADMIN->add('server', new admin_externalpage('database', get_string('managedatabase'), "$CFG->wwwroot/$CFG->admin/mysql/frame.php"));
|
||||
}
|
||||
} else if ($CFG->dbfamily === 'postgres') {
|
||||
if (file_exists("$CFG->dirroot/$CFG->admin/pgsql/frame.php")) {
|
||||
$ADMIN->add('server', new admin_externalpage('database', get_string('managedatabase'), "$CFG->wwwroot/$CFG->admin/pgsql/frame.php"));
|
||||
}
|
||||
}
|
||||
|
||||
} // end of speedup
|
||||
|
||||
@@ -23,35 +23,13 @@ $ADMIN->add('root', new admin_category('courses', get_string('courses','admin'))
|
||||
$ADMIN->add('root', new admin_category('grades', get_string('grades')));
|
||||
$ADMIN->add('root', new admin_category('location', get_string('location','admin')));
|
||||
$ADMIN->add('root', new admin_category('language', get_string('language')));
|
||||
|
||||
$ADMIN->add('root', new admin_category('modules', get_string('plugins', 'admin')));
|
||||
|
||||
$ADMIN->add('root', new admin_category('security', get_string('security','admin')));
|
||||
$ADMIN->add('root', new admin_category('appearance', get_string('appearance','admin')));
|
||||
$ADMIN->add('root', new admin_category('frontpage', get_string('frontpage','admin')));
|
||||
$ADMIN->add('root', new admin_category('server', get_string('server','admin')));
|
||||
$ADMIN->add('root', new admin_category('mnet', get_string('net','mnet')));
|
||||
|
||||
$ADMIN->add('root', new admin_category('reports', get_string('reports')));
|
||||
foreach (get_list_of_plugins($CFG->admin.'/report') as $plugin) {
|
||||
/// This snippet is temporary until simpletest can be fixed to use xmldb. See MDL-7377 XXX TODO
|
||||
if ($plugin == 'simpletest' && $CFG->dbfamily != 'mysql' && $CFG->dbfamily != 'postgres') {
|
||||
continue;
|
||||
}
|
||||
/// End of removable snippet
|
||||
$reportname = get_string($plugin, 'report_' . $plugin);
|
||||
if ($reportname[1] == '[') {
|
||||
$reportname = get_string($plugin, 'admin');
|
||||
}
|
||||
// ugly hack for special access control in reports
|
||||
switch($plugin) {
|
||||
case 'backups': $cap = 'moodle/site:backup'; break;
|
||||
case 'simpletest': $cap = 'moodle/site:config'; break;
|
||||
default: $cap = 'moodle/site:viewreports';
|
||||
}
|
||||
$ADMIN->add('reports', new admin_externalpage('report'.$plugin, $reportname, "$CFG->wwwroot/$CFG->admin/report/$plugin/index.php",$cap));
|
||||
}
|
||||
|
||||
$ADMIN->add('root', new admin_category('misc', get_string('miscellaneous')));
|
||||
|
||||
// hidden unsupported category
|
||||
|
||||
+18
-11
@@ -2,6 +2,10 @@
|
||||
|
||||
// This file defines settingpages and externalpages under the "users" category
|
||||
|
||||
$ADMIN->add('users', new admin_category('authsettings', get_string('authentication','admin')));
|
||||
$ADMIN->add('users', new admin_category('accounts', get_string('accounts', 'admin')));
|
||||
$ADMIN->add('users', new admin_category('roles', get_string('permissions', 'role')));
|
||||
|
||||
if ($hassiteconfig
|
||||
or has_capability('moodle/site:uploadusers', $systemcontext)
|
||||
or has_capability('moodle/user:create', $systemcontext)
|
||||
@@ -11,8 +15,6 @@ if ($hassiteconfig
|
||||
or has_capability('moodle/role:assign', $systemcontext)) { // speedup for non-admins, add all caps used on this page
|
||||
|
||||
|
||||
$ADMIN->add('users', new admin_category('authsettings', get_string('authentication','admin')));
|
||||
|
||||
$temp = new admin_settingpage('manageauths', get_string('authsettings', 'admin'));
|
||||
$temp->add(new admin_setting_manageauths());
|
||||
$temp->add(new admin_setting_heading('manageauthscommonheading', get_string('commonsettings', 'admin'), ''));
|
||||
@@ -39,10 +41,7 @@ if ($hassiteconfig
|
||||
$authbyname = array();
|
||||
|
||||
foreach ($auths as $auth) {
|
||||
$strauthname = get_string("auth_{$auth}title", "auth");
|
||||
if ($strauthname == "[[auth_{$auth}title]]") {
|
||||
$strauthname = get_string("auth_{$auth}title", "auth_{$auth}");
|
||||
}
|
||||
$strauthname = auth_get_plugin_title($auth);
|
||||
$authbyname[$strauthname] = $auth;
|
||||
}
|
||||
ksort($authbyname);
|
||||
@@ -70,7 +69,6 @@ if ($hassiteconfig
|
||||
$securewwwroot = str_replace('http:','https:',$CFG->wwwroot);
|
||||
}
|
||||
// stuff under the "accounts" subcategory
|
||||
$ADMIN->add('users', new admin_category('accounts', get_string('accounts', 'admin')));
|
||||
$ADMIN->add('accounts', new admin_externalpage('editusers', get_string('userlist','admin'), "$CFG->wwwroot/$CFG->admin/user.php", array('moodle/user:update', 'moodle/user:delete')));
|
||||
$ADMIN->add('accounts', new admin_externalpage('userbulk', get_string('userbulk','admin'), "$CFG->wwwroot/$CFG->admin/user/user_bulk.php", array('moodle/user:update', 'moodle/user:delete')));
|
||||
$ADMIN->add('accounts', new admin_externalpage('addnewuser', get_string('addnewuser'), "$securewwwroot/user/editadvanced.php?id=-1", 'moodle/user:create'));
|
||||
@@ -80,7 +78,6 @@ if ($hassiteconfig
|
||||
|
||||
|
||||
// stuff under the "roles" subcategory
|
||||
$ADMIN->add('users', new admin_category('roles', get_string('permissions', 'role')));
|
||||
$ADMIN->add('roles', new admin_externalpage('defineroles', get_string('defineroles', 'role'), "$CFG->wwwroot/$CFG->admin/roles/manage.php", 'moodle/role:manage'));
|
||||
$ADMIN->add('roles', new admin_externalpage('assignroles', get_string('assignglobalroles', 'role'), "$CFG->wwwroot/$CFG->admin/roles/assign.php?contextid=".$systemcontext->id, 'moodle/role:assign'));
|
||||
|
||||
@@ -113,7 +110,12 @@ if ($hassiteconfig
|
||||
}
|
||||
if (!$guestroles = get_roles_with_capability('moodle/legacy:guest', CAP_ALLOW)) {
|
||||
$guestroles = array();
|
||||
$defaultguestid = null;
|
||||
} else {
|
||||
$defaultguestid = reset($guestroles);
|
||||
$defaultguestid = $defaultguestid->id;
|
||||
}
|
||||
|
||||
// we must not use assignable roles here:
|
||||
// 1/ unsetting roles as assignable for admin might bork the settings!
|
||||
// 2/ default user role should not be assignable anyway
|
||||
@@ -130,9 +132,9 @@ if ($hassiteconfig
|
||||
}
|
||||
|
||||
$temp->add(new admin_setting_configselect('notloggedinroleid', get_string('notloggedinroleid', 'admin'),
|
||||
get_string('confignotloggedinroleid', 'admin'), $guestrole->id, $allroles ));
|
||||
get_string('confignotloggedinroleid', 'admin'), $defaultguestid, $allroles ));
|
||||
$temp->add(new admin_setting_configselect('guestroleid', get_string('guestroleid', 'admin'),
|
||||
get_string('configguestroleid', 'admin'), $guestrole->id, $allroles));
|
||||
get_string('configguestroleid', 'admin'), $defaultguestid, $allroles));
|
||||
$temp->add(new admin_setting_configselect('defaultuserroleid', get_string('defaultuserroleid', 'admin'),
|
||||
get_string('configdefaultuserroleid', 'admin'), $userrole->id, $nonguestroles)); // guest role here breaks a lot of stuff
|
||||
}
|
||||
@@ -164,9 +166,14 @@ if ($hassiteconfig
|
||||
'yahooid' => get_string('yahooid'),
|
||||
'aimid' => get_string('aimid'),
|
||||
'msnid' => get_string('msnid'),
|
||||
'lastaccess' => get_string('lastaccess'))));
|
||||
'firstaccess' => get_string('firstaccess'),
|
||||
'lastaccess' => get_string('lastaccess'),
|
||||
'mycourses' => get_string('mycourses'),
|
||||
'groups' => get_string('groups'))));
|
||||
}
|
||||
|
||||
$temp->add(new admin_setting_configcheckbox('allowuserswitchrolestheycantassign', get_string('allowuserswitchrolestheycantassign', 'admin'), get_string('configallowuserswitchrolestheycantassign', 'admin'), 0));
|
||||
|
||||
$ADMIN->add('roles', $temp);
|
||||
|
||||
} // end of speedup
|
||||
|
||||
@@ -173,7 +173,7 @@ if ($formdata = $mform->is_cancelled()) {
|
||||
}
|
||||
unset($allowedroles);
|
||||
|
||||
// clear bilk selection
|
||||
// clear bulk selection
|
||||
if ($bulk) {
|
||||
$SESSION->bulk_users = array();
|
||||
}
|
||||
@@ -961,7 +961,7 @@ function uu_allowed_auths() {
|
||||
$plugins = get_enabled_auth_plugins();
|
||||
$choices = array();
|
||||
foreach ($plugins as $plugin) {
|
||||
$choices[$plugin] = get_string('auth_'.$plugin.'title', 'auth');
|
||||
$choices[$plugin] = auth_get_plugin_title ($plugin);
|
||||
}
|
||||
|
||||
return $choices;
|
||||
|
||||
@@ -39,7 +39,7 @@ if ($format) {
|
||||
|
||||
if ($extrafields = get_records_select('user_info_field')) {
|
||||
foreach ($extrafields as $n=>$v){
|
||||
$fields['profile_field_'.$v->shortname] = 'profile_field_'.$v->name;
|
||||
$fields['profile_field_'.$v->shortname] = 'profile_field_'.$v->shortname;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ class edit_field extends XMLDBAction {
|
||||
/// Fetch request data
|
||||
$tableparam = required_param('table', PARAM_CLEAN);
|
||||
if (!$table =& $structure->getTable($tableparam)) {
|
||||
$this->errormsg = 'Wrong table specified: ' . $tableparm;
|
||||
$this->errormsg = 'Wrong table specified: ' . $tableparam;
|
||||
return false;
|
||||
}
|
||||
$fieldparam = required_param('field', PARAM_CLEAN);
|
||||
|
||||
@@ -84,7 +84,7 @@ class edit_index extends XMLDBAction {
|
||||
/// Fetch request data
|
||||
$tableparam = required_param('table', PARAM_CLEAN);
|
||||
if (!$table =& $structure->getTable($tableparam)) {
|
||||
$this->errormsg = 'Wrong table specified: ' . $tableparm;
|
||||
$this->errormsg = 'Wrong table specified: ' . $tableparam;
|
||||
return false;
|
||||
}
|
||||
$indexparam = required_param('index', PARAM_CLEAN);
|
||||
|
||||
@@ -84,7 +84,7 @@ class edit_key extends XMLDBAction {
|
||||
/// Fetch request data
|
||||
$tableparam = required_param('table', PARAM_CLEAN);
|
||||
if (!$table =& $structure->getTable($tableparam)) {
|
||||
$this->errormsg = 'Wrong table specified: ' . $tableparm;
|
||||
$this->errormsg = 'Wrong table specified: ' . $tableparam;
|
||||
return false;
|
||||
}
|
||||
$keyparam = required_param('key', PARAM_CLEAN);
|
||||
|
||||
@@ -80,7 +80,7 @@ class view_table_sql extends XMLDBAction {
|
||||
/// Get parameters
|
||||
$tableparam = required_param('table', PARAM_PATH);
|
||||
if (!$table =& $structure->getTable($tableparam)) {
|
||||
$this->errormsg = 'Wrong table specified: ' . $tableparm;
|
||||
$this->errormsg = 'Wrong table specified: ' . $tableparam;
|
||||
return false;
|
||||
}
|
||||
$generatorparam = optional_param('generator', null, PARAM_ALPHANUM);
|
||||
|
||||
@@ -657,7 +657,7 @@ class CASClient
|
||||
*/
|
||||
function setCacheTimesForAuthRequest($n)
|
||||
{
|
||||
$this->_cache_times_for_auth_recheck = n;
|
||||
$this->_cache_times_for_auth_recheck = $n;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+463
-794
File diff suppressed because it is too large
Load Diff
+33
-4
@@ -57,8 +57,8 @@ class auth_plugin_cas extends auth_plugin_base {
|
||||
* @return bool Authentication success or failure.
|
||||
*/
|
||||
function user_login ($username, $password) {
|
||||
$this->connectCAS();
|
||||
return phpCAS::isAuthenticated();
|
||||
$this->connectCAS();
|
||||
return phpCAS::isAuthenticated() && (phpCAS::getUser() == $username);
|
||||
}
|
||||
/**
|
||||
* Returns true if this authentication plugin is 'internal'.
|
||||
@@ -409,7 +409,7 @@ if ( !is_object($PHPCAS_CLIENT) ) {
|
||||
$result[$key] = $ldapval;
|
||||
}
|
||||
}
|
||||
@ldap_close($ldapconnection);
|
||||
$this->ldap_close($ldapconnection);
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
@@ -439,6 +439,16 @@ if ( !is_object($PHPCAS_CLIENT) ) {
|
||||
* @return connection result
|
||||
*/
|
||||
function ldap_connect($binddn='',$bindpwd='') {
|
||||
// Cache ldap connections (they are expensive to set up
|
||||
// and can drain the TCP/IP ressources on the server if we
|
||||
// are syncing a lot of users (as we try to open a new connection
|
||||
// to get the user details). This is the least invasive way
|
||||
// to reuse existing connections without greater code surgery.
|
||||
if(!empty($this->ldapconnection)) {
|
||||
$this->ldapconns++;
|
||||
return $this->ldapconnection;
|
||||
}
|
||||
|
||||
//Select bind password, With empty values use
|
||||
//ldap_bind_* variables or anonymous bind if ldap_bind_* are empty
|
||||
if ($binddn == '' and $bindpwd == '') {
|
||||
@@ -473,6 +483,10 @@ if ( !is_object($PHPCAS_CLIENT) ) {
|
||||
ldap_set_option($connresult, LDAP_OPT_DEREF, $this->config->opt_deref);
|
||||
}
|
||||
if ($bindresult) {
|
||||
// Set the connection counter so we can call PHP's ldap_close()
|
||||
// when we call $this->ldap_close() for the last 'open' connection.
|
||||
$this->ldapconns = 1;
|
||||
$this->ldapconnection = $connresult;
|
||||
return $connresult;
|
||||
}
|
||||
$debuginfo .= "<br/>Server: '$server' <br/> Connection: '$connresult'<br/> Bind result: '$bindresult'</br>";
|
||||
@@ -481,6 +495,18 @@ if ( !is_object($PHPCAS_CLIENT) ) {
|
||||
print_error('auth_ldap_noconnect_all','auth',$this->config->user_type);
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* disconnects from a ldap server
|
||||
*
|
||||
*/
|
||||
function ldap_close() {
|
||||
$this->ldapconns--;
|
||||
if($this->ldapconns == 0) {
|
||||
@ldap_close($this->ldapconnection);
|
||||
unset($this->ldapconnection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* retuns user attribute mappings between moodle and ldap
|
||||
*
|
||||
@@ -630,7 +656,7 @@ if ( !is_object($PHPCAS_CLIENT) ) {
|
||||
print "Connecting to ldap...\n";
|
||||
$ldapconnection = $this->ldap_connect();
|
||||
if (!$ldapconnection) {
|
||||
@ldap_close($ldapconnection);
|
||||
$this->ldap_close($ldapconnection);
|
||||
print get_string('auth_ldap_noconnect','auth',$this->config->host_url);
|
||||
exit;
|
||||
}
|
||||
@@ -866,6 +892,7 @@ if ( !is_object($PHPCAS_CLIENT) ) {
|
||||
} else {
|
||||
print "No users to be added\n";
|
||||
}
|
||||
$this->ldap_close();
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
@@ -1004,6 +1031,7 @@ if (!empty($this->config->attrcreators)) {
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->ldap_close();
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
@@ -1043,6 +1071,7 @@ if (!empty($this->config->attrcreators)) {
|
||||
array_push($fresult, ($users[$i][$this->config->user_attribute][0]) );
|
||||
}
|
||||
}
|
||||
$this->ldap_close();
|
||||
return $fresult;
|
||||
}
|
||||
/**
|
||||
|
||||
+2
-1
@@ -16,7 +16,8 @@
|
||||
/* */
|
||||
/* 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. */
|
||||
/* the Free Software Foundation; either version 2 of the License or any */
|
||||
/* later version. */
|
||||
/************************************************************************/
|
||||
/* Author: Torsten Anderson, torsten.anderson@skeria.skelleftea.se
|
||||
*/
|
||||
|
||||
+101
-22
@@ -141,7 +141,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
if ($this->ldap_find_userdn($ldapconnection, $extusername)) {
|
||||
$validuser = true;
|
||||
}
|
||||
ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
}
|
||||
|
||||
// Shortcut here - SSO confirmed
|
||||
@@ -156,19 +156,19 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
|
||||
//if ldap_user_dn is empty, user does not exist
|
||||
if (!$ldap_user_dn) {
|
||||
ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to bind with current username and password
|
||||
$ldap_login = @ldap_bind($ldapconnection, $ldap_user_dn, $extpassword);
|
||||
ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
if ($ldap_login) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
print_error('auth_ldap_noconnect','auth','',$this->config->host_url);
|
||||
}
|
||||
return false;
|
||||
@@ -242,7 +242,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
}
|
||||
|
||||
@ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -383,7 +383,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
default:
|
||||
print_error('auth_ldap_unsupportedusertype','auth','',$this->config->user_type);
|
||||
}
|
||||
ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
return $uadd;
|
||||
|
||||
}
|
||||
@@ -596,7 +596,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
$ldapconnection = $this->ldap_connect();
|
||||
|
||||
if (!$ldapconnection) {
|
||||
@ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
print get_string('auth_ldap_noconnect','auth',$this->config->host_url);
|
||||
exit;
|
||||
}
|
||||
@@ -838,6 +838,9 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
$user->confirmed = 1;
|
||||
$user->auth = 'ldap';
|
||||
$user->mnethostid = $CFG->mnet_localhost_id;
|
||||
// get_userinfo_asobj() might have replaced $user->username with the value
|
||||
// from the LDAP server (which can be mixed-case). Make sure it's lowercase
|
||||
$user->username = trim(moodle_strtolower($user->username));
|
||||
if (empty($user->lang)) {
|
||||
$user->lang = $CFG->lang;
|
||||
}
|
||||
@@ -864,6 +867,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
} else {
|
||||
print "No users to be added\n";
|
||||
}
|
||||
$this->ldap_close();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -968,7 +972,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
error ('auth: ldap user_activate() does not support selected usertype:"'.$this->config->user_type.'" (..yet)');
|
||||
}
|
||||
$result = ldap_modify($ldapconnection, $userdn, $newinfo);
|
||||
ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -1003,7 +1007,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
error ('auth: ldap user_disable() does not support selected usertype (..yet)');
|
||||
}
|
||||
$result = ldap_modify($ldapconnection, $userdn, $newinfo);
|
||||
ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
return $result;
|
||||
}*/
|
||||
|
||||
@@ -1188,11 +1192,11 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
} else {
|
||||
error_log("ERROR:No user found in LDAP");
|
||||
@ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1316,7 +1320,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
|
||||
}
|
||||
|
||||
@ldap_close($ldapconnection);
|
||||
$this->ldap_close();
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -1561,6 +1565,16 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
* @return connection result
|
||||
*/
|
||||
function ldap_connect($binddn='',$bindpwd='') {
|
||||
// Cache ldap connections (they are expensive to set up
|
||||
// and can drain the TCP/IP ressources on the server if we
|
||||
// are syncing a lot of users (as we try to open a new connection
|
||||
// to get the user details). This is the least invasive way
|
||||
// to reuse existing connections without greater code surgery.
|
||||
if(!empty($this->ldapconnection)) {
|
||||
$this->ldapconns++;
|
||||
return $this->ldapconnection;
|
||||
}
|
||||
|
||||
//Select bind password, With empty values use
|
||||
//ldap_bind_* variables or anonymous bind if ldap_bind_* are empty
|
||||
if ($binddn == '' and $bindpwd == '') {
|
||||
@@ -1607,6 +1621,10 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
|
||||
if ($bindresult) {
|
||||
// Set the connection counter so we can call PHP's ldap_close()
|
||||
// when we call $this->ldap_close() for the last 'open' connection.
|
||||
$this->ldapconns = 1;
|
||||
$this->ldapconnection = $connresult;
|
||||
return $connresult;
|
||||
}
|
||||
|
||||
@@ -1618,6 +1636,18 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* disconnects from a ldap server
|
||||
*
|
||||
*/
|
||||
function ldap_close() {
|
||||
$this->ldapconns--;
|
||||
if($this->ldapconns == 0) {
|
||||
@ldap_close($this->ldapconnection);
|
||||
unset($this->ldapconnection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* retuns dn of username
|
||||
*
|
||||
@@ -1813,16 +1843,55 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
*
|
||||
*/
|
||||
function loginpage_hook() {
|
||||
global $CFG;
|
||||
global $CFG, $SESSION;
|
||||
|
||||
if (($_SERVER['REQUEST_METHOD'] === 'GET' // Only on initial GET of loginpage
|
||||
|| ($_SERVER['REQUEST_METHOD'] === 'POST'
|
||||
&& (get_referer() != strip_querystring(qualified_me()))))
|
||||
// Or when POSTed from another place
|
||||
// See MDL-14071
|
||||
&& !empty($this->config->ntlmsso_enabled) // SSO enabled
|
||||
&& !empty($this->config->ntlmsso_subnet) // have a subnet to test for
|
||||
&& empty($_GET['authldap_skipntlmsso']) // haven't failed it yet
|
||||
&& (isguestuser() || !isloggedin()) // guestuser or not-logged-in users
|
||||
&& address_in_subnet(getremoteaddr(), $this->config->ntlmsso_subnet)) {
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'GET' // Only on initial GET
|
||||
// of loginpage
|
||||
&&!empty($this->config->ntlmsso_enabled)// SSO enabled
|
||||
&& !empty($this->config->ntlmsso_subnet)// have a subnet to test for
|
||||
&& empty($_GET['authldap_skipntlmsso']) // haven't failed it yet
|
||||
&& (isguestuser() || !isloggedin()) // guestuser or not-logged-in users
|
||||
&& address_in_subnet($_SERVER['REMOTE_ADDR'],$this->config->ntlmsso_subnet)) {
|
||||
redirect("{$CFG->wwwroot}/auth/ldap/ntlmsso_attempt.php");
|
||||
// First, let's remember where we were trying to get to before we got here
|
||||
if (empty($SESSION->wantsurl)) {
|
||||
$SESSION->wantsurl = (array_key_exists('HTTP_REFERER', $_SERVER) &&
|
||||
$_SERVER['HTTP_REFERER'] != $CFG->wwwroot &&
|
||||
$_SERVER['HTTP_REFERER'] != $CFG->wwwroot.'/' &&
|
||||
$_SERVER['HTTP_REFERER'] != $CFG->httpswwwroot.'/login/' &&
|
||||
$_SERVER['HTTP_REFERER'] != $CFG->httpswwwroot.'/login/index.php')
|
||||
? $_SERVER['HTTP_REFERER'] : NULL;
|
||||
}
|
||||
|
||||
// Now start the whole NTLM machinery.
|
||||
if(!empty($this->config->ntlmsso_ie_fastpath)) {
|
||||
// Shortcut for IE browsers: skip the attempt page at all
|
||||
if(check_browser_version('MSIE')) {
|
||||
$sesskey = sesskey();
|
||||
redirect($CFG->wwwroot.'/auth/ldap/ntlmsso_magic.php?sesskey='.$sesskey);
|
||||
} else {
|
||||
redirect($CFG->httpswwwroot.'/login/index.php?authldap_skipntlmsso=1');
|
||||
}
|
||||
} else {
|
||||
redirect($CFG->wwwroot.'/auth/ldap/ntlmsso_attempt.php');
|
||||
}
|
||||
}
|
||||
|
||||
// No NTLM SSO, Use the normal login page instead.
|
||||
|
||||
// If $SESSION->wantsurl is empty and we have a 'Referer:' header, the login
|
||||
// page insists on redirecting us to that page after user validation. If
|
||||
// we clicked on the redirect link at the ntlmsso_finish.php page instead
|
||||
// of waiting for the redirection to happen, then we have a 'Referer:' header
|
||||
// we don't want to use at all. As we can't get rid of it, just point
|
||||
// $SESSION->wantsurl to $CFG->wwwroot (after all, we came from there).
|
||||
if (empty($SESSION->wantsurl)
|
||||
&& (get_referer() == $CFG->httpswwwroot.'/auth/ldap/ntlmsso_finish.php')) {
|
||||
|
||||
$SESSION->wantsurl = $CFG->wwwroot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1845,7 +1914,14 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
*/
|
||||
function ntlmsso_magic($sesskey) {
|
||||
if (isset($_SERVER['REMOTE_USER']) && !empty($_SERVER['REMOTE_USER'])) {
|
||||
$username = $_SERVER['REMOTE_USER'];
|
||||
|
||||
// HTTP __headers__ seem to be sent in ISO-8859-1 encoding
|
||||
// (according to my reading of RFC-1945, RFC-2616 and RFC-2617 and
|
||||
// my local tests), so we need to convert the REMOTE_USER value
|
||||
// (i.e., what we got from the HTTP WWW-Authenticate header) into UTF-8
|
||||
$textlib = textlib_get_instance();
|
||||
$username = $textlib->convert($_SERVER['REMOTE_USER'], 'iso-8859-1', 'utf-8');
|
||||
|
||||
$username = substr(strrchr($username, '\\'), 1); //strip domain info
|
||||
$username = moodle_strtolower($username); //compatibility hack
|
||||
set_cache_flag('auth/ldap/ntlmsess', $sesskey, $username, AUTH_NTLMTIMEOUT);
|
||||
@@ -2002,6 +2078,8 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
{$config->ntlmsso_enabled = 0; }
|
||||
if (!isset($config->ntlmsso_subnet))
|
||||
{$config->ntlmsso_subnet = ''; }
|
||||
if (!isset($config->ntlmsso_ie_fastpath))
|
||||
{$config->ntlmsso_ie_fastpath = 0; }
|
||||
|
||||
// save settings
|
||||
set_config('host_url', $config->host_url, 'auth/ldap');
|
||||
@@ -2034,6 +2112,7 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
set_config('removeuser', $config->removeuser, 'auth/ldap');
|
||||
set_config('ntlmsso_enabled', (int)$config->ntlmsso_enabled, 'auth/ldap');
|
||||
set_config('ntlmsso_subnet', $config->ntlmsso_subnet, 'auth/ldap');
|
||||
set_config('ntlmsso_ie_fastpath', (int)$config->ntlmsso_ie_fastpath, 'auth/ldap');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
{$config->ntlmsso_enabled = 0; }
|
||||
if (!isset($config->ntlmsso_subnet))
|
||||
{$config->ntlmsso_subnet = ''; }
|
||||
if (!isset($config->ntlmsso_ie_fastpath))
|
||||
{$config->ntlmsso_ie_fastpath = 0; }
|
||||
|
||||
$yesno = array( get_string('no'), get_string('yes') );
|
||||
|
||||
@@ -468,6 +470,17 @@ if (!function_exists('ldap_connect')) { // Is php4-ldap really there?
|
||||
<?php print_string('auth_ntlmsso_subnet','auth') ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td align="right"><label for="menuntlmsso_ie_fastpath"><?php print_string('auth_ntlmsso_ie_fastpath_key','auth') ?></label></td>
|
||||
<td>
|
||||
<?php
|
||||
choose_from_menu($yesno, 'ntlmsso_ie_fastpath', $config->ntlmsso_ie_fastpath, '0');
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php print_string('auth_ntlmsso_ie_fastpath','auth') ?>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
|
||||
|
||||
@@ -22,7 +22,15 @@ if (empty($authplugin->config->ntlmsso_enabled)) {
|
||||
|
||||
$sesskey = sesskey();
|
||||
|
||||
//print_header("$site->fullname: $loginsite", $site->fullname, $loginsite, $focus, '', true);
|
||||
// Display the page header. This makes redirect respect the timeout we specify
|
||||
// here (and not add 3 more secs) which in turn prevents a bug in both IE 6.x
|
||||
// and FF 3.x (Windows version at least) where javascript timers fire up even
|
||||
// when we've already left the page that set the timer.
|
||||
$loginsite = get_string("loginsite");
|
||||
$navlinks = array(array('name' => $loginsite, 'link' => null, 'type' => 'misc'));
|
||||
$navigation = build_navigation($navlinks);
|
||||
print_header("$site->fullname: $loginsite", $site->fullname, $navigation, '', '', true);
|
||||
|
||||
$msg = '<p>'.get_string('ntlmsso_attempting','auth').'</p>'
|
||||
. '<img width="1", height="1" '
|
||||
. ' src="' . $CFG->wwwroot . '/auth/ldap/ntlmsso_magic.php?sesskey='
|
||||
@@ -31,4 +39,4 @@ redirect($CFG->wwwroot . '/auth/ldap/ntlmsso_finish.php', $msg, 3);
|
||||
|
||||
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -24,7 +24,13 @@ if (empty($authplugin->config->ntlmsso_enabled)) {
|
||||
// so we only worry about failure.
|
||||
if (!$authplugin->ntlmsso_finish()) {
|
||||
// Redirect to login, saying "don't try again!"
|
||||
redirect($CFG->wwwroot . '/login/index.php?authldap_skipntlmsso=1',
|
||||
// Display the page header. This makes redirect respect the timeout we specify
|
||||
// here (and not add 3 more secs).
|
||||
$loginsite = get_string("loginsite");
|
||||
$navlinks = array(array('name' => $loginsite, 'link' => null, 'type' => 'misc'));
|
||||
$navigation = build_navigation($navlinks);
|
||||
print_header("$site->fullname: $loginsite", $site->fullname, $navigation, '', '', true);
|
||||
redirect($CFG->httpswwwroot . '/login/index.php?authldap_skipntlmsso=1',
|
||||
get_string('ntlmsso_failed','auth'), 3);
|
||||
}
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -27,6 +27,12 @@ $file = $CFG->dirroot . '/pix/spacer.gif';
|
||||
if ($authplugin->ntlmsso_magic($sesskey)
|
||||
&& file_exists($file)) {
|
||||
|
||||
if (!empty($authplugin->config->ntlmsso_ie_fastpath)) {
|
||||
if (check_browser_version('MSIE')) {
|
||||
redirect($CFG->wwwroot . '/auth/ldap/ntlmsso_finish.php');
|
||||
}
|
||||
}
|
||||
|
||||
// Serve GIF
|
||||
// Type
|
||||
header('Content-Type: image/gif');
|
||||
@@ -41,4 +47,4 @@ if ($authplugin->ntlmsso_magic($sesskey)
|
||||
print_error('ntlmsso_iwamagicnotenabled','auth');
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
+83
-62
@@ -208,7 +208,7 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
$mnet_session->confirm_timeout = time() + $this->config->rpc_negotiation_timeout;
|
||||
$mnet_session->expires = time() + (integer)ini_get('session.gc_maxlifetime');
|
||||
$mnet_session->session_id = session_id();
|
||||
if (! $mnet_session->id = insert_record('mnet_session', addslashes_object($mnet_session))) {
|
||||
if (! $mnet_session->id = insert_record('mnet_session', addslashes_recursive($mnet_session))) {
|
||||
print_error('databaseerror', 'mnet');
|
||||
}
|
||||
} else {
|
||||
@@ -217,7 +217,7 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
$mnet_session->confirm_timeout = time() + $this->config->rpc_negotiation_timeout;
|
||||
$mnet_session->expires = time() + (integer)ini_get('session.gc_maxlifetime');
|
||||
$mnet_session->session_id = session_id();
|
||||
if (false == update_record('mnet_session', addslashes_object($mnet_session))) {
|
||||
if (false == update_record('mnet_session', addslashes_recursive($mnet_session))) {
|
||||
print_error('databaseerror', 'mnet');
|
||||
}
|
||||
}
|
||||
@@ -294,7 +294,7 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
print_error('nolocaluser', 'mnet');
|
||||
}
|
||||
$remoteuser->mnethostid = $remotehost->id;
|
||||
if (! insert_record('user', addslashes_object($remoteuser))) {
|
||||
if (! insert_record('user', addslashes_recursive($remoteuser))) {
|
||||
print_error('databaseerror', 'mnet');
|
||||
}
|
||||
$firsttime = true;
|
||||
@@ -368,7 +368,7 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
|
||||
$localuser->mnethostid = $remotepeer->id;
|
||||
|
||||
$bool = update_record('user', addslashes_object($localuser));
|
||||
$bool = update_record('user', addslashes_recursive($localuser));
|
||||
if (!$bool) {
|
||||
// TODO: Jonathan to clean up mess
|
||||
// Actually, this should never happen (modulo race conditions) - ML
|
||||
@@ -391,12 +391,12 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
$mnet_session->confirm_timeout = time();
|
||||
$mnet_session->expires = time() + (integer)$session_gc_maxlifetime;
|
||||
$mnet_session->session_id = session_id();
|
||||
if (! $mnet_session->id = insert_record('mnet_session', addslashes_object($mnet_session))) {
|
||||
if (! $mnet_session->id = insert_record('mnet_session', addslashes_recursive($mnet_session))) {
|
||||
print_error('databaseerror', 'mnet');
|
||||
}
|
||||
} else {
|
||||
$mnet_session->expires = time() + (integer)$session_gc_maxlifetime;
|
||||
update_record('mnet_session', addslashes_object($mnet_session));
|
||||
update_record('mnet_session', addslashes_recursive($mnet_session));
|
||||
}
|
||||
|
||||
if (!$firsttime) {
|
||||
@@ -540,7 +540,7 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
// First up - do we have a record for this course?
|
||||
if (!array_key_exists($course['remoteid'], $currentcourses)) {
|
||||
// No record - we must create it
|
||||
$course['id'] = insert_record('mnet_enrol_course', addslashes_object((object)$course));
|
||||
$course['id'] = insert_record('mnet_enrol_course', addslashes_recursive((object)$course));
|
||||
$currentcourse = (object)$course;
|
||||
} else {
|
||||
// Pointer to current course:
|
||||
@@ -558,7 +558,7 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
}
|
||||
|
||||
if ($saveflag) {
|
||||
update_record('mnet_enrol_course', addslashes_object($currentcourse));
|
||||
update_record('mnet_enrol_course', addslashes_recursive($currentcourse));
|
||||
}
|
||||
|
||||
if (isset($currentcourse->assignmentid) && is_numeric($currentcourse->assignmentid)) {
|
||||
@@ -581,7 +581,7 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
$assignObj->hostid = (int)$MNET_REMOTE_CLIENT->id;
|
||||
$assignObj->courseid = $course['id'];
|
||||
$assignObj->rolename = $course['defaultrolename'];
|
||||
$assignObj->id = insert_record('mnet_enrol_assignments', addslashes_object($assignObj));
|
||||
$assignObj->id = insert_record('mnet_enrol_assignments', addslashes_recursive($assignObj));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -772,76 +772,76 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
join("\n", $mnet_request->error));
|
||||
break;
|
||||
}
|
||||
$mnethostlogssql = '
|
||||
SELECT
|
||||
mhostlogs.remoteid, mhostlogs.time, mhostlogs.userid, mhostlogs.ip,
|
||||
mhostlogs.course, mhostlogs.module, mhostlogs.cmid, mhostlogs.action,
|
||||
mhostlogs.url, mhostlogs.info, mhostlogs.username, c.fullname as coursename,
|
||||
c.modinfo
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
l.id as remoteid, l.time, l.userid, l.ip, l.course, l.module, l.cmid,
|
||||
l.action, l.url, l.info, u.username
|
||||
FROM
|
||||
' . $CFG->prefix . 'user u
|
||||
INNER JOIN ' . $CFG->prefix . 'log l on l.userid = u.id
|
||||
WHERE
|
||||
u.mnethostid = ' . $mnethostid . '
|
||||
AND l.id > ' . $mnet_request->response['last log id'] . '
|
||||
ORDER BY remoteid ASC
|
||||
LIMIT 500
|
||||
) mhostlogs
|
||||
INNER JOIN ' . $CFG->prefix . 'course c on c.id = mhostlogs.course
|
||||
ORDER by mhostlogs.remoteid ASC';
|
||||
|
||||
$query = "SELECT
|
||||
l.id as remoteid,
|
||||
l.time,
|
||||
l.userid,
|
||||
l.ip,
|
||||
l.course,
|
||||
l.module,
|
||||
l.cmid,
|
||||
l.action,
|
||||
l.url,
|
||||
l.info,
|
||||
c.fullname as coursename,
|
||||
c.modinfo as modinfo,
|
||||
u.username
|
||||
FROM
|
||||
{$CFG->prefix}user u,
|
||||
{$CFG->prefix}log l,
|
||||
{$CFG->prefix}course c
|
||||
WHERE
|
||||
l.userid = u.id AND
|
||||
u.mnethostid = '$mnethostid' AND
|
||||
l.id > '".$mnet_request->response['last log id']."' AND
|
||||
c.id = l.course
|
||||
ORDER BY
|
||||
remoteid ASC";
|
||||
$mnethostlogs = get_records_sql($mnethostlogssql);
|
||||
|
||||
$results = get_records_sql($query);
|
||||
if ($mnethostlogs == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false == $results) continue;
|
||||
$processedlogs = array();
|
||||
|
||||
$param = array();
|
||||
|
||||
foreach($results as $result) {
|
||||
if (!empty($result->modinfo) && !empty($result->cmid)) {
|
||||
$modinfo = unserialize($result->modinfo);
|
||||
unset($result->modinfo);
|
||||
foreach($mnethostlogs as $hostlog) {
|
||||
// Extract the name of the relevant module instance from the
|
||||
// course modinfo if possible.
|
||||
if (!empty($hostlog->modinfo) && !empty($hostlog->cmid)) {
|
||||
$modinfo = unserialize($hostlog->modinfo);
|
||||
unset($hostlog->modinfo);
|
||||
$modulearray = array();
|
||||
foreach($modinfo as $module) {
|
||||
$modulearray[$module->cm] = urldecode($module->name);
|
||||
}
|
||||
$result->resource_name = $modulearray[$result->cmid];
|
||||
$hostlog->resource_name = $modulearray[$hostlog->cmid];
|
||||
} else {
|
||||
$result->resource_name = '';
|
||||
$hostlog->resource_name = '';
|
||||
}
|
||||
|
||||
$param[] = array (
|
||||
'remoteid' => $result->remoteid,
|
||||
'time' => $result->time,
|
||||
'userid' => $result->userid,
|
||||
'ip' => $result->ip,
|
||||
'course' => $result->course,
|
||||
'coursename' => $result->coursename,
|
||||
'module' => $result->module,
|
||||
'cmid' => $result->cmid,
|
||||
'action' => $result->action,
|
||||
'url' => $result->url,
|
||||
'info' => $result->info,
|
||||
'resource_name' => $result->resource_name,
|
||||
'username' => $result->username
|
||||
$processedlogs[] = array (
|
||||
'remoteid' => $hostlog->remoteid,
|
||||
'time' => $hostlog->time,
|
||||
'userid' => $hostlog->userid,
|
||||
'ip' => $hostlog->ip,
|
||||
'course' => $hostlog->course,
|
||||
'coursename' => $hostlog->coursename,
|
||||
'module' => $hostlog->module,
|
||||
'cmid' => $hostlog->cmid,
|
||||
'action' => $hostlog->action,
|
||||
'url' => $hostlog->url,
|
||||
'info' => $hostlog->info,
|
||||
'resource_name' => $hostlog->resource_name,
|
||||
'username' => $hostlog->username
|
||||
);
|
||||
}
|
||||
|
||||
unset($result);
|
||||
unset($hostlog);
|
||||
|
||||
$mnet_request = new mnet_xmlrpc_client();
|
||||
$mnet_request->set_method('auth/mnet/auth.php/refresh_log');
|
||||
|
||||
// set $token and $useragent parameters
|
||||
$mnet_request->add_param($param);
|
||||
$mnet_request->add_param($processedlogs);
|
||||
|
||||
if ($mnet_request->send($mnet_peer) === true) {
|
||||
if ($mnet_request->response['code'] > 0) {
|
||||
@@ -877,7 +877,7 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
if (isset($useridarray[$logEntryObj->username])) {
|
||||
$logEntryObj->userid = $useridarray[$logEntryObj->username];
|
||||
} else {
|
||||
$logEntryObj->userid = get_field('user','id','username',$logEntryObj->username);
|
||||
$logEntryObj->userid = get_field('user','id','username',$logEntryObj->username,'mnethostid',(int)$logEntryObj->hostid);
|
||||
if ($logEntryObj->userid == false) {
|
||||
$logEntryObj->userid = 0;
|
||||
}
|
||||
@@ -886,10 +886,12 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
|
||||
unset($logEntryObj->username);
|
||||
|
||||
$insertok = insert_record('mnet_log', addslashes_object($logEntryObj), false);
|
||||
$logEntryObj = $this->trim_logline($logEntryObj);
|
||||
$insertok = insert_record('mnet_log', addslashes_recursive($logEntryObj), false);
|
||||
|
||||
if ($insertok) {
|
||||
$MNET_REMOTE_CLIENT->last_log_id = $logEntryObj->remoteid;
|
||||
$MNET_REMOTE_CLIENT->updateparams->last_log_id = $logEntryObj->remoteid;
|
||||
} else {
|
||||
$returnString .= 'Record with id '.$logEntryObj->remoteid." failed to insert.\n";
|
||||
}
|
||||
@@ -1352,6 +1354,25 @@ class auth_plugin_mnet extends auth_plugin_base {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims a log line from mnet peer to limit each part to a length which can be stored in our DB
|
||||
*
|
||||
* @param object $logline The log information to be trimmed
|
||||
* @return object The passed logline object trimmed to not exceed storable limits
|
||||
*/
|
||||
function trim_logline ($logline) {
|
||||
$limits = array('ip' => 15, 'coursename' => 40, 'module' => 20, 'action' => 40,
|
||||
'url' => 255);
|
||||
foreach ($limits as $property => $limit) {
|
||||
if (isset($logline->$property)) {
|
||||
$logline->$property = substr($logline->$property, 0, $limit);
|
||||
}
|
||||
}
|
||||
|
||||
return $logline;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
+51
-1
@@ -9,8 +9,10 @@
|
||||
*
|
||||
* Authenticates against a RADIUS server.
|
||||
* Contributed by Clive Gould <clive@ce.bromley.ac.uk>
|
||||
* CHAP support contributed by Stanislav Tsymbalov http://www.tsymbalov.net/
|
||||
*
|
||||
* 2006-08-31 File created.
|
||||
* 2008-03-12 CHAP support added by Stanislav Tsymbalov.
|
||||
*/
|
||||
|
||||
if (!defined('MOODLE_INTERNAL')) {
|
||||
@@ -42,6 +44,7 @@ class auth_plugin_radius extends auth_plugin_base {
|
||||
*/
|
||||
function user_login ($username, $password) {
|
||||
require_once 'Auth/RADIUS.php';
|
||||
require_once 'Crypt/CHAP.php';
|
||||
|
||||
// Added by Clive on 7th May for test purposes
|
||||
// printf("Username: $username <br/>");
|
||||
@@ -50,9 +53,52 @@ class auth_plugin_radius extends auth_plugin_base {
|
||||
// printf("nasport: $this->config->nasport <br/>");
|
||||
// printf("secret: $this->config->secret <br/>");
|
||||
|
||||
$rauth = new Auth_RADIUS_PAP(stripslashes($username), stripslashes($password));
|
||||
// Added by Stanislav Tsymbalov on 12th March 2008 only for test purposes
|
||||
//$type = 'PAP';
|
||||
//$type = 'CHAP_MD5';
|
||||
//$type = 'MSCHAPv1';
|
||||
//$type = 'MSCHAPv2';
|
||||
$type = $this->config->radiustype;
|
||||
if (empty($type)) {
|
||||
$type = 'PAP';
|
||||
}
|
||||
|
||||
$classname = 'Auth_RADIUS_' . $type;
|
||||
$rauth = new $classname(stripslashes($username), stripslashes($password));
|
||||
$rauth->addServer($this->config->host, $this->config->nasport, $this->config->secret);
|
||||
|
||||
$rauth->username = $username;
|
||||
|
||||
switch($type) {
|
||||
case 'CHAP_MD5':
|
||||
case 'MSCHAPv1':
|
||||
$classname = $type == 'MSCHAPv1' ? 'Crypt_CHAP_MSv1' : 'Crypt_CHAP_MD5';
|
||||
$crpt = new $classname;
|
||||
$crpt->password = $password;
|
||||
$rauth->challenge = $crpt->challenge;
|
||||
$rauth->chapid = $crpt->chapid;
|
||||
$rauth->response = $crpt->challengeResponse();
|
||||
$rauth->flags = 1;
|
||||
// If you must use deprecated and weak LAN-Manager-Responses use this:
|
||||
// $rauth->lmResponse = $crpt->lmChallengeResponse();
|
||||
// $rauth->flags = 0;
|
||||
break;
|
||||
|
||||
case 'MSCHAPv2':
|
||||
$crpt = new Crypt_CHAP_MSv2;
|
||||
$crpt->username = $username;
|
||||
$crpt->password = $password;
|
||||
$rauth->challenge = $crpt->authChallenge;
|
||||
$rauth->peerChallenge = $crpt->peerChallenge;
|
||||
$rauth->chapid = $crpt->chapid;
|
||||
$rauth->response = $crpt->challengeResponse();
|
||||
break;
|
||||
|
||||
default:
|
||||
$rauth->password = $password;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$rauth->start()) {
|
||||
printf("Radius start: %s<br/>\n", $rauth->getError());
|
||||
exit;
|
||||
@@ -122,6 +168,9 @@ class auth_plugin_radius extends auth_plugin_base {
|
||||
if (!isset ($config->nasport)) {
|
||||
$config->nasport = '1812';
|
||||
}
|
||||
if (!isset($config->radiustype)) {
|
||||
$config->radiustype = 'PAP';
|
||||
}
|
||||
if (!isset ($config->secret)) {
|
||||
$config->secret = '';
|
||||
}
|
||||
@@ -134,6 +183,7 @@ class auth_plugin_radius extends auth_plugin_base {
|
||||
set_config('nasport', $config->nasport, 'auth/radius');
|
||||
set_config('secret', $config->secret, 'auth/radius');
|
||||
set_config('changepasswordurl', $config->changepasswordurl, 'auth/radius');
|
||||
set_config('radiustype', $config->radiustype, 'auth/radius');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+31
-4
@@ -1,10 +1,12 @@
|
||||
<?php
|
||||
|
||||
// TODO: this generates broken file errors, needs safer test -JH
|
||||
|
||||
// Is Auth/RADIUS really there?
|
||||
if (!defined('Auth_RADIUS_PAP') or !class_exists(Auth_RADIUS_PAP) or !include_once('Auth/RADIUS.php')) {
|
||||
print '<p style="text-align:center; color: red"><strong>Warning: The Auth_RADIUS module does not seem to be present. Please ensure it is installed and enabled.</strong></p>';
|
||||
if (!extension_loaded('radius')) {
|
||||
print '<div class="box errorbox errorboxcontent"><p class="errormessage"><strong>Warning: The PHP RADIUS extension is not present. Please ensure it is installed and enabled.</strong></p></div>';
|
||||
}
|
||||
include_once 'Auth/RADIUS.php';
|
||||
if (!class_exists('Auth_RADIUS')) {
|
||||
print '<div class="box errorbox errorboxcontent"><p class="errormessage"><strong>Warning: There is a problem with the PHP Pear Auth_RADIUS package. Please ensure it is installed correctly.</strong></p></div>';
|
||||
}
|
||||
|
||||
// set to defaults if undefined
|
||||
@@ -14,6 +16,9 @@ if (!isset($config->host)) {
|
||||
if (!isset($config->nasport)) {
|
||||
$config->nasport = '1812';
|
||||
}
|
||||
if (!isset($config->radiustype)) {
|
||||
$config->radiustype = 'PAP';
|
||||
}
|
||||
if (!isset($config->secret)) {
|
||||
$config->secret = '';
|
||||
}
|
||||
@@ -54,6 +59,28 @@ if (!isset($config->changepasswordurl)) {
|
||||
<td><?php print_string('auth_radiusnasport', 'auth') ?></td>
|
||||
</tr>
|
||||
|
||||
<tr valign="top" >
|
||||
<td align="right"><?php print_string('auth_radiustype_key', 'auth') ?>: </td>
|
||||
<td>
|
||||
<?php
|
||||
|
||||
$radiustype = array();
|
||||
$radiustype['PAP'] = get_string('auth_radiustypepap', 'auth');
|
||||
$radiustype['CHAP_MD5'] = get_string('auth_radiustypechapmd5', 'auth');
|
||||
$radiustype['MSCHAPv1'] = get_string('auth_radiustypemschapv1', 'auth');
|
||||
$radiustype['MSCHAPv2'] = get_string('auth_radiustypemschapv2', 'auth');
|
||||
choose_from_menu($radiustype, 'radiustype', $config->radiustype, '');
|
||||
|
||||
if (isset($err['radiustype'])) {
|
||||
formerr($err['radiustype']);
|
||||
}
|
||||
|
||||
?>
|
||||
</td>
|
||||
<td><?php print_string('auth_radiustype', 'auth') ?></td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr valign="top" >
|
||||
<td align="right"><?php print_string('auth_radiussecret_key', 'auth') ?>: </td>
|
||||
<td>
|
||||
|
||||
+118
-10
@@ -2,8 +2,8 @@ Shibboleth Authentication for Moodle
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Requirements:
|
||||
- Shibboleth target 1.1 or later. See documentation for your Shibboleth
|
||||
federation on how to set up Shibboleth.
|
||||
- Shibboleth Service Provider 1.3 or newer. Recommended is 2.1 or newer.
|
||||
See documentation for your Shibboleth federation on how to set up Shibboleth.
|
||||
|
||||
Changes:
|
||||
- 11. 2004: Created by Markus Hagman
|
||||
@@ -20,6 +20,11 @@ Changes:
|
||||
- 10. 2007: Removed the requirement for email address, surname and given name
|
||||
attributes on request of Markus Hagman
|
||||
- 11. 2007: Integrated WAYF Service in Moodle
|
||||
- 12. 2008: Shibboleth 2.x and Single Logout support added
|
||||
- 1. 2008: Added logout hook and moved Shibboleth config strings to utf8 auth
|
||||
language files.
|
||||
- 3. 2009: Added various improvements and bug fixes reported by Ina Müller from
|
||||
university Tuebingen and Peter Ellis of University of Washington
|
||||
|
||||
Moodle Configuration with Dual login
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -39,17 +44,30 @@ Moodle Configuration with Dual login
|
||||
with something that fits your needs, e.g. 'require affiliation student'.
|
||||
|
||||
For IIS you have protect the auth/shibboleth directory directly in the
|
||||
RequestMap of the Shibboleth configuration file (shibboleth.xml). See
|
||||
RequestMap of the Shibboleth configuration file (shibboleth.xml or
|
||||
shibboleth2.xml).
|
||||
|
||||
https://spaces.internet2.edu/display/SHIB/xmlaccesscontrol?topic=XMLAccessControl
|
||||
--
|
||||
<Path name="moodle" requireSession="false" >
|
||||
<Path name="auth/shibboleth/index.php" requireSession="true" >
|
||||
<AccessControl>
|
||||
...
|
||||
</AccessControl>
|
||||
</Path>
|
||||
</Path>
|
||||
--
|
||||
|
||||
Also see:
|
||||
https://spaces.internet2.edu/display/SHIB2/NativeSPRequestMapper and
|
||||
https://spaces.internet2.edu/display/SHIB2/NativeSPAccessControl
|
||||
|
||||
2. As Moodle admin, go to the 'Administrations >> Users >> Authentication
|
||||
Options' and click on the the 'Shibboleth' settings.
|
||||
2. As Moodle admin, go to the 'Administrations >> Users >> Authentication' and
|
||||
click on the the 'Shibboleth' settings.
|
||||
|
||||
3. Fill in the fields of the form. The fields 'Username', 'First name',
|
||||
'Surname', etc. should contain the name of the environment variables of the
|
||||
Shibboleth attributes that you want to map onto the corresponding Moodle
|
||||
variable (e.g. 'HTTP_SHIB_PERSON_SURNAME' for the person's last name, refer
|
||||
variable (e.g. 'Shib-Person-surname' for the person's last name, refer
|
||||
the Shibboleth documentation or the documentation of your Shibboleth
|
||||
federation for information on which attributes are available).
|
||||
Especially the 'Username' field is of great importance because
|
||||
@@ -72,14 +90,16 @@ Moodle Configuration with Dual login
|
||||
to the the URL of the file 'moodle/auth/shibboleth/index.php'.
|
||||
This will enforce Shibboleth login.
|
||||
|
||||
4.b If you want to use the Moodle internal WAYF service, you have to activate it
|
||||
4.b If you want to use the Moodle integrated WAYF service, you have to activate it
|
||||
in the Moodle Shibboleth authentication settings by checking the
|
||||
'Moodle WAYF Service' checkbox and providing a list of entity IDs in the
|
||||
'Identity Providers' textarea together with a name and an optional
|
||||
SessionInitiator URL, which usually is an absolute or relative URL pointing
|
||||
to the same host. If no SessionInitiator URL is given, the default one
|
||||
'/Shibboleth.sso' will be used.
|
||||
'/Shibboleth.sso' (only works for Shibboleth 1.3.x) will be used. For
|
||||
Shibboleth 2.x you have to add '/Shibboleth.sso/DS' as a SessionInitiator.
|
||||
Also see https://spaces.internet2.edu/display/SHIB/SessionInitiator
|
||||
and https://spaces.internet2.edu/display/SHIB2/NativeSPSessionInitiator
|
||||
|
||||
Important Note: If you upgraded from a previous version of Moodle and now
|
||||
want to use the integrated WAYF, you have to make sure that
|
||||
@@ -87,7 +107,7 @@ Moodle Configuration with Dual login
|
||||
moodle/auth/shibboleth/ is protected but *not* the other
|
||||
scripts and especially not the login.php script.
|
||||
|
||||
5. Save the changes for the 'Shibboleth settings'. T
|
||||
5. Save the changes for the 'Shibboleth settings'.
|
||||
|
||||
Important Note: If you went for 4.b (integrated WAYF service), saving the
|
||||
settings will overwrite the Moodle Alternate Login URL
|
||||
@@ -199,6 +219,94 @@ Example file:
|
||||
?>
|
||||
--
|
||||
|
||||
How to upgrade your Service Provider to 2.x
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
In case your upgrade your Service Provider 1.3.x to 2.x, be aware of the fact
|
||||
that in version 2.0 the default behaviour regarding attribute propagation
|
||||
changed.
|
||||
While the Service Provider 1.3.x published the Shibboleth attributes to the
|
||||
web server environment as HTTP Request headers, the Service Provider 2.x
|
||||
publishes attributes as environment variables, which increases the security for
|
||||
some platforms.
|
||||
However, this change has the effect that the attribute names change.
|
||||
E.g. while the surname attribute was published as 'HTTP_SHIB_PERSON_SURNAME'
|
||||
with 1.3.x, this attribute will be available in $_SERVER['Shib-Person-surname']
|
||||
or depending on your /etc/shibboleth/attribute-map.xml file just as
|
||||
$_SERVER['sn'].
|
||||
Because Moodle needs to know what Shibboleth attributes it shall map onto which
|
||||
Moodle user profile field, one has to make sure the mapping is updated as well
|
||||
after the Service Provider upgrade.
|
||||
|
||||
********************************************************************************
|
||||
Because you risk locking yourself out of Moodle it is strongly
|
||||
recommended to use the following approach when upgrading the Service Provider:
|
||||
1. Enable manual authentication before the upgrade.
|
||||
2. Make sure that you have at least one manual account with administration
|
||||
privileges working before upgrading your Service Provider to 2.x.
|
||||
3. After the SP upgrade, use this account to log into Moodle and adapt the
|
||||
attribute mapping in 'Site Administration -> Users -> Shibboleth' to reflect
|
||||
the changed attribute names.
|
||||
You find the attribute names in the file /etc/shibboleth/attribute-map.xml
|
||||
listed as the 'id' value of an attribute definition.
|
||||
4. If you are using the integrated WAYF, you may have to set the third parameter
|
||||
of each entry to '/Shibboleth.sso/DS'
|
||||
5. Test the login with a Shibboleth account
|
||||
6. If all is working, disable manual authentication again
|
||||
********************************************************************************
|
||||
|
||||
How to add logout support
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
In order make Moodle support Shibboleth logout, one has to make the Shibboleth
|
||||
Service Provider (SP) aware of the Moodle logout capability. Only then the SP
|
||||
can trigger Moodle's front or back channel logout handler.
|
||||
|
||||
To make the SP aware of the Moodle logout, you have to add the following to the
|
||||
Shibboleth main configuration file shibboleth2.xml (usually in /etc/shibboleth/)
|
||||
just before the <MetadataProvider> element.
|
||||
|
||||
--
|
||||
<Notify
|
||||
Channel="back"
|
||||
Location="https://#YOUR_MOODLE_HOSTNAME#/moodle/auth/shibboleth/logout.php" />
|
||||
|
||||
<!--
|
||||
If possible, you should use only the back channel logout once it is working.
|
||||
-->
|
||||
<!--
|
||||
<Notify
|
||||
Channel="front"
|
||||
Location="https://#YOUR_MOODLE_HOSTNAME#/moodle/auth/shibboleth/logout.php" />
|
||||
-->
|
||||
--
|
||||
|
||||
Then restart the Shibboleth daemon and check the log file for errors. If there
|
||||
were no errors, you can test the logout feature by accessing Moodle,
|
||||
authenticating via Shibboleth and the access the URL:
|
||||
#YOUR_MOODLE_HOSTNAME#/Shibboleth.sso/Logout (assuming you have a standard
|
||||
Shibboleth installation). If everything worked well, you should see a Shibboleth
|
||||
page saying that you were successfully logged out and if you go back to Moodle
|
||||
you also should be logged out from Moodle.
|
||||
|
||||
Requirements:
|
||||
- PHP needs the Soap Extension, which maybe must installed manually:
|
||||
More information is available here http://ch.php.net/soap
|
||||
- Logout only works with Shibboleth Service Provider 2.1 or higher
|
||||
|
||||
Limitations:
|
||||
Single Logout is only supported when SAML2 is used at the SP and the IdP.
|
||||
As of December 2008, the Shibboleth Identity Provider 2.1.1 does not yet support
|
||||
Single Logout (SLO). Therefore, the single logout feature cannot be used yet.
|
||||
One of the reasons why SLO isn't supported yet is because there aren't many
|
||||
applications yet that were adapted to support front and back channel
|
||||
logout. Hopefully, the Moodle logout helps to motivate the developers to
|
||||
implement SLO :)
|
||||
|
||||
Also see https://spaces.internet2.edu/display/SHIB2/SLOIssues and
|
||||
https://spaces.internet2.edu/display/SHIB2/NativeSPLogoutInitiator for some
|
||||
background information on this topic.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
In case of problems and questions with Shibboleth authentication, contact
|
||||
Lukas Haemmerle <lukas.haemmerle@switch.ch> or Markus Hagman <hagman@hytti.uku.fi>
|
||||
|
||||
@@ -51,9 +51,27 @@ class auth_plugin_shibboleth extends auth_plugin_base {
|
||||
* @return bool Authentication success or failure.
|
||||
*/
|
||||
function user_login($username, $password) {
|
||||
|
||||
global $SESSION;
|
||||
|
||||
// If we are in the shibboleth directory then we trust the server var
|
||||
if (!empty($_SERVER[$this->config->user_attribute])) {
|
||||
// Associate Shibboleth session with user for SLO preparation
|
||||
$sessionkey = '';
|
||||
if (isset($_SERVER['Shib-Session-ID'])){
|
||||
// This is only available for Shibboleth 2.x SPs
|
||||
$sessionkey = $_SERVER['Shib-Session-ID'];
|
||||
} else {
|
||||
// Try to find out using the user's cookie
|
||||
foreach ($_COOKIE as $name => $value){
|
||||
if (eregi('_shibsession_', $name)){
|
||||
$sessionkey = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set shibboleth session ID for logout
|
||||
$SESSION->shibboleth_session_id = $sessionkey;
|
||||
|
||||
return (strtolower($_SERVER[$this->config->user_attribute]) == strtolower($username));
|
||||
} else {
|
||||
// If we are not, the user has used the manual login and the login name is
|
||||
@@ -165,6 +183,37 @@ class auth_plugin_shibboleth extends auth_plugin_base {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for logout page
|
||||
*
|
||||
*/
|
||||
function logoutpage_hook() {
|
||||
global $redirect;
|
||||
|
||||
// Only do this if logout handler is defined
|
||||
if (
|
||||
isset($this->config->logout_handler)
|
||||
&& !empty($this->config->logout_handler)
|
||||
){
|
||||
// Check if there is an alternative logout return url defined
|
||||
if (
|
||||
isset($this->config->logout_return_url)
|
||||
&& !empty($this->config->logout_return_url)
|
||||
){
|
||||
// Set temp_redirect to alternative return url
|
||||
$temp_redirect = $this->config->logout_return_url;
|
||||
} else {
|
||||
// Backup old redirect url
|
||||
$temp_redirect = $redirect;
|
||||
}
|
||||
|
||||
// Overwrite redirect in order to send user to Shibboleth logout page and let him return back
|
||||
$redirect = $this->config->logout_handler.'?return='.urlencode($temp_redirect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Prints a form for configuring this authentication plugin.
|
||||
@@ -225,17 +274,24 @@ class auth_plugin_shibboleth extends auth_plugin_base {
|
||||
if (isset($config->organization_selection) && !empty($config->organization_selection)) {
|
||||
set_config('organization_selection', $config->organization_selection, 'auth/shibboleth');
|
||||
}
|
||||
set_config('logout_handler', $config->logout_handler, 'auth/shibboleth');
|
||||
set_config('logout_return_url', $config->logout_return_url, 'auth/shibboleth');
|
||||
set_config('login_name', $config->login_name, 'auth/shibboleth');
|
||||
set_config('convert_data', $config->convert_data, 'auth/shibboleth');
|
||||
set_config('auth_instructions', $config->auth_instructions, 'auth/shibboleth');
|
||||
set_config('changepasswordurl', $config->changepasswordurl, 'auth/shibboleth');
|
||||
|
||||
// Overwrite alternative login URL if integrated WAYF is used
|
||||
if (isset($config->alt_login) && $config->alt_login == 'on'){
|
||||
set_config('alt_login', $config->alt_login, 'auth/shibboleth');
|
||||
set_config('alternateloginurl', $CFG->wwwroot.'/auth/shibboleth/login.php');
|
||||
} else {
|
||||
set_config('alt_login', 'off', 'auth/shibboleth');
|
||||
set_config('alternateloginurl', '');
|
||||
// Check if integrated WAYF was enabled and is now turned off
|
||||
// If it was and only then, reset the Moodle alternate URL
|
||||
if ($this->config->alt_login == 'on'){
|
||||
set_config('alt_login', 'off', 'auth/shibboleth');
|
||||
set_config('alternateloginurl', '');
|
||||
}
|
||||
$config->alt_login = 'off';
|
||||
}
|
||||
|
||||
|
||||
+32
-10
@@ -45,7 +45,7 @@
|
||||
</tr>
|
||||
|
||||
<tr valign="top">
|
||||
<td align="right">Moodle WAYF Service:</td>
|
||||
<td align="right"><?php print_string("auth_shib_integrated_wayf", "auth") ?>:</td>
|
||||
<td>
|
||||
<input name="alt_login" type="checkbox" <?php
|
||||
if ( isset($config->alt_login) and $config->alt_login == 'on' ){
|
||||
@@ -53,24 +53,24 @@
|
||||
}
|
||||
?> />
|
||||
</td>
|
||||
<td>If you check this, Moodle will use its own WAYF service instead of the one configured for Shibboleth. Moodle will display a drop-down list on this alternative login page where the user has to select his Identity Provider.</td>
|
||||
<td><?php print_string("auth_shib_integrated_wayf_description", "auth") ?></td>
|
||||
</tr>
|
||||
|
||||
<tr valign="top">
|
||||
<td align="right">Identity Providers:</td>
|
||||
<td align="right"><?php print_string("auth_shib_idp_list", "auth") ?>:</td>
|
||||
<td>
|
||||
<textarea name="organization_selection" rows="10" cols="30" style="overflow: auto; white-space: nowrap;"
|
||||
><?php
|
||||
if (!isset($config->organization_selection)){
|
||||
echo 'urn:mace:organization1:providerID, Example Organization 1
|
||||
https://another.idp-id.com/shibboleth, Other Example Organization
|
||||
https://another.idp-id.com/shibboleth, Other Example Organization, /Shibboleth.sso/DS/SWITCHaai
|
||||
urn:mace:organization2:providerID, Example Organization 2, /Shibboleth.sso/WAYF/SWITCHaai';
|
||||
} else {
|
||||
echo $config->organization_selection;
|
||||
}
|
||||
?>
|
||||
</textarea>
|
||||
<?
|
||||
<?php
|
||||
if (isset($config->organization_selection) && empty($config->organization_selection) && isset($config->alt_login) && $config->alt_login == 'on') {
|
||||
echo '<br/><font color="red">';
|
||||
print_string("auth_shib_no_organizations_warning", "auth");
|
||||
@@ -78,13 +78,35 @@ urn:mace:organization2:providerID, Example Organization 2, /Shibboleth.sso/WAYF/
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td>Provide a list of Identity Provider entityIDs to let the user choose from on the login page.
|
||||
On each line there must be a comma-separated tuple for entityID of the IdP (see the Shibboleth metadata file) and Name of IdP as it shall be displayed in the drow-down list.
|
||||
As an optional third parameter you can add the location of a Shibboleth session initiator that shall be used in case your Moodle installation is part of a multi federation setup.</td>
|
||||
<td><?php print_string("auth_shib_idp_list_description", "auth") ?></td>
|
||||
</tr>
|
||||
|
||||
<tr valign="top">
|
||||
<td align="right">Authentication Method Name:</td>
|
||||
<td align="right"><?php print_string("auth_shib_logout_url", "auth") ?>:</td>
|
||||
<td>
|
||||
<input name="logout_handler" type="text" size="30" value="<?php
|
||||
if ( isset($config->logout_handler) and !empty($config->logout_handler)){
|
||||
echo $config->logout_handler;
|
||||
}
|
||||
?>" />
|
||||
</td>
|
||||
<td><?php print_string("auth_shib_logout_url_description", "auth") ?></td>
|
||||
</tr>
|
||||
|
||||
<tr valign="top">
|
||||
<td align="right"><?php print_string("auth_shib_logout_return_url", "auth") ?>:</td>
|
||||
<td>
|
||||
<input name="logout_return_url" type="text" size="30" value="<?php
|
||||
if ( isset($config->logout_return_url) and !empty($config->logout_return_url)){
|
||||
echo $config->logout_return_url;
|
||||
}
|
||||
?>" />
|
||||
</td>
|
||||
<td><?php print_string("auth_shib_logout_return_url_description", "auth") ?></td>
|
||||
</tr>
|
||||
|
||||
<tr valign="top">
|
||||
<td align="right"><?php print_string("auth_shib_auth_method", "auth") ?>:</td>
|
||||
<td>
|
||||
<input name="login_name" type="text" size="30" value="<?php
|
||||
if ( isset($config->login_name) and !empty($config->login_name)){
|
||||
@@ -94,7 +116,7 @@ As an optional third parameter you can add the location of a Shibboleth session
|
||||
}
|
||||
?>" />
|
||||
</td>
|
||||
<td>Provide a name for the Shibboleth authentication method that is familiar to your users. This could be the name of your Shibboleth federation, e.g. "SWITCHaai Login" or "InCommon Login" and so on.</td>
|
||||
<td><?php print_string("auth_shib_auth_method_description", "auth") ?></td>
|
||||
</tr>
|
||||
|
||||
<tr valign="top">
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
|
||||
// If we can find any (user independent) Shibboleth attributes but no user
|
||||
// attributes we probably didn't receive any user attributes
|
||||
elseif (!empty($_SERVER['HTTP_SHIB_APPLICATION_ID'])) {
|
||||
elseif (!empty($_SERVER['HTTP_SHIB_APPLICATION_ID']) || !empty($_SERVER['Shib-Application-ID'])) {
|
||||
print_error('shib_no_attributes_error', 'auth' , '', '\''.$pluginconfig->user_attribute.'\', \''.$pluginconfig->field_map_firstname.'\', \''.$pluginconfig->field_map_lastname.'\' and \''.$pluginconfig->field_map_email.'\'');
|
||||
} else {
|
||||
print_error('shib_not_set_up_error', 'auth');
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php // $Id$
|
||||
|
||||
|
||||
require_once("../../config.php");
|
||||
require_once($CFG->dirroot."/auth/shibboleth/auth.php");
|
||||
|
||||
@@ -61,6 +60,8 @@ httpsrequired();
|
||||
if (isset($IdPs[$selectedIdP][1]) && !empty($IdPs[$selectedIdP][1])){
|
||||
header('Location: '.$IdPs[$selectedIdP][1].'?providerId='. urlencode($selectedIdP) .'&target='. urlencode($CFG->wwwroot.'/auth/shibboleth/index.php'));
|
||||
} else {
|
||||
// TODO: This has to be changed to /Shibboleth.sso/DS?entityId= for
|
||||
// Shibbolet 2.x sometime...
|
||||
header('Location: /Shibboleth.sso?providerId='. urlencode($selectedIdP) .'&target='. urlencode($CFG->wwwroot.'/auth/shibboleth/index.php'));
|
||||
}
|
||||
} elseif (isset($_POST['idp']) && !isset($IdPs[$_POST['idp']])) {
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
<?php // $Id$
|
||||
|
||||
// Implements logout for Shibboleth authenticated users according to:
|
||||
// - https://spaces.internet2.edu/display/SHIB2/NativeSPLogoutInitiator
|
||||
// - https://spaces.internet2.edu/display/SHIB2/NativeSPNotify
|
||||
|
||||
require_once("../../config.php");
|
||||
|
||||
require_once($CFG->dirroot."/auth/shibboleth/auth.php");
|
||||
|
||||
|
||||
// Find out whether host supports https
|
||||
$protocol = 'http://';
|
||||
if ( isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on'){
|
||||
$protocol = 'https://';
|
||||
}
|
||||
|
||||
// Front channel logout
|
||||
if (
|
||||
isset($_GET['return'])
|
||||
&& isset($_GET['action'])
|
||||
&& $_GET['action'] == 'logout'
|
||||
){
|
||||
|
||||
// Logout out user from application
|
||||
// E.g. destroy application session/cookie etc
|
||||
require_logout();
|
||||
|
||||
// Finally, send user to the return URL
|
||||
redirect($_GET['return']);
|
||||
}
|
||||
|
||||
// Back channel logout
|
||||
elseif (!empty($HTTP_RAW_POST_DATA)) {
|
||||
|
||||
// Requires PHP 5
|
||||
|
||||
|
||||
// Set SOAP header
|
||||
$server = new SoapServer($protocol.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'/LogoutNotification.wsdl');
|
||||
|
||||
|
||||
$server->addFunction("LogoutNotification");
|
||||
$server->handle();
|
||||
}
|
||||
|
||||
// Return WSDL
|
||||
else {
|
||||
|
||||
header('Content-Type: text/xml');
|
||||
|
||||
echo <<<WSDL
|
||||
<?xml version ="1.0" encoding ="UTF-8" ?>
|
||||
<definitions name="LogoutNotification"
|
||||
targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
|
||||
xmlns:notify="urn:mace:shibboleth:2.0:sp:notify"
|
||||
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||
xmlns="http://schemas.xmlsoap.org/wsdl/">
|
||||
|
||||
<!--
|
||||
This page either has to be called with the GET arguments 'action' and 'return' via
|
||||
a redirect from the Shibboleth Service Provider logout handler (front-channel
|
||||
logout) or via a SOAP request by a Shibboleth Service Provider (back-channel
|
||||
logout).
|
||||
Because neither of these two variants seems to be the case, the WSDL file for
|
||||
the web service is returned.
|
||||
|
||||
For more information see:
|
||||
- https://spaces.internet2.edu/display/SHIB2/NativeSPLogoutInitiator
|
||||
- https://spaces.internet2.edu/display/SHIB2/NativeSPNotify
|
||||
-->
|
||||
|
||||
<types>
|
||||
<schema targetNamespace="urn:mace:shibboleth:2.0:sp:notify"
|
||||
xmlns="http://www.w3.org/2000/10/XMLSchema"
|
||||
xmlns:notify="urn:mace:shibboleth:2.0:sp:notify">
|
||||
|
||||
<simpleType name="string">
|
||||
<restriction base="string">
|
||||
<minLength value="1"/>
|
||||
</restriction>
|
||||
</simpleType>
|
||||
|
||||
<element name="OK" type="notify:OKType"/>
|
||||
<complexType name="OKType">
|
||||
<sequence/>
|
||||
</complexType>
|
||||
|
||||
</schema>
|
||||
</types>
|
||||
|
||||
<message name="getLogoutNotificationRequest">
|
||||
<part name="SessionID" type="notify:string" />
|
||||
</message>
|
||||
|
||||
<message name="getLogoutNotificationResponse" >
|
||||
<part name="OK"/>
|
||||
</message>
|
||||
|
||||
<portType name="LogoutNotificationPortType">
|
||||
<operation name="LogoutNotification">
|
||||
<input message="getLogoutNotificationRequest"/>
|
||||
<output message="getLogoutNotificationResponse"/>
|
||||
</operation>
|
||||
</portType>
|
||||
|
||||
<binding name="LogoutNotificationBinding" type="notify:LogoutNotificationPortType">
|
||||
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
|
||||
<operation name="LogoutNotification">
|
||||
<soap:operation soapAction="urn:xmethods-logout-notification#LogoutNotification"/>
|
||||
</operation>
|
||||
</binding>
|
||||
|
||||
<service name="LogoutNotificationService">
|
||||
<port name="LogoutNotificationPort" binding="notify:LogoutNotificationBinding">
|
||||
<soap:address location="{$protocol}{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}"/>
|
||||
</port>
|
||||
</service>
|
||||
</definitions>
|
||||
WSDL;
|
||||
exit;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function LogoutNotification($SessionID){
|
||||
|
||||
global $CFG, $SESSION;
|
||||
|
||||
// Delete session of user using $SessionID
|
||||
if(empty($CFG->dbsessions)) {
|
||||
|
||||
// File session
|
||||
$dir = $CFG->dataroot .'/sessions';
|
||||
if (is_dir($dir)) {
|
||||
if ($dh = opendir($dir)) {
|
||||
// Read all session files
|
||||
while (($file = readdir($dh)) !== false) {
|
||||
// Check if it is a file
|
||||
if (is_file($dir.'/'.$file)){
|
||||
$session_key = ereg_replace('sess_', '', $file);
|
||||
|
||||
// Read session file data
|
||||
$data = file($dir.'/'.$file);
|
||||
if (isset($data[0])){
|
||||
$user_session = unserializesession($data[0]);
|
||||
|
||||
// Check if we have found session that shall be deleted
|
||||
if (isset($user_session['SESSION']) && isset($user_session['SESSION']->shibboleth_session_id)){
|
||||
|
||||
// If there is a match, delete file
|
||||
if ($user_session['SESSION']->shibboleth_session_id == $SessionID){
|
||||
// Delete session file
|
||||
if (!unlink($dir.'/'.$file)){
|
||||
return new SoapFault('LogoutError', 'Could not delete Moodle session file.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// DB Session
|
||||
if (!empty($CFG->sessiontimeout)) {
|
||||
$ADODB_SESS_LIFE = $CFG->sessiontimeout;
|
||||
}
|
||||
|
||||
if ($user_session_data = get_records_sql('SELECT sesskey, sessdata FROM '. $CFG->prefix .'sessions2 WHERE expiry > NOW()')) {
|
||||
foreach ($user_session_data as $session_data) {
|
||||
|
||||
// Get user session
|
||||
$user_session = adodb_unserialize( urldecode($session_data->sessdata) );
|
||||
|
||||
if (isset($user_session['SESSION']) && isset($user_session['SESSION']->shibboleth_session_id)){
|
||||
|
||||
// If there is a match, delete file
|
||||
if ($user_session['SESSION']->shibboleth_session_id == $SessionID){
|
||||
// Delete this session entry
|
||||
if (ADODB_Session::destroy($session_data->sesskey) !== true){
|
||||
return new SoapFault('LogoutError', 'Could not delete Moodle session entry in database.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If now SoapFault was thrown the function will return OK as the SP assumes
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
// Same function as in adodb, but cannot be used for file session for some reason...
|
||||
function unserializesession( $serialized_string ){
|
||||
$variables = array( );
|
||||
$a = preg_split( "/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
|
||||
for( $i = 0; $i < count( $a ); $i = $i+2 ) {
|
||||
$variables[$a[$i]] = unserialize( $a[$i+1] );
|
||||
}
|
||||
return( $variables );
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -337,6 +337,9 @@ function schedule_backup_course_configure($course,$starttime = 0) {
|
||||
if (!isset($backup_config->backup_sche_sitefiles)) {
|
||||
$backup_config->backup_sche_sitefiles = 1;
|
||||
}
|
||||
if (!isset($backup_config->backup_sche_gradebook_history)) {
|
||||
$backup_config->backup_sche_gradebook_history = 0;
|
||||
}
|
||||
if (!isset($backup_config->backup_sche_messages)) {
|
||||
$backup_config->backup_sche_messages = 0;
|
||||
}
|
||||
@@ -439,6 +442,7 @@ function schedule_backup_course_configure($course,$starttime = 0) {
|
||||
$preferences->backup_user_files = $backup_config->backup_sche_userfiles;
|
||||
$preferences->backup_course_files = $backup_config->backup_sche_coursefiles;
|
||||
$preferences->backup_site_files = $backup_config->backup_sche_sitefiles;
|
||||
$preferences->backup_gradebook_history = $backup_config->backup_sche_gradebook_history;
|
||||
$preferences->backup_messages = $backup_config->backup_sche_messages;
|
||||
$preferences->backup_blogs = $backup_config->backup_sche_blogs;
|
||||
$preferences->backup_course = $course->id;
|
||||
|
||||
+176
-111
@@ -235,7 +235,7 @@
|
||||
}
|
||||
rs_close($backup_users);
|
||||
//Gets the user data
|
||||
$info[0][0] = get_string("userswithfiles");
|
||||
$info[0][0] = get_string('userswithfiles', 'moodle');
|
||||
$info[0][1] = $count;
|
||||
|
||||
return $info;
|
||||
@@ -483,6 +483,8 @@
|
||||
fwrite ($bf,full_tag("DATE",2,false,$preferences->backup_unique_code));
|
||||
//The original site wwwroot
|
||||
fwrite ($bf,full_tag("ORIGINAL_WWWROOT",2,false,$CFG->wwwroot));
|
||||
//The original site identifier. MD5 hashed for security.
|
||||
fwrite ($bf,full_tag("ORIGINAL_SITE_IDENTIFIER_HASH",2,false,md5(get_site_identifier())));
|
||||
//The zip method used
|
||||
if (!empty($CFG->zip)) {
|
||||
$zipmethod = 'external';
|
||||
@@ -587,7 +589,7 @@
|
||||
fwrite ($bf,full_tag("SITEFILES",3,false,"false"));
|
||||
}
|
||||
//The gradebook histories
|
||||
if ($preferences->backup_gradebook_history == 1) {
|
||||
if (empty($CFG->disablegradehistory) && $preferences->backup_gradebook_history == 1) {
|
||||
fwrite ($bf,full_tag("GRADEBOOKHISTORIES",3,false,"true"));
|
||||
} else {
|
||||
fwrite ($bf,full_tag("GRADEBOOKHISTORIES",3,false,"false"));
|
||||
@@ -1272,11 +1274,16 @@
|
||||
|
||||
// Use a recordset to for the memory handling on to
|
||||
// the DB and run faster
|
||||
// Note the outer join with mnet_host: It shouldn't be neccesary
|
||||
// but there are some sites having mnet_host records missing
|
||||
// and that causes backup to fail (no users). Being a bit more
|
||||
// flexible here (outer joing) we bypass the problem and doesn't
|
||||
// cause more troubles. Eloy - MDL-16879
|
||||
$users = get_recordset_sql("SELECT b.old_id, b.table_name, b.info,
|
||||
u.*, m.wwwroot
|
||||
FROM {$CFG->prefix}backup_ids b
|
||||
JOIN {$CFG->prefix}user u ON b.old_id=u.id
|
||||
JOIN {$CFG->prefix}mnet_host m ON u.mnethostid=m.id
|
||||
LEFT JOIN {$CFG->prefix}mnet_host m ON u.mnethostid=m.id
|
||||
WHERE b.backup_code = '$preferences->backup_unique_code' AND
|
||||
b.table_name = 'user'");
|
||||
|
||||
@@ -1333,7 +1340,7 @@
|
||||
fwrite ($bf,full_tag("AJAX",4,false,$user->ajax));
|
||||
fwrite ($bf,full_tag("AUTOSUBSCRIBE",4,false,$user->autosubscribe));
|
||||
fwrite ($bf,full_tag("TRACKFORUMS",4,false,$user->trackforums));
|
||||
if ($user->mnethostid != $CFG->mnet_localhost_id) {
|
||||
if ($user->mnethostid != $CFG->mnet_localhost_id && !empty($user->wwwroot)) {
|
||||
fwrite ($bf,full_tag("MNETHOSTURL",4,false,$user->wwwroot));
|
||||
}
|
||||
fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$user->timemodified));
|
||||
@@ -1370,11 +1377,11 @@
|
||||
fwrite ($bf,end_tag("ROLES",4,true));
|
||||
|
||||
//Check if we have custom profile fields to backup
|
||||
if ($cpfields = get_records_sql("SELECT uif.shortname, uif.datatype, uid.data
|
||||
if ($cpfields = get_records_sql("SELECT uif.shortname, uif.datatype, uidata.data
|
||||
FROM {$CFG->prefix}user_info_field uif,
|
||||
{$CFG->prefix}user_info_data uid
|
||||
WHERE uif.id = uid.fieldid
|
||||
AND uid.userid = $user->id")) {
|
||||
{$CFG->prefix}user_info_data uidata
|
||||
WHERE uif.id = uidata.fieldid
|
||||
AND uidata.userid = $user->id")) {
|
||||
//Start USER_CUSTOM_PROFILE_FIELDS tag
|
||||
fwrite ($bf,start_tag("USER_CUSTOM_PROFILE_FIELDS",4,true));
|
||||
//Write custom profile fields
|
||||
@@ -1564,8 +1571,8 @@
|
||||
|
||||
$status = backup_gradebook_item_info($bf,$preferences, $backupall);
|
||||
|
||||
// backup gradebook histories
|
||||
if ($preferences->backup_gradebook_history) {
|
||||
// backup gradebook histories (only if grade history is enabled and selected)
|
||||
if (empty($CFG->disablegradehistory) && $preferences->backup_gradebook_history) {
|
||||
$status = backup_gradebook_outcomes_history($bf, $preferences);
|
||||
$status = backup_gradebook_categories_history_info($bf, $preferences);
|
||||
$status = backup_gradebook_items_history_info($bf, $preferences);
|
||||
@@ -1827,28 +1834,28 @@
|
||||
|
||||
// find all grade categories history
|
||||
if ($chs = get_records('grade_categories_history', 'courseid', $preferences->backup_course)) {
|
||||
fwrite ($bf,start_tag("GRADE_CATEGORIES_HISTORIES",5,true));
|
||||
fwrite ($bf,start_tag("GRADE_CATEGORIES_HISTORIES",3,true));
|
||||
foreach ($chs as $ch) {
|
||||
fwrite ($bf,start_tag("GRADE_CATEGORIES_HISTORY",6,true));
|
||||
fwrite ($bf,full_tag("ID",7,false,$ch->id));
|
||||
fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
|
||||
fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
|
||||
fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
|
||||
fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
|
||||
fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
|
||||
fwrite ($bf,full_tag("PARENT",7,false,$ch->parent));
|
||||
fwrite ($bf,full_tag("DEPTH",7,false,$ch->depth));
|
||||
fwrite ($bf,full_tag("PATH",7,false,$ch->path));
|
||||
fwrite ($bf,full_tag("FULLNAME",7,false,$ch->fullname));
|
||||
fwrite ($bf,full_tag("AGGRETGATION",7,false,$ch->aggregation));
|
||||
fwrite ($bf,full_tag("KEEPHIGH",7,false,$ch->keephigh));
|
||||
fwrite ($bf,full_tag("DROPLOW",7,false,$ch->droplow));
|
||||
fwrite ($bf,full_tag("AGGREGATEONLYGRADED",7,false,$ch->aggregateonlygraded));
|
||||
fwrite ($bf,full_tag("AGGREGATEOUTCOMES",7,false,$ch->aggregateoutcomes));
|
||||
fwrite ($bf,full_tag("AGGREGATESUBCATS",7,false,$ch->aggregatesubcats));
|
||||
fwrite ($bf,end_tag("GRADE_CATEGORIES_HISTORY",6,true));
|
||||
fwrite ($bf,start_tag("GRADE_CATEGORIES_HISTORY",4,true));
|
||||
fwrite ($bf,full_tag("ID",5,false,$ch->id));
|
||||
fwrite ($bf,full_tag("ACTION",5,false,$ch->action));
|
||||
fwrite ($bf,full_tag("OLDID",5,false,$ch->oldid));
|
||||
fwrite ($bf,full_tag("SOURCE",5,false,$ch->source));
|
||||
fwrite ($bf,full_tag("TIMEMODIFIED",5,false,$ch->timemodified));
|
||||
fwrite ($bf,full_tag("LOGGEDUSER",5,false,$ch->loggeduser));
|
||||
fwrite ($bf,full_tag("PARENT",5,false,$ch->parent));
|
||||
fwrite ($bf,full_tag("DEPTH",5,false,$ch->depth));
|
||||
fwrite ($bf,full_tag("PATH",5,false,$ch->path));
|
||||
fwrite ($bf,full_tag("FULLNAME",5,false,$ch->fullname));
|
||||
fwrite ($bf,full_tag("AGGRETGATION",5,false,$ch->aggregation));
|
||||
fwrite ($bf,full_tag("KEEPHIGH",5,false,$ch->keephigh));
|
||||
fwrite ($bf,full_tag("DROPLOW",5,false,$ch->droplow));
|
||||
fwrite ($bf,full_tag("AGGREGATEONLYGRADED",5,false,$ch->aggregateonlygraded));
|
||||
fwrite ($bf,full_tag("AGGREGATEOUTCOMES",5,false,$ch->aggregateoutcomes));
|
||||
fwrite ($bf,full_tag("AGGREGATESUBCATS",5,false,$ch->aggregatesubcats));
|
||||
fwrite ($bf,end_tag("GRADE_CATEGORIES_HISTORY",4,true));
|
||||
}
|
||||
$status = fwrite ($bf,end_tag("GRADE_CATEGORIES_HISTORIES",5,true));
|
||||
$status = fwrite ($bf,end_tag("GRADE_CATEGORIES_HISTORIES",3,true));
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
@@ -1864,39 +1871,39 @@
|
||||
JOIN {$CFG->prefix}grade_items gi
|
||||
ON gi.id = ggh.itemid
|
||||
WHERE gi.courseid = $preferences->backup_course")) {
|
||||
fwrite ($bf,start_tag("GRADE_GRADES_HISTORIES",5,true));
|
||||
fwrite ($bf,start_tag("GRADE_GRADES_HISTORIES",3,true));
|
||||
foreach ($chs as $ch) {
|
||||
/// Grades are only sent to backup if the user is one target user
|
||||
if (backup_getid($preferences->backup_unique_code, 'user', $ch->userid)) {
|
||||
fwrite ($bf,start_tag("GRADE_GRADES_HISTORY",6,true));
|
||||
fwrite ($bf,full_tag("ID",7,false,$ch->id));
|
||||
fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
|
||||
fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
|
||||
fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
|
||||
fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
|
||||
fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
|
||||
fwrite ($bf,full_tag("ITEMID",7,false,$ch->itemid));
|
||||
fwrite ($bf,full_tag("USERID",7,false,$ch->userid));
|
||||
fwrite ($bf,full_tag("RAWGRADE",7,false,$ch->rawgrade));
|
||||
fwrite ($bf,full_tag("RAWGRADEMAX",7,false,$ch->rawgrademax));
|
||||
fwrite ($bf,full_tag("RAWGRADEMIN",7,false,$ch->rawgrademin));
|
||||
fwrite ($bf,full_tag("RAWSCALEID",7,false,$ch->rawscaleid));
|
||||
fwrite ($bf,full_tag("USERMODIFIED",7,false,$ch->usermodified));
|
||||
fwrite ($bf,full_tag("FINALGRADE",7,false,$ch->finalgrade));
|
||||
fwrite ($bf,full_tag("HIDDEN",7,false,$ch->hidden));
|
||||
fwrite ($bf,full_tag("LOCKED",7,false,$ch->locked));
|
||||
fwrite ($bf,full_tag("LOCKTIME",7,false,$ch->locktime));
|
||||
fwrite ($bf,full_tag("EXPORTED",7,false,$ch->exported));
|
||||
fwrite ($bf,full_tag("OVERRIDDEN",7,false,$ch->overridden));
|
||||
fwrite ($bf,full_tag("EXCLUDED",7,false,$ch->excluded));
|
||||
fwrite ($bf,full_tag("FEEDBACK",7,false,$ch->feedback));
|
||||
fwrite ($bf,full_tag("FEEDBACKFORMAT",7,false,$ch->feedbackformat));
|
||||
fwrite ($bf,full_tag("INFORMATION",7,false,$ch->information));
|
||||
fwrite ($bf,full_tag("INFORMATIONFORMAT",7,false,$ch->informationformat));
|
||||
fwrite ($bf,end_tag("GRADE_GRADES_HISTORY",6,true));
|
||||
fwrite ($bf,start_tag("GRADE_GRADES_HISTORY",4,true));
|
||||
fwrite ($bf,full_tag("ID",5,false,$ch->id));
|
||||
fwrite ($bf,full_tag("ACTION",5,false,$ch->action));
|
||||
fwrite ($bf,full_tag("OLDID",5,false,$ch->oldid));
|
||||
fwrite ($bf,full_tag("SOURCE",5,false,$ch->source));
|
||||
fwrite ($bf,full_tag("TIMEMODIFIED",5,false,$ch->timemodified));
|
||||
fwrite ($bf,full_tag("LOGGEDUSER",5,false,$ch->loggeduser));
|
||||
fwrite ($bf,full_tag("ITEMID",5,false,$ch->itemid));
|
||||
fwrite ($bf,full_tag("USERID",5,false,$ch->userid));
|
||||
fwrite ($bf,full_tag("RAWGRADE",5,false,$ch->rawgrade));
|
||||
fwrite ($bf,full_tag("RAWGRADEMAX",5,false,$ch->rawgrademax));
|
||||
fwrite ($bf,full_tag("RAWGRADEMIN",5,false,$ch->rawgrademin));
|
||||
fwrite ($bf,full_tag("RAWSCALEID",5,false,$ch->rawscaleid));
|
||||
fwrite ($bf,full_tag("USERMODIFIED",5,false,$ch->usermodified));
|
||||
fwrite ($bf,full_tag("FINALGRADE",5,false,$ch->finalgrade));
|
||||
fwrite ($bf,full_tag("HIDDEN",5,false,$ch->hidden));
|
||||
fwrite ($bf,full_tag("LOCKED",5,false,$ch->locked));
|
||||
fwrite ($bf,full_tag("LOCKTIME",5,false,$ch->locktime));
|
||||
fwrite ($bf,full_tag("EXPORTED",5,false,$ch->exported));
|
||||
fwrite ($bf,full_tag("OVERRIDDEN",5,false,$ch->overridden));
|
||||
fwrite ($bf,full_tag("EXCLUDED",5,false,$ch->excluded));
|
||||
fwrite ($bf,full_tag("FEEDBACK",5,false,$ch->feedback));
|
||||
fwrite ($bf,full_tag("FEEDBACKFORMAT",5,false,$ch->feedbackformat));
|
||||
fwrite ($bf,full_tag("INFORMATION",5,false,$ch->information));
|
||||
fwrite ($bf,full_tag("INFORMATIONFORMAT",5,false,$ch->informationformat));
|
||||
fwrite ($bf,end_tag("GRADE_GRADES_HISTORY",4,true));
|
||||
}
|
||||
}
|
||||
$status = fwrite ($bf,end_tag("GRADE_GRADES_HISTORIES",5,true));
|
||||
$status = fwrite ($bf,end_tag("GRADE_GRADES_HISTORIES",3,true));
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
@@ -1908,43 +1915,43 @@
|
||||
|
||||
// find all grade categories history
|
||||
if ($chs = get_records('grade_items_history','courseid', $preferences->backup_course)) {
|
||||
fwrite ($bf,start_tag("GRADE_ITEM_HISTORIES",5,true));
|
||||
fwrite ($bf,start_tag("GRADE_ITEM_HISTORIES",3,true));
|
||||
foreach ($chs as $ch) {
|
||||
fwrite ($bf,start_tag("GRADE_ITEM_HISTORY",6,true));
|
||||
fwrite ($bf,full_tag("ID",7,false,$ch->id));
|
||||
fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
|
||||
fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
|
||||
fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
|
||||
fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
|
||||
fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
|
||||
fwrite ($bf,full_tag("CATEGORYID",7,false,$ch->categoryid));
|
||||
fwrite ($bf,full_tag("ITEMNAME",7,false,$ch->itemname));
|
||||
fwrite ($bf,full_tag("ITEMTYPE",7,false,$ch->itemtype));
|
||||
fwrite ($bf,full_tag("ITEMMODULE",7,false,$ch->itemmodule));
|
||||
fwrite ($bf,full_tag("ITEMINSTANCE",7,false,$ch->iteminstance));
|
||||
fwrite ($bf,full_tag("ITEMNUMBER",7,false,$ch->itemnumber));
|
||||
fwrite ($bf,full_tag("ITEMINFO",7,false,$ch->iteminfo));
|
||||
fwrite ($bf,full_tag("IDNUMBER",7,false,$ch->idnumber));
|
||||
fwrite ($bf,full_tag("CALCULATION",7,false,$ch->calculation));
|
||||
fwrite ($bf,full_tag("GRADETYPE",7,false,$ch->gradetype));
|
||||
fwrite ($bf,full_tag("GRADEMAX",7,false,$ch->grademax));
|
||||
fwrite ($bf,full_tag("GRADEMIN",7,false,$ch->grademin));
|
||||
fwrite ($bf,full_tag("SCALEID",7,false,$ch->scaleid));
|
||||
fwrite ($bf,full_tag("OUTCOMEID",7,false,$ch->outcomeid));
|
||||
fwrite ($bf,full_tag("GRADEPASS",7,false,$ch->gradepass));
|
||||
fwrite ($bf,full_tag("MULTFACTOR",7,false,$ch->multfactor));
|
||||
fwrite ($bf,full_tag("PLUSFACTOR",7,false,$ch->plusfactor));
|
||||
fwrite ($bf,full_tag("AGGREGATIONCOEF",7,false,$ch->aggregationcoef));
|
||||
fwrite ($bf,full_tag("SORTORDER",7,false,$ch->sortorder));
|
||||
fwrite ($bf,start_tag("GRADE_ITEM_HISTORY",4,true));
|
||||
fwrite ($bf,full_tag("ID",5,false,$ch->id));
|
||||
fwrite ($bf,full_tag("ACTION",5,false,$ch->action));
|
||||
fwrite ($bf,full_tag("OLDID",5,false,$ch->oldid));
|
||||
fwrite ($bf,full_tag("SOURCE",5,false,$ch->source));
|
||||
fwrite ($bf,full_tag("TIMEMODIFIED",5,false,$ch->timemodified));
|
||||
fwrite ($bf,full_tag("LOGGEDUSER",5,false,$ch->loggeduser));
|
||||
fwrite ($bf,full_tag("CATEGORYID",5,false,$ch->categoryid));
|
||||
fwrite ($bf,full_tag("ITEMNAME",5,false,$ch->itemname));
|
||||
fwrite ($bf,full_tag("ITEMTYPE",5,false,$ch->itemtype));
|
||||
fwrite ($bf,full_tag("ITEMMODULE",5,false,$ch->itemmodule));
|
||||
fwrite ($bf,full_tag("ITEMINSTANCE",5,false,$ch->iteminstance));
|
||||
fwrite ($bf,full_tag("ITEMNUMBER",5,false,$ch->itemnumber));
|
||||
fwrite ($bf,full_tag("ITEMINFO",5,false,$ch->iteminfo));
|
||||
fwrite ($bf,full_tag("IDNUMBER",5,false,$ch->idnumber));
|
||||
fwrite ($bf,full_tag("CALCULATION",5,false,$ch->calculation));
|
||||
fwrite ($bf,full_tag("GRADETYPE",5,false,$ch->gradetype));
|
||||
fwrite ($bf,full_tag("GRADEMAX",5,false,$ch->grademax));
|
||||
fwrite ($bf,full_tag("GRADEMIN",5,false,$ch->grademin));
|
||||
fwrite ($bf,full_tag("SCALEID",5,false,$ch->scaleid));
|
||||
fwrite ($bf,full_tag("OUTCOMEID",5,false,$ch->outcomeid));
|
||||
fwrite ($bf,full_tag("GRADEPASS",5,false,$ch->gradepass));
|
||||
fwrite ($bf,full_tag("MULTFACTOR",5,false,$ch->multfactor));
|
||||
fwrite ($bf,full_tag("PLUSFACTOR",5,false,$ch->plusfactor));
|
||||
fwrite ($bf,full_tag("AGGREGATIONCOEF",5,false,$ch->aggregationcoef));
|
||||
fwrite ($bf,full_tag("SORTORDER",5,false,$ch->sortorder));
|
||||
//fwrite ($bf,full_tag("DISPLAY",7,false,$ch->display));
|
||||
//fwrite ($bf,full_tag("DECIMALS",7,false,$ch->decimals));
|
||||
fwrite ($bf,full_tag("HIDDEN",7,false,$ch->hidden));
|
||||
fwrite ($bf,full_tag("LOCKED",7,false,$ch->locked));
|
||||
fwrite ($bf,full_tag("LOCKTIME",7,false,$ch->locktime));
|
||||
fwrite ($bf,full_tag("NEEDSUPDATE",7,false,$ch->needsupdate));
|
||||
fwrite ($bf,end_tag("GRADE_ITEM_HISTORY",6,true));
|
||||
fwrite ($bf,full_tag("HIDDEN",5,false,$ch->hidden));
|
||||
fwrite ($bf,full_tag("LOCKED",5,false,$ch->locked));
|
||||
fwrite ($bf,full_tag("LOCKTIME",5,false,$ch->locktime));
|
||||
fwrite ($bf,full_tag("NEEDSUPDATE",5,false,$ch->needsupdate));
|
||||
fwrite ($bf,end_tag("GRADE_ITEM_HISTORY",4,true));
|
||||
}
|
||||
$status = fwrite ($bf,end_tag("GRADE_ITEM_HISTORIES",5,true));
|
||||
$status = fwrite ($bf,end_tag("GRADE_ITEM_HISTORIES",3,true));
|
||||
|
||||
}
|
||||
return $status;
|
||||
@@ -1956,22 +1963,22 @@
|
||||
|
||||
// find all grade categories history
|
||||
if ($chs = get_records('grade_outcomes_history','courseid', $preferences->backup_course)) {
|
||||
fwrite ($bf,start_tag("GRADE_OUTCOME_HISTORIES",5,true));
|
||||
fwrite ($bf,start_tag("GRADE_OUTCOME_HISTORIES",3,true));
|
||||
foreach ($chs as $ch) {
|
||||
fwrite ($bf,start_tag("GRADE_OUTCOME_HISTORY",6,true));
|
||||
fwrite ($bf,full_tag("ID",7,false,$ch->id));
|
||||
fwrite ($bf,full_tag("OLDID",7,false,$ch->oldid));
|
||||
fwrite ($bf,full_tag("ACTION",7,false,$ch->action));
|
||||
fwrite ($bf,full_tag("SOURCE",7,false,$ch->source));
|
||||
fwrite ($bf,full_tag("TIMEMODIFIED",7,false,$ch->timemodified));
|
||||
fwrite ($bf,full_tag("LOGGEDUSER",7,false,$ch->loggeduser));
|
||||
fwrite ($bf,full_tag("SHORTNAME",7,false,$ch->shortname));
|
||||
fwrite ($bf,full_tag("FULLNAME",7,false,$ch->fullname));
|
||||
fwrite ($bf,full_tag("SCALEID",7,false,$ch->scaleid));
|
||||
fwrite ($bf,full_tag("DESCRIPTION",7,false,$ch->description));
|
||||
fwrite ($bf,end_tag("GRADE_OUTCOME_HISTORY",6,true));
|
||||
fwrite ($bf,start_tag("GRADE_OUTCOME_HISTORY",4,true));
|
||||
fwrite ($bf,full_tag("ID",5,false,$ch->id));
|
||||
fwrite ($bf,full_tag("OLDID",5,false,$ch->oldid));
|
||||
fwrite ($bf,full_tag("ACTION",5,false,$ch->action));
|
||||
fwrite ($bf,full_tag("SOURCE",5,false,$ch->source));
|
||||
fwrite ($bf,full_tag("TIMEMODIFIED",5,false,$ch->timemodified));
|
||||
fwrite ($bf,full_tag("LOGGEDUSER",5,false,$ch->loggeduser));
|
||||
fwrite ($bf,full_tag("SHORTNAME",5,false,$ch->shortname));
|
||||
fwrite ($bf,full_tag("FULLNAME",5,false,$ch->fullname));
|
||||
fwrite ($bf,full_tag("SCALEID",5,false,$ch->scaleid));
|
||||
fwrite ($bf,full_tag("DESCRIPTION",5,false,$ch->description));
|
||||
fwrite ($bf,end_tag("GRADE_OUTCOME_HISTORY",4,true));
|
||||
}
|
||||
$status = fwrite ($bf,end_tag("GRADE_OUTCOME_HISTORIES",5,true));
|
||||
$status = fwrite ($bf,end_tag("GRADE_OUTCOME_HISTORIES",3,true));
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
@@ -2290,7 +2297,7 @@
|
||||
//It does this conversions:
|
||||
// - $CFG->wwwroot/file.php/courseid ------------------> $@FILEPHP@$ (slasharguments links)
|
||||
// - $CFG->wwwroot/file.php?file=/courseid ------------> $@FILEPHP@$ (non-slasharguments links)
|
||||
// - Every module xxxx_encode_content_links() is executed too
|
||||
// - Every module/block/course_format xxxx_encode_content_links() is executed too
|
||||
//
|
||||
function backup_encode_absolute_links($content) {
|
||||
|
||||
@@ -2316,6 +2323,12 @@
|
||||
$includedfiles = array();
|
||||
}
|
||||
|
||||
//Check if we support unicode modifiers in regular expressions. Cache it.
|
||||
static $unicoderegexp;
|
||||
if (!isset($unicoderegexp)) {
|
||||
$unicoderegexp = @preg_match('/\pL/u', 'a'); // This will fail silenty, returning false,
|
||||
} // if regexp libraries don't support unicode
|
||||
|
||||
//Check if preferences is ok. If it isn't set, we are
|
||||
//in a scheduled_backup to we are able to get a copy
|
||||
//from CFG->backup_preferences
|
||||
@@ -2325,15 +2338,28 @@
|
||||
//We are in manual backups so global preferences must exist!!
|
||||
$mypreferences = $preferences;
|
||||
}
|
||||
|
||||
//First, we check for every call to file.php inside the course
|
||||
$search = array($CFG->wwwroot.'/file.php/'.$mypreferences->backup_course,
|
||||
$CFG->wwwroot.'/file.php?file=/'.$mypreferences->backup_course);
|
||||
$CFG->wwwroot.'/file.php?file=/'.$mypreferences->backup_course,
|
||||
$CFG->wwwroot.'/file.php?file=%2f'.$mypreferences->backup_course,
|
||||
$CFG->wwwroot.'/file.php?file=%2F'.$mypreferences->backup_course);
|
||||
|
||||
$replace = array('$@FILEPHP@$','$@FILEPHP@$');
|
||||
$replace = array('$@FILEPHP@$', '$@FILEPHP@$', '$@FILEPHP@$', '$@FILEPHP@$');
|
||||
|
||||
$result = str_replace($search,$replace,$content);
|
||||
|
||||
// Now we look for any '$@FILEPHP@$' URLs, replacing:
|
||||
// - slashes and %2F by $@SLASH@$
|
||||
// - &forcedownload=1 &forcedownload=1 and ?forcedownload=1 by $@FORCEDOWNLOAD@$
|
||||
// This way, backup contents will be neutral and independent of slasharguments configuration. MDL-18799
|
||||
// Based in $unicoderegexp, decide the regular expression to use
|
||||
if ($unicoderegexp) { //We can use unicode modifiers
|
||||
$search = '/(\$@FILEPHP@\$)((?:(?:\/|%2f|%2F))(?:(?:\([-;:@#&=\pL0-9\$~_.+!*\',]*?\))|[-;:@#&=\pL0-9\$~_.+!*\',]|%[a-fA-F0-9]{2}|\/)*)?(\?(?:(?:(?:\([-;:@#&=\pL0-9\$~_.+!*\',]*?\))|[-;:@#&=?\pL0-9\$~_.+!*\',]|%[a-fA-F0-9]{2}|\/)*))?(?<![,.;])/';
|
||||
} else { //We cannot ue unicode modifiers
|
||||
$search = '/(\$@FILEPHP@\$)((?:(?:\/|%2f|%2F))(?:(?:\([-;:@#&=a-zA-Z0-9\$~_.+!*\',]*?\))|[-;:@#&=a-zA-Z0-9\$~_.+!*\',]|%[a-fA-F0-9]{2}|\/)*)?(\?(?:(?:(?:\([-;:@#&=a-zA-Z0-9\$~_.+!*\',]*?\))|[-;:@#&=?a-zA-Z0-9\$~_.+!*\',]|%[a-fA-F0-9]{2}|\/)*))?(?<![,.;])/';
|
||||
}
|
||||
$result = preg_replace_callback($search, 'backup_process_filephp_uses', $result);
|
||||
|
||||
foreach ($mypreferences->mods as $name => $info) {
|
||||
/// We only include the corresponding backuplib.php if it hasn't been included before
|
||||
/// This will save some load under PHP5. MDL-8700.
|
||||
@@ -2349,6 +2375,25 @@
|
||||
}
|
||||
}
|
||||
|
||||
// For the current course format call its encode_content_links method (if it exists)
|
||||
static $format_function_name;
|
||||
if (!isset($format_function_name)) {
|
||||
$format_function_name = false;
|
||||
if ($format = get_field('course', 'format', 'id', $mypreferences->backup_course)) {
|
||||
if (file_exists("$CFG->dirroot/course/format/$format/backuplib.php")) {
|
||||
include_once("$CFG->dirroot/course/format/$format/backuplib.php");
|
||||
$function_name = $format.'_encode_format_content_links';
|
||||
if (function_exists($function_name)) {
|
||||
$format_function_name = $function_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the above worked - then we have a function to call
|
||||
if ($format_function_name) {
|
||||
$result = $format_function_name($result, $mypreferences);
|
||||
}
|
||||
|
||||
// For each block, call its encode_content_links method.
|
||||
// This encodes forexample links to blocks/something/viewphp?id=666
|
||||
// that are stored in other activities.
|
||||
@@ -2375,6 +2420,21 @@
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback preg_replace function used by backup_encode_absolute_links()
|
||||
* to process $@FILEPHP@$ URLs to get slasharguments independent URLs
|
||||
*/
|
||||
function backup_process_filephp_uses($matches) {
|
||||
|
||||
// Replace slashes (plain and encoded) and forcedownload=1 parameter
|
||||
$search = array('/', '%2f', '%2F', '?forcedownload=1', '&forcedownload=1', '&forcedownload=1');
|
||||
$replace = array('$@SLASH@$', '$@SLASH@$', '$@SLASH@$', '$@FORCEDOWNLOAD@$', '$@FORCEDOWNLOAD@$', '$@FORCEDOWNLOAD@$');
|
||||
|
||||
$result = $matches[1] . (isset($matches[2]) ? str_replace($search, $replace, $matches[2]) : '') . (isset($matches[3]) ? str_replace($search, $replace, $matches[3]) : '');
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
//This function copies all the needed files under the "user" directory to the "user_files"
|
||||
//directory under temp/backup
|
||||
function backup_copy_user_files ($preferences) {
|
||||
@@ -2783,9 +2843,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
// foreach context, call get_roles_on_exact_context insert into array
|
||||
// foreach context, call get_roles_on_exact_context + get_roles_with_override_on_context() and insert into array
|
||||
foreach ($contexts as $context) {
|
||||
if ($proles = get_roles_on_exact_context($context)) {
|
||||
if ($proles = get_roles_on_exact_context($context)) { // Look for roles assignments
|
||||
foreach ($proles as $prole) {
|
||||
$roles[$prole->id] = $prole;
|
||||
}
|
||||
}
|
||||
if ($proles = get_roles_with_override_on_context($context)) { // Look for roles overrides
|
||||
foreach ($proles as $prole) {
|
||||
$roles[$prole->id] = $prole;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ function blackboard_convert($dir){
|
||||
|
||||
// Copy the Blackboard course files into the moodle course_files structure
|
||||
$subdirs = get_subdirs($dir."/");
|
||||
mkdir("$dir/course_files");
|
||||
mkdir("$dir/course_files", $CFG->directorypermissions);
|
||||
foreach ($subdirs as $subdir){
|
||||
rename($subdir, "course_files/$subdir");
|
||||
}
|
||||
|
||||
+57
-9
@@ -435,6 +435,25 @@
|
||||
upgrade_log_finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Are we restoring a backup that was made on the same site that we are restoring to?
|
||||
* This relies on some information that was only added to backup files in January 2009.
|
||||
* For older backup files, fall back to guessing based on wwwroot. MDL-16614 explains
|
||||
* when this guess could give the wrong answer.
|
||||
* @return boolean true if the backup was made on the same site we are restoring to.
|
||||
*/
|
||||
function backup_is_same_site(&$restore) {
|
||||
global $CFG;
|
||||
static $hashedsiteid = null;
|
||||
if (is_null($hashedsiteid)) {
|
||||
$hashedsiteid = md5(get_site_identifier());
|
||||
}
|
||||
if (!empty($restore->original_siteidentifier)) {
|
||||
return $restore->original_siteidentifier == $hashedsiteid;
|
||||
} else {
|
||||
return $restore->original_wwwroot == $CFG->wwwroot;
|
||||
}
|
||||
}
|
||||
|
||||
//This function is used to insert records in the backup_ids table
|
||||
//If the info field is greater than max_db_storage, then its info
|
||||
@@ -630,12 +649,10 @@
|
||||
function import_backup_file_silently($pathtofile,$destinationcourse,$emptyfirst=false,$userdata=false, $preferences=array()) {
|
||||
global $CFG,$SESSION,$USER; // is there such a thing on cron? I guess so..
|
||||
global $restore; // ick
|
||||
if (empty($USER)) {
|
||||
$USER = get_admin();
|
||||
$USER->admin = 1; // not sure why, but this doesn't get set
|
||||
}
|
||||
|
||||
define('RESTORE_SILENTLY',true); // don't output all the stuff to us.
|
||||
if (!defined('RESTORE_SILENTLY')) {
|
||||
define('RESTORE_SILENTLY',true); // don't output all the stuff to us.
|
||||
}
|
||||
|
||||
$debuginfo = 'import_backup_file_silently: ';
|
||||
$cleanupafter = false;
|
||||
@@ -684,9 +701,12 @@
|
||||
mtrace($debuginfo.'Required function check failed (see backup_required_functions)');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ini_set("max_execution_time","3000");
|
||||
raise_memory_limit("192M");
|
||||
if (empty($CFG->extramemorylimit)) {
|
||||
raise_memory_limit('128M');
|
||||
} else {
|
||||
raise_memory_limit($CFG->extramemorylimit);
|
||||
}
|
||||
|
||||
if (!$backup_unique_code = restore_precheck($destinationcourse,$pathtofile,$errorstr,true)) {
|
||||
mtrace($debuginfo.'Failed restore_precheck (error was '.$errorstr.')');
|
||||
@@ -699,14 +719,17 @@
|
||||
$SESSION->restore->metacourse = $restore->metacourse = (isset($preferences['restore_metacourse']) ? $preferences['restore_metacourse'] : 0);
|
||||
$SESSION->restore->restoreto = $restore->restoreto = 1;
|
||||
$SESSION->restore->users = $restore->users = $userdata;
|
||||
$SESSION->restore->groups = $restore->groups = (isset($preferences['restore_groups']) ? $preferences['restore_groups'] : RESTORE_GROUPS_NONE);
|
||||
$SESSION->restore->logs = $restore->logs = (isset($preferences['restore_logs']) ? $preferences['restore_logs'] : 0);
|
||||
$SESSION->restore->user_files = $restore->user_files = $userdata;
|
||||
$SESSION->restore->messages = $restore->messages = (isset($preferences['restore_messages']) ? $preferences['restore_messages'] : 0);
|
||||
$SESSION->restore->blogs = $restore->blogs = (isset($preferences['restore_blogs']) ? $preferences['restore_blogs'] : 0);
|
||||
$SESSION->restore->course_id = $restore->course_id = $destinationcourse;
|
||||
$SESSION->restore->restoreto = 1;
|
||||
$SESSION->restore->course_id = $destinationcourse;
|
||||
$SESSION->restore->deleting = $emptyfirst;
|
||||
$SESSION->restore->restore_course_files = $restore->course_files = (isset($preferences['restore_course_files']) ? $preferences['restore_course_files'] : 0);
|
||||
$SESSION->restore->restore_site_files = $restore->site_files = (isset($preferences['restore_site_files']) ? $preferences['restore_site_files'] : 0);
|
||||
$SESSION->restore->backup_version = $SESSION->info->backup_backup_version;
|
||||
$SESSION->restore->course_startdateoffset = $course->startdate - $SESSION->course_header->course_startdate;
|
||||
|
||||
@@ -749,7 +772,9 @@
|
||||
*/
|
||||
function backup_course_silently($courseid, $prefs, &$errorstring) {
|
||||
global $CFG, $preferences; // global preferences here because something else wants it :(
|
||||
define('BACKUP_SILENTLY', 1);
|
||||
if (!defined('BACKUP_SILENTLY')) {
|
||||
define('BACKUP_SILENTLY', 1);
|
||||
}
|
||||
if (!$course = get_record('course', 'id', $courseid)) {
|
||||
debugging("Couldn't find course with id $courseid in backup_course_silently");
|
||||
return false;
|
||||
@@ -783,6 +808,7 @@
|
||||
global $CFG;
|
||||
$preferences = new StdClass;
|
||||
$preferences->backup_unique_code = time();
|
||||
$preferences->backup_users = (isset($prefs['backup_users']) ? $prefs['backup_users'] : 0);
|
||||
$preferences->backup_name = backup_get_zipfile_name($course, $preferences->backup_unique_code);
|
||||
$count = 0;
|
||||
|
||||
@@ -800,6 +826,7 @@
|
||||
if (!function_exists($modbackup) || !function_exists($modcheckbackup)) {
|
||||
continue;
|
||||
}
|
||||
$modcheckbackup($course->id, $preferences->backup_users, $preferences->backup_unique_code);
|
||||
$var = "exists_".$modname;
|
||||
$preferences->$var = true;
|
||||
$count++;
|
||||
@@ -841,7 +868,6 @@
|
||||
|
||||
//Check other parameters
|
||||
$preferences->backup_metacourse = (isset($prefs['backup_metacourse']) ? $prefs['backup_metacourse'] : 0);
|
||||
$preferences->backup_users = (isset($prefs['backup_users']) ? $prefs['backup_users'] : 0);
|
||||
$preferences->backup_logs = (isset($prefs['backup_logs']) ? $prefs['backup_logs'] : 0);
|
||||
$preferences->backup_user_files = (isset($prefs['backup_user_files']) ? $prefs['backup_user_files'] : 0);
|
||||
$preferences->backup_course_files = (isset($prefs['backup_course_files']) ? $prefs['backup_course_files'] : 0);
|
||||
@@ -850,6 +876,28 @@
|
||||
$preferences->backup_gradebook_history = (isset($prefs['backup_gradebook_history']) ? $prefs['backup_gradebook_history'] : 0);
|
||||
$preferences->backup_blogs = (isset($prefs['backup_blogs']) ? $prefs['backup_blogs'] : 0);
|
||||
$preferences->backup_course = $course->id;
|
||||
|
||||
//Check users
|
||||
user_check_backup($course->id,$preferences->backup_unique_code,$preferences->backup_users,$preferences->backup_messages, $preferences->backup_blogs);
|
||||
|
||||
//Check logs
|
||||
log_check_backup($course->id);
|
||||
|
||||
//Check user files
|
||||
user_files_check_backup($course->id,$preferences->backup_unique_code);
|
||||
|
||||
//Check course files
|
||||
course_files_check_backup($course->id,$preferences->backup_unique_code);
|
||||
|
||||
//Check site files
|
||||
site_files_check_backup($course->id,$preferences->backup_unique_code);
|
||||
|
||||
//Role assignments
|
||||
$roles = get_records('role', '', '', 'sortorder');
|
||||
foreach ($roles as $role) {
|
||||
$preferences->backuproleassignments[$role->id] = $role;
|
||||
}
|
||||
|
||||
backup_add_static_preferences($preferences);
|
||||
return $preferences;
|
||||
}
|
||||
|
||||
+17
-6
@@ -23,6 +23,18 @@
|
||||
$method = optional_param( 'method' );
|
||||
$backup_unique_code = optional_param('backup_unique_code',0,PARAM_INT);
|
||||
|
||||
//Get and check course
|
||||
if (! $course = get_record("course", "id", $id)) {
|
||||
error("Course ID was incorrect (can't find it)");
|
||||
}
|
||||
// To some reasons, course_startdateoffset value was lost during restoring
|
||||
// See MDL-17469
|
||||
if (!empty($course->startdate) && !empty($SESSION->course_header->course_startdate)) {
|
||||
$SESSION->restore->course_startdateoffset = $course->startdate - $SESSION->course_header->course_startdate;
|
||||
} else {
|
||||
$SESSION->restore->course_startdateoffset = 0;
|
||||
}
|
||||
|
||||
//Check login
|
||||
require_login();
|
||||
|
||||
@@ -116,11 +128,6 @@
|
||||
|
||||
//We are here, so me have a file.
|
||||
|
||||
//Get and check course
|
||||
if (! $course = get_record("course", "id", $id)) {
|
||||
error("Course ID was incorrect (can't find it)");
|
||||
}
|
||||
|
||||
//Print header
|
||||
if (has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
|
||||
$navlinks[] = array('name' => basename($file), 'link' => null, 'type' => 'misc');
|
||||
@@ -140,7 +147,11 @@
|
||||
|
||||
//Adjust some php variables to the execution of this script
|
||||
@ini_set("max_execution_time","3000");
|
||||
raise_memory_limit("192M");
|
||||
if (empty($CFG->extramemorylimit)) {
|
||||
raise_memory_limit('128M');
|
||||
} else {
|
||||
raise_memory_limit($CFG->extramemorylimit);
|
||||
}
|
||||
|
||||
//Call the form, depending the step we are
|
||||
|
||||
|
||||
+78
-53
@@ -1,4 +1,5 @@
|
||||
<?php //$Id$
|
||||
|
||||
//This page receive all the restore_form data. Then, if existing course
|
||||
//has been selected, shows a list of courses to select one.
|
||||
//It cheks that the parammeter from restore_form are coherent.
|
||||
@@ -22,8 +23,8 @@
|
||||
$course_header->course_fullname = stripslashes_safe($form1->fullname); //"update_FullName";
|
||||
/// Roll dates only if the backup course has a start date
|
||||
/// (some formats like main page, social..., haven't it and rolling dates
|
||||
/// from 0 produces crazy dates. MDL-10125
|
||||
if ($course_header->course_startdate) {
|
||||
/// from 0 produces crazy dates. MDL-10125 and we have passed some custom startyear/month/day. MDL-12922
|
||||
if ($course_header->course_startdate && !empty($form1->startyear)) {
|
||||
$form1->startdate = make_timestamp($form1->startyear, $form1->startmonth, $form1->startday);
|
||||
$currentcoursestartdate = $course_header->course_startdate;
|
||||
$coursestartdatedateoffset = $form1->startdate - $currentcoursestartdate;
|
||||
@@ -202,50 +203,56 @@
|
||||
error("Site not found!");
|
||||
}
|
||||
|
||||
//Depending the selected restoreto:
|
||||
// If user is a teacher (and not creator) or we are restoring from within SITEID:
|
||||
// 0-Current course, deleting: Put $restore->course_id and $restore->deleting (true), create the restore object
|
||||
// 1-Current course, adding: Put $restore->course_id and $restore->deleting (false), create the restore object
|
||||
// If the uses is a creator:
|
||||
// 0-Existing course, deleting: Select the destination course and launch the check again, then
|
||||
// put $restore->course_id and $restore->deleting (true), create the restore object.
|
||||
// 1-Existing course, adding: Select the destination course and launch the check again, then
|
||||
// put $restore->course_id and $restore->deleting (false), create the restore object.
|
||||
// 2-New course: Create the restore object and launch the execute.
|
||||
|
||||
//If the user is a teacher and not a creator or we are restoring from within SITEID
|
||||
|
||||
if (!user_can_create_courses() || $id == SITEID) {
|
||||
$restore->course_id = $id;
|
||||
if ($restore->restoreto == 0) {
|
||||
$restore->deleting = true;
|
||||
} else {
|
||||
$restore->deleting = false;
|
||||
}
|
||||
}
|
||||
|
||||
//If the user is a creator (or admin)
|
||||
if (user_can_create_courses()) {
|
||||
//Set restore->deleting as needed
|
||||
if ($restore->restoreto == 0) {
|
||||
$restore->deleting = true;
|
||||
} else {
|
||||
$restore->deleting = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Non-cached - get accessinfo
|
||||
if (isset($USER->access)) {
|
||||
$accessinfo = $USER->access;
|
||||
} else {
|
||||
$accessinfo = get_user_access_sitewide($USER->id);
|
||||
}
|
||||
|
||||
// Get all the courses the user is able to restore to
|
||||
$mycourses = get_user_courses_bycap($USER->id, 'moodle/site:restore', $accessinfo, true, 'c.sortorder ASC', array('id', 'fullname', 'shortname', 'visible'));
|
||||
|
||||
// Calculate if the user can create courses
|
||||
$cancreatecourses = user_can_create_courses();
|
||||
|
||||
//Depending the selected restoreto:
|
||||
// A) If user has 'moodle/site:restore' in more than one course and cannot create courses and he isn't restoring from SITEID:
|
||||
// 0-Existing course, deleting: Select the destination course and launch the check again, then
|
||||
// put $restore->course_id and $restore->deleting (true), create the restore object.
|
||||
// 1-Existing course, adding: Select the destination course and launch the check again, then
|
||||
// put $restore->course_id and $restore->deleting (false), create the restore object.
|
||||
// B) Else, if user cannot create courses or he is restoring from within SITEID:
|
||||
// 0-Current course, deleting: Put $restore->course_id and $restore->deleting (true), create the restore object
|
||||
// 1-Current course, adding: Put $restore->course_id and $restore->deleting (false), create the restore object
|
||||
// C) If the user is a creator:
|
||||
// 0-Existing course, deleting: Select the destination course and launch the check again, then
|
||||
// put $restore->course_id and $restore->deleting (true), create the restore object.
|
||||
// 1-Existing course, adding: Select the destination course and launch the check again, then
|
||||
// put $restore->course_id and $restore->deleting (false), create the restore object.
|
||||
// 2-New course: Create the restore object and launch the execute.
|
||||
// NOTE: SITEID is prevented as a source for restoring because it's public area and we must encourage admins
|
||||
// to avoid using it as a "repository" for courses storage.
|
||||
|
||||
// A) If user has 'moodle/site:restore' in more than one course, cannot create courses and he isn't restoring from SITEID
|
||||
if (count($mycourses) > 1 && !$cancreatecourses && $id != SITEID) {
|
||||
/// Nothing to do, process continues and C) will show the list of courses
|
||||
|
||||
// B) Else, if the user is a teacher and not a creator or we are restoring from within SITEID
|
||||
} else if (!$cancreatecourses || $id == SITEID) {
|
||||
$restore->course_id = $id; /// Force restore to current course, disabling pick course from list
|
||||
}
|
||||
|
||||
// C) Arrived here, we have preprocessed all the changes needed by A) and B). Continue with the process
|
||||
|
||||
//Set restore->deleting as needed
|
||||
if ($restore->restoreto == 0) {
|
||||
$restore->deleting = true;
|
||||
} else {
|
||||
$restore->deleting = false;
|
||||
}
|
||||
|
||||
//Now, select the course if needed
|
||||
//if (($restore->restoreto == 0 or $restore->restoreto == 1) and ($restore->course_id == 0) and get_capability_courses('moodle/site:restore')) {
|
||||
if (($restore->restoreto == 0 or $restore->restoreto == 1) and ($restore->course_id == 0) && count($mycourses) > 1) {
|
||||
|
||||
if ($courses = $mycourses) {
|
||||
@@ -270,12 +277,14 @@
|
||||
//Checks everything and execute restore
|
||||
} else if ((($restore->restoreto == 0 or $restore->restoreto == 1) and ($restore->course_id != 0)) or ($restore->restoreto == 2)) {
|
||||
//Final access control check
|
||||
if ($restore->course_id == 0 and !user_can_create_courses()) {
|
||||
if ($restore->course_id == 0 and !$cancreatecourses) {
|
||||
error("You need to be a creator or admin to restore into new course!");
|
||||
} else if ($restore->course_id != 0 and !has_capability('moodle/site:restore', get_context_instance(CONTEXT_COURSE, $restore->course_id))) {
|
||||
error("You need to be an edit teacher or admin to restore into selected course!");
|
||||
}
|
||||
$show_continue_button = true;
|
||||
$messages = array();
|
||||
|
||||
//Check if we've selected any mod's user info and restore->users
|
||||
//is set to none. Change it to course and inform.
|
||||
if ($restore->users == 2) {
|
||||
@@ -291,36 +300,52 @@
|
||||
$changed = 1;
|
||||
}
|
||||
if ($changed) {
|
||||
echo get_string ("noteuserschangednonetocourse");
|
||||
echo "<hr noshade size=\"1\">";
|
||||
$messages[] = get_string ("noteuserschangednonetocourse");
|
||||
$restore->users = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// If restoring users and backup has mnet remote users and we are restoring to different site, forbid restore to non-admins. MDL-17009
|
||||
if ($restore->users != 2 && /// If restoring users
|
||||
!empty($info->mnet_remoteusers) && $info->mnet_remoteusers === 'true' && /// and backup contains remote users
|
||||
!backup_is_same_site($info)) { /// and backup is being restored to different site
|
||||
|
||||
/// If user is admin (by 'moodle/user:create' cap), warn about conversion to local auth if missing mnet hosts and continue restore
|
||||
if (has_capability('moodle/user:create', get_context_instance(CONTEXT_SYSTEM))) {
|
||||
$messages[] = get_string('mnetrestore_extusers_admin', 'admin');
|
||||
$show_continue_button = true;
|
||||
|
||||
/// else, notify about the thing (suggesting to ask admin) and stop restore
|
||||
} else {
|
||||
$messages[] = get_string('mnetrestore_extusers_noadmin', 'admin');
|
||||
$show_continue_button = false;
|
||||
}
|
||||
}
|
||||
|
||||
//Save the restore session object
|
||||
$SESSION->restore = $restore;
|
||||
|
||||
echo "<div style='text-align:center'>";
|
||||
|
||||
/// Printout messages
|
||||
foreach ($messages as $message) {
|
||||
echo '<p>' . $message . '</p>';
|
||||
}
|
||||
|
||||
/// Warning and button
|
||||
if ($show_continue_button) {
|
||||
//Print the continue button to execute the restore NOW !!!!
|
||||
//All is prepared !!!
|
||||
echo "<div style='text-align:center'>";
|
||||
$hidden["launch"] = "execute";
|
||||
$hidden["file"] = $file;
|
||||
$hidden["id"] = $id;
|
||||
print_string('longtimewarning','admin');
|
||||
|
||||
if ($restore->users && !empty($info->mnet_externalusers)
|
||||
&& $info->mnet_externalusers === 'true') {
|
||||
if ($info->original_wwwroot === $CFG->wwwroot) {
|
||||
print '<p>'.get_string('mnetrestore_extusers','admin').'</p>';
|
||||
} else {
|
||||
print '<p>'. get_string('mnetrestore_extusers_mismatch','admin').'</p>';
|
||||
}
|
||||
}
|
||||
|
||||
/// Restore button
|
||||
print_single_button("restore.php", $hidden, get_string("restorecoursenow"),"post");
|
||||
echo "</div>";
|
||||
} else {
|
||||
//Show error
|
||||
error ("Something was wrong checking restore preferences");
|
||||
}
|
||||
echo "</div>";
|
||||
|
||||
//If we are here. Something must be wrong. Debug !!!
|
||||
} else {
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
//Add info->original_wwwroot to $restore to be able to use it in all the restore process
|
||||
//(mainly when decoding internal links)
|
||||
$restore->original_wwwroot = $info->original_wwwroot;
|
||||
// Copy $info->original_siteidentifier, is present, so backup_is_same_site can work.
|
||||
if (isset($info->original_siteidentifier)) {
|
||||
$restore->original_siteidentifier = $info->original_siteidentifier;
|
||||
}
|
||||
//Add info->backup_version to $restore to be able to detect versions in the restore process
|
||||
//(to decide when to convert wiki texts to markdown...)
|
||||
$restore->backup_version = $info->backup_backup_version;
|
||||
|
||||
+18
-12
@@ -109,8 +109,9 @@
|
||||
$restore_blogs = 1;
|
||||
}
|
||||
|
||||
$cancreatecourses = user_can_create_courses();
|
||||
if (!isset($restore_restoreto)) {
|
||||
if (!user_can_create_courses()) {
|
||||
if (!$cancreatecourses) {
|
||||
$restore_restoreto = 1;
|
||||
} else {
|
||||
$restore_restoreto = 2;
|
||||
@@ -206,7 +207,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) {
|
||||
* if user has course:create in any category, we show
|
||||
* newcourse
|
||||
*/
|
||||
|
||||
|
||||
// Non-cached - get accessinfo
|
||||
if (isset($USER->access)) {
|
||||
$accessinfo = $USER->access;
|
||||
@@ -229,7 +230,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) {
|
||||
}
|
||||
|
||||
// if user can create any course at all, give the option
|
||||
if (user_can_create_courses()) {
|
||||
if ($cancreatecourses) {
|
||||
$restore_restoreto_options[2] = get_string("newcourse");
|
||||
}
|
||||
|
||||
@@ -238,7 +239,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) {
|
||||
|
||||
choose_from_menu($restore_restoreto_options, "restore_restoreto", $restore_restoreto, "");
|
||||
echo "</td></tr>";
|
||||
if (user_can_create_courses()) { //display these fields conditionally
|
||||
if ($cancreatecourses) { //display these fields conditionally
|
||||
|
||||
// find the list of cates user can edit
|
||||
echo "<tr valign=\"top\" >";
|
||||
@@ -291,6 +292,11 @@ function selectItemInCheckboxByName(formId, checkName, checked ) {
|
||||
echo '<input type="hidden" name="startday" value="0" />';
|
||||
}
|
||||
echo "</td></tr>";
|
||||
} else {
|
||||
/// If user cannot create course, prevent any change in startyear/month/day (so restore wont calculate any roll. MDL-12922
|
||||
echo '<input type="hidden" name="startyear" value="0" />';
|
||||
echo '<input type="hidden" name="startmonth" value="0" />';
|
||||
echo '<input type="hidden" name="startday" value="0" />';
|
||||
}
|
||||
//Line
|
||||
echo "<tr><td colspan=\"4\"><hr /></td></tr>";
|
||||
@@ -529,7 +535,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) {
|
||||
echo "<input type=\"hidden\" id=\"menurestore_site_files\" name=\"restore_site_files\" value=\"0\" />";
|
||||
}
|
||||
echo "</td></tr>";
|
||||
|
||||
|
||||
// do you want grade histories to be restored?
|
||||
if (empty($CFG->disablegradehistory)) {
|
||||
echo "<tr>";
|
||||
@@ -661,7 +667,7 @@ if ($info->backup_moodle_version < 2006092801) {
|
||||
$mappableroles = $siteroleschoicearray;
|
||||
|
||||
echo ('<tr><td align="right">');
|
||||
echo '<label for="menuroles_'.$roleid.'">'.$role->name." (".($role->shortname).")".'</label>';
|
||||
echo '<label for="menuroles_'.$roleid.'">'.format_string($role->name)." (".($role->shortname).")".'</label>';
|
||||
echo ('</td><td align="left">');
|
||||
|
||||
/// first, we see if any exact role definition is found
|
||||
@@ -671,7 +677,7 @@ if ($info->backup_moodle_version < 2006092801) {
|
||||
$matchrole = $samerole->id;
|
||||
// if an exact role is found, it does not matter whether this user can assign this role or not,
|
||||
// this will be presented as a valid option regardless
|
||||
$mappableroles[$samerole->id] = $allroles[$samerole->id]->name." (". $allroles[$samerole->id]->shortname.")";
|
||||
$mappableroles[$samerole->id] = format_string($allroles[$samerole->id]->name)." (". $allroles[$samerole->id]->shortname.")";
|
||||
} else {
|
||||
// no exact role found, let's try to match shortname
|
||||
// this is useful in situations where basic roles differ slightly in definition
|
||||
@@ -712,9 +718,9 @@ echo ('</table>'); // end of role mappings table
|
||||
|
||||
/**
|
||||
* Look for a role in the database with exactly the same definition as the one in the backup file.
|
||||
*
|
||||
*
|
||||
* @param integer $roleid the id that the role in the backup files had on the old server.
|
||||
* @param object $role the rest of the definition of the role from the backup file.
|
||||
* @param object $role the rest of the definition of the role from the backup file.
|
||||
*/
|
||||
function restore_samerole($roleid, $rolefromxml) {
|
||||
global $CFG;
|
||||
@@ -724,13 +730,13 @@ function restore_samerole($roleid, $rolefromxml) {
|
||||
|
||||
// First guess, try let's use the id
|
||||
if (restore_is_samerole($roleid, $rolefromxml)) {
|
||||
return get_record('role', 'id', $roleid);
|
||||
return get_record('role', 'id', $roleid);
|
||||
}
|
||||
|
||||
// Second guess, try the shortname
|
||||
$testroleid = get_field('role', 'id', 'shortname', $rolefromxml->shortname);
|
||||
if ($testroleid && restore_is_samerole($testroleid, $rolefromxml)) {
|
||||
return get_record('role', 'id', $testroleid);
|
||||
return get_record('role', 'id', $testroleid);
|
||||
}
|
||||
|
||||
// Finally, search all other roles. In orter to speed things up, we exclude the ones we have
|
||||
@@ -765,7 +771,7 @@ function restore_samerole($roleid, $rolefromxml) {
|
||||
*/
|
||||
function restore_is_samerole($testroleid, $rolefromxml) {
|
||||
// Load the role definition from the databse.
|
||||
$rolefromdb = get_records('role_capabilities', 'roleid', $testroleid, '', 'capability,permission');
|
||||
$rolefromdb = get_records('role_capabilities', 'roleid', $testroleid, '', 'capability,permission');
|
||||
if (!$rolefromdb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+472
-62
@@ -81,7 +81,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
}
|
||||
|
||||
//This function makes all the necessary calls to xxxx_decode_content_links_caller()
|
||||
//function in each module, passing them the desired contents to be decoded
|
||||
//function in each module/block/course format..., passing them the desired contents to be decoded
|
||||
//from backup format to destination site/course in order to mantain inter-activities
|
||||
//working in the backup/restore process
|
||||
function restore_decode_content_links($restore) {
|
||||
@@ -98,7 +98,8 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
echo '<li>' . get_string('from') . ' ' . get_string('course');
|
||||
}
|
||||
$course = get_record('course', 'id', $restore->course_id, '', '', '', '', 'id,summary');
|
||||
$coursesummary = restore_decode_content_links_worker($course->summary, $restore);
|
||||
$coursesummary = backup_todb($course->summary,false); // Exception: Process FILEPHP (not available when restored) MDL-18222
|
||||
$coursesummary = restore_decode_content_links_worker($coursesummary, $restore);
|
||||
if ($coursesummary != $course->summary) {
|
||||
$course->summary = addslashes($coursesummary);
|
||||
if (!update_record('course', $course)) {
|
||||
@@ -148,6 +149,23 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
}
|
||||
}
|
||||
|
||||
// For the course format call its decode_content_links method (if it exists)
|
||||
$format = get_field('course', 'format', 'id', $restore->course_id);
|
||||
if (file_exists("$CFG->dirroot/course/format/$format/restorelib.php")) {
|
||||
include_once("$CFG->dirroot/course/format/$format/restorelib.php");
|
||||
$function_name = $format.'_decode_format_content_links_caller';
|
||||
|
||||
if (function_exists($function_name)) {
|
||||
if (!defined('RESTORE_SILENTLY')) {
|
||||
echo "<li>".get_string ("from")." ".get_string("format").' '.$format;
|
||||
}
|
||||
$status = $function_name($restore);
|
||||
if (!defined('RESTORE_SILENTLY')) {
|
||||
echo '</li>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process all html text also in blocks too
|
||||
if (!defined('RESTORE_SILENTLY')) {
|
||||
echo '<li>'.get_string ('from').' '.get_string('blocks');
|
||||
@@ -186,6 +204,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
//its task is to ask all modules (maybe other linkable objects) to restore
|
||||
//links to them.
|
||||
function restore_decode_content_links_worker($content,$restore) {
|
||||
global $CFG;
|
||||
foreach($restore->mods as $name => $info) {
|
||||
$function_name = $name."_decode_content_links";
|
||||
if (function_exists($function_name)) {
|
||||
@@ -193,6 +212,25 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
}
|
||||
}
|
||||
|
||||
// For the current format, call decode_format_content_links if it exists
|
||||
static $format_function_name;
|
||||
if (!isset($format_function_name)) {
|
||||
$format_function_name = false;
|
||||
if ($format = get_field('course', 'format', 'id', $restore->course_id)) {
|
||||
if (file_exists("$CFG->dirroot/course/format/$format/restorelib.php")) {
|
||||
include_once("$CFG->dirroot/course/format/$format/restorelib.php");
|
||||
$function_name = $format.'_decode_format_content_links';
|
||||
if (function_exists($function_name)) {
|
||||
$format_function_name = $function_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the above worked - then we have a function to call
|
||||
if ($format_function_name) {
|
||||
$content = $format_function_name($content, $restore);
|
||||
}
|
||||
|
||||
// For each block, call its encode_content_links method
|
||||
static $blockobjects = null;
|
||||
if (!isset($blockobjects)) {
|
||||
@@ -486,6 +524,15 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
//The backup date
|
||||
$tab[3][0] = "<b>".get_string("backupdate").":</b>";
|
||||
$tab[3][1] = userdate($info->backup_date);
|
||||
//Is this the same Moodle install?
|
||||
if (!empty($info->original_siteidentifier)) {
|
||||
$tab[4][0] = "<b>".get_string("backupfromthissite").":</b>";
|
||||
if (backup_is_same_site($info)) {
|
||||
$tab[4][1] = get_string('yes');
|
||||
} else {
|
||||
$tab[4][1] = get_string('no');
|
||||
}
|
||||
}
|
||||
//Print title
|
||||
print_heading(get_string("backup").":");
|
||||
$table->data = $tab;
|
||||
@@ -725,7 +772,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
$course->shortname = addslashes($course_header->course_shortname);
|
||||
$course->idnumber = addslashes($course_header->course_idnumber);
|
||||
$course->idnumber = ''; //addslashes($course_header->course_idnumber); // we don't want this at all.
|
||||
$course->summary = backup_todb($course_header->course_summary);
|
||||
$course->summary = addslashes($course_header->course_summary);
|
||||
$course->format = addslashes($course_header->course_format);
|
||||
$course->showgrades = addslashes($course_header->course_showgrades);
|
||||
$course->newsitems = addslashes($course_header->course_newsitems);
|
||||
@@ -824,7 +871,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
global $CFG;
|
||||
$status = true;
|
||||
|
||||
delete_records('block_instance', 'pageid', $restore->course_id, 'pagetype', PAGE_COURSE_VIEW);
|
||||
blocks_delete_all_on_page(PAGE_COURSE_VIEW, $restore->course_id);
|
||||
if (empty($backup_block_format)) { // This is a backup from Moodle < 1.5
|
||||
if (empty($blockinfo)) {
|
||||
// Looks like it's from Moodle < 1.3. Let's give the course default blocks...
|
||||
@@ -1067,6 +1114,11 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
//Get section id when restoring in existing course
|
||||
$rec = get_record("course_sections","course",$restore->course_id,
|
||||
"section",$section->section);
|
||||
//If section exists, has empty summary and backup has some summary, use it. MDL-8848
|
||||
if ($rec && empty($rec->summary) && !empty($section->summary)) {
|
||||
$rec->summary = $section->summary;
|
||||
update_record("course_sections", $rec);
|
||||
}
|
||||
//If that section doesn't exist, get section 0 (every mod will be
|
||||
//asigned there
|
||||
if(!$rec) {
|
||||
@@ -1260,7 +1312,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
$dbmetacourse = false;
|
||||
//Check if child course exists in destination server
|
||||
//(by id in the same server or by idnumber and shortname in other server)
|
||||
if ($restore->original_wwwroot == $CFG->wwwroot) {
|
||||
if (backup_is_same_site($restore)) {
|
||||
//Same server, lets see by id
|
||||
$dbcourse = get_record('course','id',$child->id);
|
||||
} else {
|
||||
@@ -1292,7 +1344,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
$dbmetacourse = false;
|
||||
//Check if parent course exists in destination server
|
||||
//(by id in the same server or by idnumber and shortname in other server)
|
||||
if ($restore->original_wwwroot == $CFG->wwwroot) {
|
||||
if (backup_is_same_site($restore)) {
|
||||
//Same server, lets see by id
|
||||
$dbcourse = get_record('course','id',$parent->id);
|
||||
} else {
|
||||
@@ -2421,6 +2473,9 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
|
||||
/// Iterate over all users loaded from xml
|
||||
$counter = 0;
|
||||
|
||||
/// Init trailing messages
|
||||
$messages = array();
|
||||
foreach ($info->users as $userid) {
|
||||
$rec = backup_getid($restore->backup_unique_code,"user",$userid);
|
||||
$user = $rec->info;
|
||||
@@ -2471,17 +2526,45 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
//Has role teacher or student or needed
|
||||
$is_course_user = ($is_teacher or $is_student or $is_needed);
|
||||
|
||||
//Calculate mnethostid
|
||||
if (empty($user->mnethosturl) || $user->mnethosturl===$CFG->wwwroot) {
|
||||
$user->mnethostid = $CFG->mnet_localhost_id;
|
||||
} else {
|
||||
// fast url-to-id lookups
|
||||
if (isset($mnethosts[$user->mnethosturl])) {
|
||||
$user->mnethostid = $mnethosts[$user->mnethosturl]->id;
|
||||
// in case we are restoring to same server, look for user by id
|
||||
// it should return record always, but in sites rebuilt from scratch
|
||||
// and being reconstructed using course backups
|
||||
$user_data = false;
|
||||
if (backup_is_same_site($restore)) {
|
||||
$user_data = get_record('user', 'id', $user->id);
|
||||
}
|
||||
|
||||
// Only try to perform mnethost/auth modifications if restoring to another server
|
||||
// or if, while restoring to same server, the user doesn't exists yet (rebuilt site)
|
||||
//
|
||||
// So existing user data in same server *won't be modified by restore anymore*,
|
||||
// under any circumpstance. If somehting is wrong with existing data, it's server fault.
|
||||
if (!backup_is_same_site($restore) || (backup_is_same_site($restore) && !$user_data)) {
|
||||
//Calculate mnethostid
|
||||
if (empty($user->mnethosturl) || $user->mnethosturl===$CFG->wwwroot) {
|
||||
$user->mnethostid = $CFG->mnet_localhost_id;
|
||||
} else {
|
||||
// should not happen, as we check in restore_chech.php
|
||||
// but handle the error if it does
|
||||
error("This backup file contains external Moodle Network Hosts that are not configured locally.");
|
||||
// fast url-to-id lookups
|
||||
if (isset($mnethosts[$user->mnethosturl])) {
|
||||
$user->mnethostid = $mnethosts[$user->mnethosturl]->id;
|
||||
} else {
|
||||
$user->mnethostid = $CFG->mnet_localhost_id;
|
||||
}
|
||||
}
|
||||
//Arriving here, any user with mnet auth and using $CFG->mnet_localhost_id is wrong
|
||||
//as own server cannot be accesed over mnet. Change auth to manual and inform about the switch
|
||||
if ($user->auth == 'mnet' && $user->mnethostid == $CFG->mnet_localhost_id) {
|
||||
// Respect registerauth
|
||||
if ($CFG->registerauth == 'email') {
|
||||
$user->auth = 'email';
|
||||
} else {
|
||||
$user->auth = 'manual';
|
||||
}
|
||||
// inform about the automatic switch of authentication/host
|
||||
if(empty($user->mnethosturl)) {
|
||||
$user->mnethosturl = '----';
|
||||
}
|
||||
$messages[] = get_string('mnetrestore_extusers_switchuserauth', 'admin', $user);
|
||||
}
|
||||
}
|
||||
unset($user->mnethosturl);
|
||||
@@ -2490,8 +2573,11 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
$newid=null;
|
||||
//check if it exists (by username) and get its id
|
||||
$user_exists = true;
|
||||
$user_data = get_record("user","username",addslashes($user->username),
|
||||
'mnethostid', $user->mnethostid);
|
||||
if (!backup_is_same_site($restore)) { /// Restoring to another server, look for existing user based on fields
|
||||
/// If restoring to same server, look has been performed some lines above (by id)
|
||||
$user_data = get_record('user', 'username', addslashes($user->username), 'mnethostid', $user->mnethostid);
|
||||
}
|
||||
|
||||
if (!$user_data) {
|
||||
$user_exists = false;
|
||||
} else {
|
||||
@@ -2553,7 +2639,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
// - if the destination site is different (by wwwroot) reset it.
|
||||
// - if the destination site is the same (by wwwroot), leave it unmodified
|
||||
|
||||
if ($restore->original_wwwroot != $CFG->wwwroot) {
|
||||
if (!backup_is_same_site($restore)) {
|
||||
$user->policyagreed = 0;
|
||||
} else {
|
||||
//Nothing to do, we are in the same server
|
||||
@@ -2618,7 +2704,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
// - if we are in the same server (by wwwroot), maintain it unmodified.
|
||||
if (empty($user->roles['teacher']->enrol)) {
|
||||
$user->roles['teacher']->enrol = $CFG->enrol;
|
||||
} else if ($restore->original_wwwroot != $CFG->wwwroot) {
|
||||
} else if (!backup_is_same_site($restore)) {
|
||||
$user->roles['teacher']->enrol = $CFG->enrol;
|
||||
} else {
|
||||
//Nothing to do. Leave it unmodified
|
||||
@@ -2664,7 +2750,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
// - if we are in the same server (by wwwroot), maintain it unmodified.
|
||||
if (empty($user->roles['student']->enrol)) {
|
||||
$user->roles['student']->enrol = $CFG->enrol;
|
||||
} else if ($restore->original_wwwroot != $CFG->wwwroot) {
|
||||
} else if (!backup_is_same_site($restore)) {
|
||||
$user->roles['student']->enrol = $CFG->enrol;
|
||||
} else {
|
||||
//Nothing to do. Leave it unmodified
|
||||
@@ -2749,6 +2835,17 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
backup_flush(300);
|
||||
}
|
||||
} /// End of loop over all the users loaded from xml
|
||||
|
||||
/// Inform about all the messages geerated while restoring users
|
||||
if (!defined('RESTORE_SILENTLY')) {
|
||||
if ($messages) {
|
||||
echo '<ul>';
|
||||
foreach ($messages as $message) {
|
||||
echo '<li>' . $message . '</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $status;
|
||||
@@ -3194,9 +3291,10 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
}
|
||||
|
||||
// scale is not course unique, use get_record_sql to suppress warning
|
||||
|
||||
//Going to compare LOB columns so, use the cross-db sql_compare_text() in both sides.
|
||||
$compare_scale_clause = sql_compare_text('scale') . "=" . sql_compare_text("'" . $sca->scale . "'");
|
||||
$sca_db = get_record_sql("SELECT * FROM {$CFG->prefix}scale
|
||||
WHERE scale = '$sca->scale'
|
||||
WHERE $compare_scale_clause
|
||||
AND courseid = $course_to_search", true);
|
||||
|
||||
//If it doesn't exist, create
|
||||
@@ -3398,7 +3496,9 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
$group_member->userid = $user->new_id;
|
||||
|
||||
//The structure is equal to the db, so insert the groups_members
|
||||
if (!insert_record ("groups_members", $group_member)) {
|
||||
if (record_exists("groups_members", 'groupid', $group_member->groupid, 'userid', $group_member->userid)) {
|
||||
// user already member
|
||||
} else if (!insert_record ("groups_members", $group_member)) {
|
||||
$status = false;
|
||||
continue;
|
||||
}
|
||||
@@ -3598,8 +3698,10 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
|
||||
//Now search if that event exists (by name, description, timestart fields) in
|
||||
//restore->course_id course
|
||||
//Going to compare LOB columns so, use the cross-db sql_compare_text() in both sides.
|
||||
$compare_description_clause = sql_compare_text('description') . "=" . sql_compare_text("'" . $eve->description . "'");
|
||||
$eve_db = get_record_select("event",
|
||||
"courseid={$eve->courseid} AND name='{$eve->name}' AND description='{$eve->description}' AND timestart=$eve->timestart");
|
||||
"courseid={$eve->courseid} AND name='{$eve->name}' AND $compare_description_clause AND timestart=$eve->timestart");
|
||||
//If it doesn't exist, create
|
||||
if (!$eve_db) {
|
||||
$create_event = true;
|
||||
@@ -3666,6 +3768,11 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
// - $@FILEPHP@$ ---|------------> $CFG->wwwroot/file.php/courseid (slasharguments on)
|
||||
// |------------> $CFG->wwwroot/file.php?file=/courseid (slasharguments off)
|
||||
//
|
||||
// - $@SLASH@$ --|---------------> / (slasharguments on)
|
||||
// |---------------> %2F (slasharguments off)
|
||||
//
|
||||
// - $@FORCEDOWNLOAD@$ --|-------> ?forcedownload=1 (slasharguments on)
|
||||
// |-------> &forcedownload=1(slasharguments off)
|
||||
//Note: Inter-activities linking is being implemented as a final
|
||||
//step in the restore execution, because we need to have it
|
||||
//finished to know all the oldid, newid equivaleces
|
||||
@@ -3689,6 +3796,15 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
$replace = array(get_file_url($restore->course_id));
|
||||
$result = str_replace($search,$replace,$content);
|
||||
|
||||
//Now $@SLASH@$ and $@FORCEDOWNLOAD@$ MDL-18799
|
||||
$search = array('$@SLASH@$', '$@FORCEDOWNLOAD@$');
|
||||
if ($CFG->slasharguments) {
|
||||
$replace = array('/', '?forcedownload=1');
|
||||
} else {
|
||||
$replace = array('%2F', '&forcedownload=1');
|
||||
}
|
||||
$result = str_replace($search, $replace, $result);
|
||||
|
||||
if ($result != $content && debugging()) { //Debug
|
||||
if (!defined('RESTORE_SILENTLY')) {
|
||||
echo '<br /><hr />'.s($content).'<br />changed to<br />'.s($result).'<hr /><br />'; //Debug
|
||||
@@ -3903,6 +4019,10 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
//Iterate
|
||||
$counter = 0;
|
||||
foreach ($list as $dir) {
|
||||
//Avoid copying maintenance.html. MDL-18594
|
||||
if ($dir == 'maintenance.html') {
|
||||
continue;
|
||||
}
|
||||
//Copy the dir to its new location
|
||||
//Only if destination file/dir doesn exists
|
||||
if (!file_exists($dest_dir."/".$dir)) {
|
||||
@@ -4432,6 +4552,217 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
//== ==
|
||||
//=====================================================================================
|
||||
|
||||
/// This is the class used to split, in first instance, the monolithic moodle.xml into
|
||||
/// smaller xml files allowing the MoodleParser later to process only the required info
|
||||
/// based in each TODO, instead of processing the whole xml for each TODO. In theory
|
||||
/// processing time can be reduced upto 1/20th of original time (depending of the
|
||||
/// number of TODOs in the original moodle.xml file)
|
||||
///
|
||||
/// Anyway, note it's a general splitter parser, and only needs to be instantiated
|
||||
/// with the proper destination dir and the tosplit configuration. Be careful when
|
||||
/// using it because it doesn't support XML attributes nor real cdata out from tags.
|
||||
/// (both not used in the target Moodle backup files)
|
||||
|
||||
class moodle_splitter_parser {
|
||||
var $level = 0; /// Level we are
|
||||
var $tree = array(); /// Array of levels we are
|
||||
var $cdata = ''; /// Raw storage for character data
|
||||
var $content = ''; /// Content buffer to be printed to file
|
||||
var $trailing= ''; /// Content of the trailing tree for each splited file
|
||||
var $savepath = null; /// Path to store splited files
|
||||
var $fhandler = null; /// Current file we are writing to
|
||||
var $tosplit = array(); /// Array defining the files we want to split, in this format:
|
||||
/// array( level/tag/level/tag => filename)
|
||||
var $splitwords = array(); /// Denormalised array containing the potential tags
|
||||
/// being a split point. To speed up check_split_point()
|
||||
var $maxsplitlevel = 0; /// Precalculated max level where any split happens. To speed up check_split_point()
|
||||
var $buffersize = 65536; /// 64KB is a good write buffer. Don't expect big benefits by increasing this.
|
||||
var $repectformat = false; /// With this setting enabled, the splited files will look like the original one
|
||||
/// with all the indentations 100% copied from original (character data outer tags).
|
||||
/// But this is a waste of time from our perspective, and splited xml files are completely
|
||||
/// functional without that, so we disable this for production, generating a more compact
|
||||
/// XML quicker
|
||||
|
||||
/// PHP4 constructor
|
||||
function moodle_splitter_parser($savepath, $tosplit = null) {
|
||||
return $this->__construct($savepath, $tosplit);
|
||||
}
|
||||
|
||||
/// PHP5 constructor
|
||||
function __construct($savepath, $tosplit = null) {
|
||||
$this->savepath = $savepath;
|
||||
if (!empty($tosplit)) {
|
||||
$this->tosplit = $tosplit;
|
||||
} else { /// No tosplit list passed, process all the possible parts in one moodle.xml file
|
||||
$this->tosplit = array(
|
||||
'1/MOODLE_BACKUP/2/INFO' => 'split_info.xml',
|
||||
'1/MOODLE_BACKUP/2/ROLES' => 'split_roles.xml',
|
||||
'2/COURSE/3/HEADER' => 'split_course_header.xml',
|
||||
'2/COURSE/3/BLOCKS' => 'split_blocks.xml',
|
||||
'2/COURSE/3/SECTIONS' => 'split_sections.xml',
|
||||
'2/COURSE/3/FORMATDATA' => 'split_formatdata.xml',
|
||||
'2/COURSE/3/METACOURSE' => 'split_metacourse.xml',
|
||||
'2/COURSE/3/GRADEBOOK' => 'split_gradebook.xml',
|
||||
'2/COURSE/3/USERS' => 'split_users.xml',
|
||||
'2/COURSE/3/MESSAGES' => 'split_messages.xml',
|
||||
'2/COURSE/3/BLOGS' => 'split_blogs.xml',
|
||||
'2/COURSE/3/QUESTION_CATEGORIES'=> 'split_questions.xml',
|
||||
'2/COURSE/3/SCALES' => 'split_scales.xml',
|
||||
'2/COURSE/3/GROUPS' => 'split_groups.xml',
|
||||
'2/COURSE/3/GROUPINGS' => 'split_groupings.xml',
|
||||
'2/COURSE/3/GROUPINGSGROUPS' => 'split_groupingsgroups.xml',
|
||||
'2/COURSE/3/EVENTS' => 'split_events.xml',
|
||||
'2/COURSE/3/MODULES' => 'split_modules.xml',
|
||||
'2/COURSE/3/LOGS' => 'split_logs.xml'
|
||||
);
|
||||
}
|
||||
/// Precalculate some info used to speedup checks
|
||||
foreach ($this->tosplit as $key=>$value) {
|
||||
$this->splitwords[basename($key)] = true;
|
||||
if (((int) basename(dirname($key))) > $this->maxsplitlevel) {
|
||||
$this->maxsplitlevel = (int) basename(dirname($key));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Given one tag being opened, check if it's one split point.
|
||||
/// Return false or split filename
|
||||
function check_split_point($tag) {
|
||||
/// Quick check. Level < 2 cannot be a split point
|
||||
if ($this->level < 2) {
|
||||
return false;
|
||||
}
|
||||
/// Quick check. Current tag against potential splitwords
|
||||
if (!isset($this->splitwords[$tag])) {
|
||||
return false;
|
||||
}
|
||||
/// Prev test passed, take a look to 2-level tosplit
|
||||
$keytocheck = ($this->level - 1) . '/' . $this->tree[$this->level - 1] . '/' . $this->level . '/' . $this->tree[$this->level];
|
||||
if (!isset($this->tosplit[$keytocheck])) {
|
||||
return false;
|
||||
}
|
||||
/// Prev test passed, we are in a split point, return new filename
|
||||
return $this->tosplit[$keytocheck];
|
||||
}
|
||||
|
||||
/// To append data (xml-escaped) to contents buffer
|
||||
function character_data($parser, $data) {
|
||||
|
||||
///$this->content .= preg_replace($this->entity_find, $this->entity_replace, $data); ///40% slower
|
||||
///$this->content .= str_replace($this->entity_find, $this->entity_replace, $data); ///25% slower
|
||||
///$this->content .= htmlspecialchars($data); ///the best
|
||||
/// Instead of htmlspecialchars() each chunk of character data, we are going to
|
||||
/// concat it without transformation and will apply the htmlspecialchars() when
|
||||
/// that character data is, efectively, going to be added to contents buffer. This
|
||||
/// makes the number of transformations to be reduced (speedup) and avoid potential
|
||||
/// problems with transformations being applied "in the middle" of multibyte chars.
|
||||
$this->cdata .= $data;
|
||||
}
|
||||
|
||||
/// To detect start of tags, keeping level, tree and fhandle updated.
|
||||
/// Also handles creation of split files
|
||||
function start_tag($parser, $tag, $attrs) {
|
||||
|
||||
/// Update things before processing
|
||||
$this->level++;
|
||||
$this->tree[$this->level] = $tag;
|
||||
|
||||
/// Check if we need to start a new split file,
|
||||
/// Speedup: we only do that if we haven't a fhandler and if level <= $maxsplitlevel
|
||||
if ($this->level <= $this->maxsplitlevel && !$this->fhandler && $newfilename = $this->check_split_point($tag)) {
|
||||
/// Open new file handler, init everything
|
||||
$this->fhandler = fopen($this->savepath . '/' . $newfilename, 'w');
|
||||
$this->content = '';
|
||||
$this->cdata = '';
|
||||
$this->trailing = '';
|
||||
/// Build the original leading tree (and calculate the original trailing one)
|
||||
for ($l = 1; $l < $this->level; $l++) {
|
||||
$this->content .= "<{$this->tree[$l]}>\n";
|
||||
$this->trailing = "\n</{$this->tree[$l]}>" . $this->trailing;
|
||||
}
|
||||
}
|
||||
/// Perform xml-entities transformation and add to contents buffer together with opening tag.
|
||||
/// Speedup. We lose nice formatting of the split XML but avoid 50% of transformations and XML is 100% equivalent
|
||||
$this->content .= ($this->repectformat ? htmlspecialchars($this->cdata) : '') . "<$tag>";
|
||||
$this->cdata = '';
|
||||
}
|
||||
|
||||
/// To detect end of tags, keeping level, tree and fhandle updated, writting contents buffer to split file.
|
||||
/// Also handles closing of split files
|
||||
function end_tag($parser, $tag) {
|
||||
|
||||
/// Perform xml-entities transformation and add to contents buffer together with closing tag, repecting (or no) format
|
||||
$this->content .= ($this->repectformat ? htmlspecialchars($this->cdata) : htmlspecialchars(trim($this->cdata))) . "</$tag>";
|
||||
$this->cdata = '';
|
||||
|
||||
/// Check if we need to close current split file
|
||||
/// Speedup: we only do that if we have a fhandler and if level <= $maxsplitlevel
|
||||
if ($this->level <= $this->maxsplitlevel && $this->fhandler && $newfilename = $this->check_split_point($tag)) {
|
||||
/// Write pending contents buffer before closing. It's a must
|
||||
fwrite($this->fhandler, $this->content);
|
||||
$this->content = "";
|
||||
/// Write the original trailing tree for fhandler
|
||||
fwrite($this->fhandler, $this->trailing);
|
||||
fclose($this->fhandler);
|
||||
$this->fhandler = null;
|
||||
} else {
|
||||
/// Normal write of contents (use one buffer to improve speed)
|
||||
if ($this->fhandler && strlen($this->content) > $this->buffersize) {
|
||||
fwrite($this->fhandler, $this->content);
|
||||
$this->content = "";
|
||||
}
|
||||
}
|
||||
|
||||
/// Update things after processing
|
||||
$this->tree[$this->level] = "";
|
||||
$this->level--;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// This function executes the moodle_splitter_parser, causing the monolithic moodle.xml
|
||||
/// file to be splitted in n smaller files for better treatament by the MoodleParser in restore_read_xml()
|
||||
function restore_split_xml ($xml_file, $preferences) {
|
||||
|
||||
$status = true;
|
||||
|
||||
$xml_parser = xml_parser_create('UTF-8');
|
||||
$split_parser = new moodle_splitter_parser(dirname($xml_file));
|
||||
xml_set_object($xml_parser,$split_parser);
|
||||
xml_set_element_handler($xml_parser, 'start_tag', 'end_tag');
|
||||
xml_set_character_data_handler($xml_parser, 'character_data');
|
||||
|
||||
$doteach = filesize($xml_file) / 20;
|
||||
$fromdot = 0;
|
||||
|
||||
$fp = fopen($xml_file,"r")
|
||||
or $status = false;
|
||||
if ($status) {
|
||||
$lasttime = time();
|
||||
while ($data = fread($fp, 8192)) {
|
||||
if (!defined('RESTORE_SILENTLY')) {
|
||||
$fromdot += 8192;
|
||||
if ($fromdot > $doteach) {
|
||||
echo ".";
|
||||
backup_flush(300);
|
||||
$fromdot = 0;
|
||||
}
|
||||
if ((time() - $lasttime) > 10) {
|
||||
$lasttime = time();
|
||||
backup_flush(300);
|
||||
}
|
||||
}
|
||||
xml_parse($xml_parser, $data, feof($fp))
|
||||
or die(sprintf("XML error: %s at line %d",
|
||||
xml_error_string(xml_get_error_code($xml_parser)),
|
||||
xml_get_current_line_number($xml_parser)));
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
xml_parser_free($xml_parser);
|
||||
return $status;
|
||||
}
|
||||
|
||||
//This is the class used to do all the xml parse
|
||||
class MoodleParser {
|
||||
|
||||
@@ -4943,8 +5274,11 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
case "ORIGINAL_WWWROOT":
|
||||
$this->info->original_wwwroot = $this->getContents();
|
||||
break;
|
||||
case "MNET_EXTERNALUSERS":
|
||||
$this->info->mnet_externalusers = $this->getContents();
|
||||
case "ORIGINAL_SITE_IDENTIFIER_HASH":
|
||||
$this->info->original_siteidentifier = $this->getContents();
|
||||
break;
|
||||
case "MNET_REMOTEUSERS":
|
||||
$this->info->mnet_remoteusers = $this->getContents();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -5030,7 +5364,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
}
|
||||
|
||||
function endElementRoles($parser, $tagName) {
|
||||
//Check if we are into INFO zone
|
||||
//Check if we are into ROLES zone
|
||||
if ($this->tree[2] == "ROLES") {
|
||||
|
||||
if ($this->tree[3] == "ROLE") {
|
||||
@@ -5071,7 +5405,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
}
|
||||
}
|
||||
|
||||
//Stop parsing if todo = INFO and tagName = INFO (en of the tag, of course)
|
||||
//Stop parsing if todo = ROLES and tagName = ROLES (en of the tag, of course)
|
||||
//Speed up a lot (avoid parse all)
|
||||
if ($tagName == "ROLES") {
|
||||
$this->finished = true;
|
||||
@@ -6972,38 +7306,58 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
$this->temp .= htmlspecialchars(trim($this->content))."</".$tagName.">";
|
||||
//If we've finished a mod, xmlize it an save to db
|
||||
if (($this->level == 4) and ($tagName == "MOD")) {
|
||||
//Prepend XML standard header to info gathered
|
||||
$xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp;
|
||||
//Call to xmlize for this portion of xml data (one MOD)
|
||||
//echo "-XMLIZE: ".strftime ("%X",time()),"-"; //Debug
|
||||
$data = xmlize($xml_data,0);
|
||||
//echo strftime ("%X",time())."<p>"; //Debug
|
||||
//traverse_xmlize($data); //Debug
|
||||
//print_object ($GLOBALS['traverse_array']); //Debug
|
||||
//$GLOBALS['traverse_array']=""; //Debug
|
||||
//Now, save data to db. We'll use it later
|
||||
//Get id and modtype from data
|
||||
$mod_id = $data["MOD"]["#"]["ID"]["0"]["#"];
|
||||
$mod_type = $data["MOD"]["#"]["MODTYPE"]["0"]["#"];
|
||||
//Only if we've selected to restore it
|
||||
if (!empty($this->preferences->mods[$mod_type]->restore)) {
|
||||
//Save to db
|
||||
$status = backup_putid($this->preferences->backup_unique_code,$mod_type,$mod_id,
|
||||
null,$data);
|
||||
//echo "<p>id: ".$mod_id."-".$mod_type." len.: ".strlen($sla_mod_temp)." to_db: ".$status."<p>"; //Debug
|
||||
//Create returning info
|
||||
$ret_info = new object();
|
||||
$ret_info->id = $mod_id;
|
||||
$ret_info->modtype = $mod_type;
|
||||
$this->info[] = $ret_info;
|
||||
//Only process the module if efectively it has been selected for restore. MDL-18482
|
||||
if (empty($this->preferences->mods[$this->temp_mod_type]->granular) // We don't care about per instance, i.e. restore all instances.
|
||||
or (array_key_exists($this->temp_mod_id, $this->preferences->mods[$this->temp_mod_type]->instances)
|
||||
and
|
||||
!empty($this->preferences->mods[$this->temp_mod_type]->instances[$this->temp_mod_id]->restore))) {
|
||||
|
||||
//Prepend XML standard header to info gathered
|
||||
$xml_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".$this->temp;
|
||||
//Call to xmlize for this portion of xml data (one MOD)
|
||||
//echo "-XMLIZE: ".strftime ("%X",time()),"-"; //Debug
|
||||
$data = xmlize($xml_data,0);
|
||||
//echo strftime ("%X",time())."<p>"; //Debug
|
||||
//traverse_xmlize($data); //Debug
|
||||
//print_object ($GLOBALS['traverse_array']); //Debug
|
||||
//$GLOBALS['traverse_array']=""; //Debug
|
||||
//Now, save data to db. We'll use it later
|
||||
//Get id and modtype from data
|
||||
$mod_id = $data["MOD"]["#"]["ID"]["0"]["#"];
|
||||
$mod_type = $data["MOD"]["#"]["MODTYPE"]["0"]["#"];
|
||||
//Only if we've selected to restore it
|
||||
if (!empty($this->preferences->mods[$mod_type]->restore)) {
|
||||
//Save to db
|
||||
$status = backup_putid($this->preferences->backup_unique_code,$mod_type,$mod_id,
|
||||
null,$data);
|
||||
//echo "<p>id: ".$mod_id."-".$mod_type." len.: ".strlen($sla_mod_temp)." to_db: ".$status."<p>"; //Debug
|
||||
//Create returning info
|
||||
$ret_info = new object();
|
||||
$ret_info->id = $mod_id;
|
||||
$ret_info->modtype = $mod_type;
|
||||
$this->info[] = $ret_info;
|
||||
}
|
||||
} else {
|
||||
debugging("Info: skipping $this->temp_mod_type activity with mod id: $this->temp_mod_id. Not selected for restore", DEBUG_DEVELOPER);
|
||||
}
|
||||
//Reset current mod_type and mod_id
|
||||
unset($this->temp_mod_type);
|
||||
unset($this->temp_mod_id);
|
||||
//Reset temp
|
||||
unset($this->temp);
|
||||
}
|
||||
|
||||
/// Grab current mod id and type when available
|
||||
if ($this->level == 5) {
|
||||
if ($tagName == 'ID') {
|
||||
$this->temp_mod_id = trim($this->content);
|
||||
} else if ($tagName == 'MODTYPE') {
|
||||
$this->temp_mod_type = trim($this->content);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Stop parsing if todo = MODULES and tagName = MODULES (en of the tag, of course)
|
||||
//Speed up a lot (avoid parse all)
|
||||
if ($tagName == "MODULES" and $this->level == 3) {
|
||||
@@ -7101,8 +7455,31 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
//This function executes the MoodleParser
|
||||
function restore_read_xml ($xml_file,$todo,$preferences) {
|
||||
|
||||
global $CFG;
|
||||
|
||||
$status = true;
|
||||
|
||||
/// If enabled in the site, use split files instead of original moodle.xml file
|
||||
/// This will speed parsing speed upto 20x.
|
||||
if (!empty($CFG->experimentalsplitrestore)) {
|
||||
/// Use splite file, else nothing to process (saves one full parsing for each non-existing todo)
|
||||
$splitfile= dirname($xml_file) . '/' . strtolower('split_' . $todo . '.xml');
|
||||
if (file_exists($splitfile)) {
|
||||
$xml_file = $splitfile;
|
||||
debugging("Info: todo=$todo, using split file", DEBUG_DEVELOPER);
|
||||
} else {
|
||||
/// For some todos, that are used in earlier restore steps (restore_precheck(), restore_form...
|
||||
/// allow fallback to monolithic moodle.xml. Those todos are at the beggining of the xml, so
|
||||
/// it doesn't hurts too much.
|
||||
if ($todo == 'INFO' || $todo == 'COURSE_HEADER' || $todo == 'ROLES') {
|
||||
debugging("Info: todo=$todo, no split file. Fallback to moodle.xml", DEBUG_DEVELOPER);
|
||||
} else {
|
||||
debugging("Info: todo=$todo, no split file. Parse skipped", DEBUG_DEVELOPER);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$xml_parser = xml_parser_create('UTF-8');
|
||||
$moodle_parser = new MoodleParser();
|
||||
$moodle_parser->todo = $todo;
|
||||
@@ -7161,7 +7538,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
if ($status) {
|
||||
// MDL-9290 performance improvement on reading large xml
|
||||
$lasttime = time(); // crmas
|
||||
while ($data = fread($fp, 4096) and !$moodle_parser->finished) {
|
||||
while ($data = fread($fp, 8192) and !$moodle_parser->finished) {
|
||||
|
||||
if ((time() - $lasttime) > 5) {
|
||||
$lasttime = time();
|
||||
@@ -7383,7 +7760,11 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
}
|
||||
else {
|
||||
if (empty($noredirect)) {
|
||||
redirect($CFG->wwwroot.'/backup/restore.php?backup_unique_code='.$backup_unique_code.'&launch=form&file='.$file.'&id='.$id);
|
||||
// in 2.0 we must not print "Continue" redirect link here, because ppl click on it and the execution gets interrupted on next page!!!
|
||||
// imo RESTORE_SILENTLY is an ugly hack :-P
|
||||
$sillystr = get_string('donotclickcontinue');
|
||||
redirect($CFG->wwwroot.'/backup/restore.php?backup_unique_code='.$backup_unique_code.'&launch=form&file='.$file.'&id='.$id, $sillystr, 0);
|
||||
|
||||
} else {
|
||||
return $backup_unique_code;
|
||||
}
|
||||
@@ -7485,9 +7866,26 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
echo "<ul>";
|
||||
}
|
||||
|
||||
//Localtion of the xml file
|
||||
//Location of the xml file
|
||||
$xml_file = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code."/moodle.xml";
|
||||
|
||||
//Preprocess the moodle.xml file spliting into smaller chucks (modules, users, logs...)
|
||||
//for optimal parsing later in the restore process.
|
||||
if (!empty($CFG->experimentalsplitrestore)) {
|
||||
if (!defined('RESTORE_SILENTLY')) {
|
||||
echo '<li>'.get_string('preprocessingbackupfile') . '</li>';
|
||||
}
|
||||
//First of all, split moodle.xml into handy files
|
||||
if (!restore_split_xml ($xml_file, $restore)) {
|
||||
if (!defined('RESTORE_SILENTLY')) {
|
||||
notify("Error proccessing moodle.xml file. Process ended.");
|
||||
} else {
|
||||
$errorstr = "Error proccessing moodle.xml file. Process ended.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//If we've selected to restore into new course
|
||||
//create it (course)
|
||||
//Saving conversion id variables into backup_tables
|
||||
@@ -7521,7 +7919,9 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
}
|
||||
|
||||
if ($status = restore_open_html($restore,$course_header)){
|
||||
echo "<li>Creating the Restorelog.html in the course backup folder</li>";
|
||||
if (!defined('RESTORE_SILENTLY')) {
|
||||
echo "<li>Creating the Restorelog.html in the course backup folder</li>";
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -8135,9 +8535,9 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
echo '</li>';
|
||||
}
|
||||
}
|
||||
/// force full refresh of grading data after all items are created
|
||||
grade_force_full_regrading($restore->course_id);
|
||||
grade_grab_course_grades($restore->course_id);
|
||||
/// force full refresh of grading data after all items are created
|
||||
grade_force_full_regrading($restore->course_id);
|
||||
grade_grab_course_grades($restore->course_id);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -8561,6 +8961,11 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
$oldinstance = backup_getid($restore->backup_unique_code,$table,$oldid);
|
||||
}
|
||||
|
||||
// new instance id not found (not restored module/block/user)... skip any assignment
|
||||
if (!$oldinstance || empty($oldinstance->new_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newcontext = get_context_instance($contextlevel, $oldinstance->new_id);
|
||||
$assignment->contextid = $newcontext->id; // new context id
|
||||
// might already have same assignment
|
||||
@@ -8591,6 +8996,11 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
|
||||
$oldinstance = backup_getid($restore->backup_unique_code,$table,$oldid);
|
||||
}
|
||||
|
||||
// new instance id not found (not restored module/block/user)... skip any override
|
||||
if (!$oldinstance || empty($oldinstance->new_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newcontext = get_context_instance($contextlevel, $oldinstance->new_id);
|
||||
$override->contextid = $newcontext->id; // new context id
|
||||
// use assign capability instead so we can add context to context_rel
|
||||
|
||||
+5
-1
@@ -19,7 +19,11 @@
|
||||
|
||||
//Adjust some php variables to the execution of this script
|
||||
@ini_set("max_execution_time","3000");
|
||||
raise_memory_limit("192M");
|
||||
if (empty($CFG->extramemorylimit)) {
|
||||
raise_memory_limit('128M');
|
||||
} else {
|
||||
raise_memory_limit($CFG->extramemorylimit);
|
||||
}
|
||||
|
||||
echo "<pre>\n";
|
||||
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
/// database (backup_version) to determine whether upgrades should
|
||||
/// be performed (see db/backup_*.php)
|
||||
|
||||
$backup_version = 2008030300; // The current version is a date (YYYYMMDDXX)
|
||||
$backup_release = '1.9'; // User-friendly version number
|
||||
$backup_version = 2008030301; // The current version is a date (YYYYMMDDXX)
|
||||
$backup_release = '1.9.4'; // User-friendly version number
|
||||
|
||||
?>
|
||||
|
||||
@@ -24,6 +24,10 @@ class block_activity_modules extends block_list {
|
||||
$course = get_record('course', 'id', $this->instance->pageid);
|
||||
}
|
||||
|
||||
if (empty($course)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
require_once($CFG->dirroot.'/course/lib.php');
|
||||
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
|
||||
@@ -19,6 +19,12 @@ class block_admin extends block_list {
|
||||
$this->content->icons = array();
|
||||
$this->content->footer = '';
|
||||
|
||||
if (empty($this->instance->pageid)) { // sticky
|
||||
if (!empty($COURSE)) {
|
||||
$this->instance->pageid = $COURSE->id;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->instance)) {
|
||||
return $this->content = '';
|
||||
} else if ($this->instance->pageid == SITEID) {
|
||||
@@ -154,7 +160,7 @@ class block_admin extends block_list {
|
||||
}
|
||||
|
||||
/// View course reports
|
||||
if ($course->id !== SITEID and has_capability('moodle/site:viewreports', $context)) {
|
||||
if ($course->id !== SITEID and has_capability('moodle/site:viewreports', $context)) { // basic capability for listing of reports
|
||||
$this->content->items[]='<a href="'.$CFG->wwwroot.'/course/report.php?id='.$this->instance->pageid.'">'.get_string('reports').'</a>';
|
||||
$this->content->icons[]='<img src="'.$CFG->pixpath.'/i/stats.gif" class="icon" alt="" />';
|
||||
}
|
||||
@@ -209,10 +215,10 @@ class block_admin extends block_list {
|
||||
/// Unenrol link
|
||||
if (empty($course->metacourse) && ($course->id!==SITEID)) {
|
||||
if (has_capability('moodle/legacy:guest', $context, NULL, false)) { // Are a guest now
|
||||
$this->content->items[]='<a href="enrol.php?id='.$this->instance->pageid.'">'.get_string('enrolme', '', format_string($course->shortname)).'</a>';
|
||||
$this->content->items[]='<a href="'.$CFG->wwwroot.'/course/enrol.php?id='.$this->instance->pageid.'">'.get_string('enrolme', '', format_string($course->shortname)).'</a>';
|
||||
$this->content->icons[]='<img src="'.$CFG->pixpath.'/i/user.gif" class="icon" alt="" />';
|
||||
} else if (has_capability('moodle/role:unassignself', $context, NULL, false) and get_user_roles($context, $USER->id, false)) { // Have some role
|
||||
$this->content->items[]='<a href="unenrol.php?id='.$this->instance->pageid.'">'.get_string('unenrolme', '', format_string($course->shortname)).'</a>';
|
||||
$this->content->items[]='<a href="'.$CFG->wwwroot.'/course/unenrol.php?id='.$this->instance->pageid.'">'.get_string('unenrolme', '', format_string($course->shortname)).'</a>';
|
||||
$this->content->icons[]='<img src="'.$CFG->pixpath.'/i/user.gif" class="icon" alt="" />';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ class block_calendar_month extends block_base {
|
||||
calendar_set_referring_course(0);
|
||||
|
||||
} else {
|
||||
//MDL-14693: fix calendar on resource page
|
||||
$courseshown = optional_param( 'id', $COURSE->id, PARAM_INT );
|
||||
// Forcibly filter events to include only those from the particular course we are in.
|
||||
$filtercourse = array($courseshown => $COURSE);
|
||||
$groupeventsfrom = array($courseshown => 1);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user